asn1: Add printing of ASN.1 values
JSON-like printing of ASN.1 parsed values. Status: - Not X.697 (JER) compliant, not even close. - String escaping isn't JSON-compliant. - It's not printing the names of CHOICE types. - It's not printing the names of open type choices (i.e., IOS object names) And yet it's quite useful already. It prints all the weird things in EK certs for example. Here's what it outputs for the EK cert we use in check-gen.c: { "_type": "Certificate", "tbsCertificate": { "_type": "TBSCertificate", "_save": "30820376A00302010202146A0597BA71D7E6D3AC0EDC9EDC95A15B998DE40A300D06092A864886F70D01010B05003055310B3009060355040613024348311E301C060355040A131553544D6963726F656C656374726F6E696373204E56312630240603550403131D53544D2054504D20454B20496E7465726D656469617465204341203035301E170D3138313231343030303030305A170D3238313231343030303030305A300030820122300D06092A864886F70D01010105000382010F003082010A0282010100CC14EB27A78CEB0EA486FA2DF7835F5FA8E905B097012B5BDE50380C355B1A2A721BBC3D08DD21796CDB239FA95310651B1B56FD2CFE53C87352EBD996E33256160404CE9302A08066801E786A2F86E181F949966F492A85B58EAA4A6A8CB3697551BB236E87CC7BF8EC1347871C91E15437E8F266BF1EA5EB271FDCF374D8B47DF8BCE89E1FAD61C2A088CB4036B359CB72A294973FEDCCF0C340AFFD14B64F041165581ACA34147C1C75617047058F7ED7D603E032508094FA73E8B9153DA3BF255D2CBBC5DF301BA8F74D198BEBCE86040FC1D2927C7657414490D802F482F3EBF2DE35EE149A1A6DE8D16891FBFBA02A18AFE59F9D6F149744E5F0D559B10203010001A38201A9308201A5301F0603551D230418301680141ADB994AB58BE57A0CC9B900E7851E1A43C0866030420603551D20043B303930370604551D2000302F302D06082B060105050702011621687474703A2F2F7777772E73742E636F6D2F54504D2F7265706F7369746F72792F30590603551D110101FF044F304DA44B304931163014060567810502010C0B69643A353335343444323031173015060567810502020C0C53543333485450484148433031163014060567810502030C0B69643A303034393030303830670603551D090460305E301706056781050210310E300C0C03322E300201000202008A304306056781050212313A30380201000101FFA0030A0101A1030A0100A2030A0100A310300E1603332E310A01040A01020101FFA40F300D16053134302D320A0102010100300E0603551D0F0101FF040403020520300C0603551D130101FF0402300030100603551D250409300706056781050801304A06082B06010505070101043E303C303A06082B06010505073002862E687474703A2F2F7365637572652E676C6F62616C7369676E2E636F6D2F73746D74706D656B696E7430352E637274", "version": "2", "serialNumber": "6A0597BA71D7E6D3AC0EDC9EDC95A15B998DE40A", "signature": { "_type": "AlgorithmIdentifier", "algorithm": "1.2.840.113549.1.1.11", "parameters": "0500" }, "issuer": { "_choice": "rdnSequence", "value": [ [ { "_type": "AttributeTypeAndValue", "type": "2.5.4.6", "value": { "_choice": "printableString", "value": "CH" } } ], [ { "_type": "AttributeTypeAndValue", "type": "2.5.4.10", "value": { "_choice": "printableString", "value": "STMicroelectronics NV" } } ], [ { "_type": "AttributeTypeAndValue", "type": "2.5.4.3", "value": { "_choice": "printableString", "value": "STM TPM EK Intermediate CA 05" } } ] ] }, "validity": { "_type": "Validity", "notBefore": { "_choice": "utcTime", "value": "2018-12-14T00:00:00Z" }, "notAfter": { "_choice": "utcTime", "value": "2028-12-14T00:00:00Z" } }, "subject": { "_choice": "rdnSequence", "value": [] }, "subjectPublicKeyInfo": { "_type": "SubjectPublicKeyInfo", "algorithm": { "_type": "AlgorithmIdentifier", "algorithm": "1.2.840.113549.1.1.1", "parameters": "0500" }, "subjectPublicKey": "2160:3082010A0282010100CC14EB27A78CEB0EA486FA2DF7835F5FA8E905B097012B5BDE50380C355B1A2A721BBC3D08DD21796CDB239FA95310651B1B56FD2CFE53C87352EBD996E33256160404CE9302A08066801E786A2F86E181F949966F492A85B58EAA4A6A8CB3697551BB236E87CC7BF8EC1347871C91E15437E8F266BF1EA5EB271FDCF374D8B47DF8BCE89E1FAD61C2A088CB4036B359CB72A294973FEDCCF0C340AFFD14B64F041165581ACA34147C1C75617047058F7ED7D603E032508094FA73E8B9153DA3BF255D2CBBC5DF301BA8F74D198BEBCE86040FC1D2927C7657414490D802F482F3EBF2DE35EE149A1A6DE8D16891FBFBA02A18AFE59F9D6F149744E5F0D559B10203010001" }, "issuerUniqueID": null, "subjectUniqueID": null, "extensions": [ { "_type": "Extension", "extnID": "2.5.29.35", "critical": false, "extnValue": "301680141ADB994AB58BE57A0CC9B900E7851E1A43C08660", "_extnValue": { "_type": "AuthorityKeyIdentifier", "keyIdentifier": "1ADB994AB58BE57A0CC9B900E7851E1A43C08660", "authorityCertIssuer": null, "authorityCertSerialNumber": null } }, { "_type": "Extension", "extnID": "2.5.29.32", "critical": false, "extnValue": "303930370604551D2000302F302D06082B060105050702011621687474703A2F2F7777772E73742E636F6D2F54504D2F7265706F7369746F72792F", "_extnValue": [ { "_type": "PolicyInformation", "policyIdentifier": "2.5.29.32.0", "policyQualifiers": [ { "_type": "PolicyQualifierInfo", "policyQualifierId": "1.3.6.1.5.5.7.2.1", "qualifier": "1621687474703A2F2F7777772E73742E636F6D2F54504D2F7265706F7369746F72792F" } ] } ] }, { "_type": "Extension", "extnID": "2.5.29.17", "critical": true, "extnValue": "304DA44B304931163014060567810502010C0B69643A353335343444323031173015060567810502020C0C53543333485450484148433031163014060567810502030C0B69643A3030343930303038", "_extnValue": [ { "_choice": "directoryName", "value": { "_choice": "rdnSequence", "value": [ [ { "_type": "AttributeTypeAndValue", "type": "2.23.133.2.1", "value": { "_choice": "utf8String", "value": "id:53544D20" } } ], [ { "_type": "AttributeTypeAndValue", "type": "2.23.133.2.2", "value": { "_choice": "utf8String", "value": "ST33HTPHAHC0" } } ], [ { "_type": "AttributeTypeAndValue", "type": "2.23.133.2.3", "value": { "_choice": "utf8String", "value": "id:00490008" } } ] ] } } ] }, { "_type": "Extension", "extnID": "2.5.29.9", "critical": false, "extnValue": "305E301706056781050210310E300C0C03322E300201000202008A304306056781050212313A30380201000101FFA0030A0101A1030A0100A2030A0100A310300E1603332E310A01040A01020101FFA40F300D16053134302D320A0102010100", "_extnValue": [ { "_type": "AttributeSet", "type": "2.23.133.2.16", "values": [ "300C0C03322E300201000202008A" ], "_values": [ { "_type": "TPMSpecification", "family": "2.0", "level": "0", "revision": "138" } ] }, { "_type": "AttributeSet", "type": "2.23.133.2.18", "values": [ "30380201000101FFA0030A0101A1030A0100A2030A0100A310300E1603332E310A01040A01020101FFA40F300D16053134302D320A0102010100" ], "_values": [ { "_type": "TPMSecurityAssertions", "version": "0", "fieldUpgradable": true, "ekGenerationType": "655617", "ekGenerationLocation": "655616", "ekCertificateGenerationLocation": "655616", "ccInfo": { "_type": "CommonCriteriaMeasures", "version": "3.1", "assurancelevel": "4", "evaluationStatus": "2", "plus": true, "strengthOfFunction": null, "profileOid": null, "profileUri": null, "targetOid": null, "targetUri": null }, "fipsLevel": { "_type": "FIPSLevel", "version": "140-2", "level": "2", "plus": false }, "iso9000Certified": false, "iso9000Uri": null } ] } ] }, { "_type": "Extension", "extnID": "2.5.29.15", "critical": true, "extnValue": "03020520", "_extnValue": [ "keyEncipherment" ] }, { "_type": "Extension", "extnID": "2.5.29.19", "critical": true, "extnValue": "3000", "_extnValue": { "_type": "BasicConstraints", "cA": false, "pathLenConstraint": null } }, { "_type": "Extension", "extnID": "2.5.29.37", "critical": false, "extnValue": "300706056781050801", "_extnValue": [ "2.23.133.8.1" ] }, { "_type": "Extension", "extnID": "1.3.6.1.5.5.7.1.1", "critical": false, "extnValue": "303C303A06082B06010505073002862E687474703A2F2F7365637572652E676C6F62616C7369676E2E636F6D2F73746D74706D656B696E7430352E637274", "_extnValue": [ { "_type": "AccessDescription", "accessMethod": "1.3.6.1.5.5.7.48.2", "accessLocation": { "_choice": "uniformResourceIdentifier", "value": "http://secure.globalsign.com/stmtpmekint05.crt" } } ] } ] }, "signatureAlgorithm": { "_type": "AlgorithmIdentifier", "algorithm": "1.2.840.113549.1.1.11", "parameters": "0500" }, "signatureValue": "2048:3D4C381E5B4F1BCBE09C63D52F1F04570CAEA142FD9CD942043B11F8E3BDCF50007AE16CF8869013041E92CDD3280BA4B51FBBD40582ED750219E261A695095674855AACEB520ADAFF9E7E908480A39CDCF900462D9171960FFE55D3AC49E8C981341BBD2EFBCC252A4C18A4F3B7C84CCE42CE70A208C84D2630A7ABFBE72D6271E75B9FF1C971D20EB3DBD763F1E04D834EAA692D2E4001BBF4730A3E3FDA9711AE386524D91C63BE0E516D00D5C6141FCCF6C539F3518E180049865BE16B69CAE1F8CB7FDC474B38F7EE56CBE7D8A89D9BA99B65D5265AEF32AA62426B10E6D75BB8677EC44F755BBC2806FD2B4E04BDF5D44259DBEAA42B6F563DF7AA7506" }
This commit is contained in:
@@ -6,7 +6,7 @@ YFLAGS = -d -t
|
||||
|
||||
AM_CPPFLAGS += $(ROKEN_RENAME)
|
||||
|
||||
man_MANS = asn1_compile.1
|
||||
man_MANS = asn1_print.1 asn1_compile.1
|
||||
|
||||
lib_LTLIBRARIES = libasn1.la
|
||||
libasn1_la_LDFLAGS = -version-info 8:0:0
|
||||
@@ -109,6 +109,7 @@ dist_libasn1base_la_SOURCES = \
|
||||
der_get.c \
|
||||
der_put.c \
|
||||
der_free.c \
|
||||
der_print.c \
|
||||
der_length.c \
|
||||
der_copy.c \
|
||||
der_cmp.c \
|
||||
@@ -132,7 +133,7 @@ asn1_compile_LDADD = \
|
||||
$(LIB_roken) $(LEXLIB)
|
||||
|
||||
check_der_LDADD = \
|
||||
libasn1base.la \
|
||||
libasn1.la \
|
||||
$(LIB_roken)
|
||||
|
||||
check_template_LDADD = $(check_der_LDADD)
|
||||
|
@@ -116,6 +116,7 @@ LIBASN1_OBJS= \
|
||||
$(OBJ)\der_get.obj \
|
||||
$(OBJ)\der_put.obj \
|
||||
$(OBJ)\der_free.obj \
|
||||
$(OBJ)\der_print.obj \
|
||||
$(OBJ)\der_length.obj \
|
||||
$(OBJ)\der_copy.obj \
|
||||
$(OBJ)\der_cmp.obj \
|
||||
@@ -381,6 +382,7 @@ libasn1_base_SOURCES= \
|
||||
der_get.c \
|
||||
der_put.c \
|
||||
der_free.c \
|
||||
der_print.c \
|
||||
der_length.c \
|
||||
der_copy.c \
|
||||
der_cmp.c \
|
||||
|
@@ -159,6 +159,55 @@ make it easy to add support for encoding rules other than X.690.
|
||||
- Most of X.690 is supported for decoding, with only DER supported for
|
||||
encoding.
|
||||
|
||||
- We have an `asn1_print` program that can decode DER from any exported types
|
||||
from any ASN.1 modules committed in Heimdal:
|
||||
|
||||
```bash
|
||||
$ ./asn1_print ek.crt Certificate |
|
||||
jq '.tbsCertificate.extensions[3]._open_type[]._open_type'
|
||||
```
|
||||
|
||||
```JSON
|
||||
[
|
||||
{
|
||||
"_type": "TPMSpecification",
|
||||
"family": "2.0",
|
||||
"level": "0",
|
||||
"revision": "138"
|
||||
}
|
||||
]
|
||||
[
|
||||
{
|
||||
"_type": "TPMSecurityAssertions",
|
||||
"version": "0",
|
||||
"fieldUpgradable": "1",
|
||||
"ekGenerationType": "655617",
|
||||
"ekGenerationLocation": "655616",
|
||||
"ekCertificateGenerationLocation": "655616",
|
||||
"ccInfo": {
|
||||
"_type": "CommonCriteriaMeasures",
|
||||
"version": "3.1",
|
||||
"assurancelevel": "4",
|
||||
"evaluationStatus": "2",
|
||||
"plus": "1",
|
||||
"strengthOfFunction": null,
|
||||
"profileOid": null,
|
||||
"profileUri": null,
|
||||
"targetOid": null,
|
||||
"targetUri": null
|
||||
},
|
||||
"fipsLevel": {
|
||||
"_type": "FIPSLevel",
|
||||
"version": "140-2",
|
||||
"level": "2",
|
||||
"plus": "0"
|
||||
},
|
||||
"iso9000Certified": "0",
|
||||
"iso9000Uri": null
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
- Unconstrained integer types have a large integer representation in C that is
|
||||
not terribly useful in common cases. Range constraints on integer types
|
||||
cause the compiler to use `int32_t`, `int64_t`, `uint32_t`, and/or
|
||||
@@ -183,6 +232,11 @@ make it easy to add support for encoding rules other than X.690.
|
||||
|
||||
## Limitations
|
||||
|
||||
- `asn1_print`'s JSON support is not X.697 (JER) compatible.
|
||||
|
||||
- Control over C types generated is very limited, mainly only for integer
|
||||
types.
|
||||
|
||||
- When using the template backend, `SET { .. }` types are currently not sorted
|
||||
by tag as they should be, but if the module author sorts them by hand then
|
||||
DER will be produced.
|
||||
|
@@ -55,6 +55,10 @@ typedef struct heim_base_data heim_any_set;
|
||||
typedef struct heim_base_data HEIM_ANY;
|
||||
typedef struct heim_base_data HEIM_ANY_SET;
|
||||
|
||||
enum asn1_print_flags {
|
||||
ASN1_PRINT_INDENT = 1,
|
||||
};
|
||||
|
||||
#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \
|
||||
do { \
|
||||
(BL) = length_##T((S)); \
|
||||
|
@@ -118,9 +118,8 @@
|
||||
* offset is all ones
|
||||
*/
|
||||
|
||||
/* name: when it happens at index 1 it's the name of the SET/SEQUENCE/CHOICE
|
||||
* when it happens at any other index it's the name of the field that the
|
||||
* next entry deals with
|
||||
/* name: first one is the name of the SET/SEQUENCE/CHOICE type
|
||||
* subsequent ones are the name of the nth field
|
||||
*
|
||||
* 0..23 unused
|
||||
* 24..27 flags A1_NM_*
|
||||
@@ -218,6 +217,7 @@ typedef int (ASN1CALL *asn1_type_encode)(unsigned char *, size_t, const void *,
|
||||
typedef size_t (ASN1CALL *asn1_type_length)(const void *);
|
||||
typedef void (ASN1CALL *asn1_type_release)(void *);
|
||||
typedef int (ASN1CALL *asn1_type_copy)(const void *, void *);
|
||||
typedef char * (ASN1CALL *asn1_type_print)(const void *, int);
|
||||
|
||||
struct asn1_type_func {
|
||||
asn1_type_encode encode;
|
||||
@@ -225,6 +225,7 @@ struct asn1_type_func {
|
||||
asn1_type_length length;
|
||||
asn1_type_copy copy;
|
||||
asn1_type_release release;
|
||||
asn1_type_print print;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
@@ -279,8 +280,10 @@ _asn1_copy_top (
|
||||
void * /*to*/);
|
||||
|
||||
void
|
||||
_asn1_free_top(const struct asn1_template *t,
|
||||
void *data);
|
||||
_asn1_free_top(const struct asn1_template *, void *);
|
||||
|
||||
char *
|
||||
_asn1_print_top(const struct asn1_template *, int, const void *);
|
||||
|
||||
int
|
||||
_asn1_decode_top (
|
||||
|
@@ -2182,9 +2182,184 @@ test_ios(void)
|
||||
0xea, 0xa4, 0x2b, 0x6f, 0x56, 0x3d, 0xf7, 0xaa,
|
||||
0x75, 0x06,
|
||||
};
|
||||
char cert_json[] = {
|
||||
"{\"_type\":\"Certificate\",\"tbsCertificate\":{\"_type\":\"TBSCe"
|
||||
"rtificate\",\"_save\":\"30820376A00302010202146A0597BA71D7E6D3AC"
|
||||
"0EDC9EDC95A15B998DE40A300D06092A864886F70D01010B05003055310B3009"
|
||||
"060355040613024348311E301C060355040A131553544D6963726F656C656374"
|
||||
"726F6E696373204E56312630240603550403131D53544D2054504D20454B2049"
|
||||
"6E7465726D656469617465204341203035301E170D3138313231343030303030"
|
||||
"305A170D3238313231343030303030305A300030820122300D06092A864886F7"
|
||||
"0D01010105000382010F003082010A0282010100CC14EB27A78CEB0EA486FA2D"
|
||||
"F7835F5FA8E905B097012B5BDE50380C355B1A2A721BBC3D08DD21796CDB239F"
|
||||
"A95310651B1B56FD2CFE53C87352EBD996E33256160404CE9302A08066801E78"
|
||||
"6A2F86E181F949966F492A85B58EAA4A6A8CB3697551BB236E87CC7BF8EC1347"
|
||||
"871C91E15437E8F266BF1EA5EB271FDCF374D8B47DF8BCE89E1FAD61C2A088CB"
|
||||
"4036B359CB72A294973FEDCCF0C340AFFD14B64F041165581ACA34147C1C7561"
|
||||
"7047058F7ED7D603E032508094FA73E8B9153DA3BF255D2CBBC5DF301BA8F74D"
|
||||
"198BEBCE86040FC1D2927C7657414490D802F482F3EBF2DE35EE149A1A6DE8D1"
|
||||
"6891FBFBA02A18AFE59F9D6F149744E5F0D559B10203010001A38201A9308201"
|
||||
"A5301F0603551D230418301680141ADB994AB58BE57A0CC9B900E7851E1A43C0"
|
||||
"866030420603551D20043B303930370604551D2000302F302D06082B06010505"
|
||||
"0702011621687474703A2F2F7777772E73742E636F6D2F54504D2F7265706F73"
|
||||
"69746F72792F30590603551D110101FF044F304DA44B30493116301406056781"
|
||||
"0502010C0B69643A353335343444323031173015060567810502020C0C535433"
|
||||
"33485450484148433031163014060567810502030C0B69643A30303439303030"
|
||||
"3830670603551D090460305E301706056781050210310E300C0C03322E300201"
|
||||
"000202008A304306056781050212313A30380201000101FFA0030A0101A1030A"
|
||||
"0100A2030A0100A310300E1603332E310A01040A01020101FFA40F300D160531"
|
||||
"34302D320A0102010100300E0603551D0F0101FF040403020520300C0603551D"
|
||||
"130101FF0402300030100603551D250409300706056781050801304A06082B06"
|
||||
"010505070101043E303C303A06082B06010505073002862E687474703A2F2F73"
|
||||
"65637572652E676C6F62616C7369676E2E636F6D2F73746D74706D656B696E74"
|
||||
"30352E637274\",\"version\":\"2\",\"serialNumber\":\"6A0597BA71D7"
|
||||
"E6D3AC0EDC9EDC95A15B998DE40A\",\"signature\":{\"_type\":\"Algori"
|
||||
"thmIdentifier\",\"algorithm\":{\"_type\":\"OBJECT IDENTIFIER\",\""
|
||||
"oid\":\"1.2.840.113549.1.1.11\",\"components\":[1,2,840,113549,"
|
||||
"1,1,11],\"name\":\"id-pkcs1-sha256WithRSAEncryption\"},\"paramet"
|
||||
"ers\":\"0500\"},\"issuer\":{\"_choice\":\"rdnSequence\",\"value\""
|
||||
":[[{\"_type\":\"AttributeTypeAndValue\",\"type\":{\"_type\":\"O"
|
||||
"BJECT IDENTIFIER\",\"oid\":\"2.5.4.6\",\"components\":[2,5,4,6],"
|
||||
"\"name\":\"id-at-countryName\"},\"value\":{\"_choice\":\"printab"
|
||||
"leString\",\"value\":\"CH\"}}],[{\"_type\":\"AttributeTypeAndVal"
|
||||
"ue\",\"type\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.5.4.1"
|
||||
"0\",\"components\":[2,5,4,10],\"name\":\"id-at-organizationName\""
|
||||
"},\"value\":{\"_choice\":\"printableString\",\"value\":\"STMicr"
|
||||
"oelectronics NV\"}}],[{\"_type\":\"AttributeTypeAndValue\",\"typ"
|
||||
"e\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.5.4.3\",\"compo"
|
||||
"nents\":[2,5,4,3],\"name\":\"id-at-commonName\"},\"value\":{\"_c"
|
||||
"hoice\":\"printableString\",\"value\":\"STM TPM EK Intermediate "
|
||||
"CA 05\"}}]]},\"validity\":{\"_type\":\"Validity\",\"notBefore\":"
|
||||
"{\"_choice\":\"utcTime\",\"value\":\"2018-12-14T00:00:00Z\"},\"n"
|
||||
"otAfter\":{\"_choice\":\"utcTime\",\"value\":\"2028-12-14T00:00:"
|
||||
"00Z\"}},\"subject\":{\"_choice\":\"rdnSequence\",\"value\":[]},\""
|
||||
"subjectPublicKeyInfo\":{\"_type\":\"SubjectPublicKeyInfo\",\"al"
|
||||
"gorithm\":{\"_type\":\"AlgorithmIdentifier\",\"algorithm\":{\"_t"
|
||||
"ype\":\"OBJECT IDENTIFIER\",\"oid\":\"1.2.840.113549.1.1.1\",\"c"
|
||||
"omponents\":[1,2,840,113549,1,1,1],\"name\":\"id-pkcs1-rsaEncryp"
|
||||
"tion\"},\"parameters\":\"0500\"},\"subjectPublicKey\":\"2160:308"
|
||||
"2010A0282010100CC14EB27A78CEB0EA486FA2DF7835F5FA8E905B097012B5BD"
|
||||
"E50380C355B1A2A721BBC3D08DD21796CDB239FA95310651B1B56FD2CFE53C87"
|
||||
"352EBD996E33256160404CE9302A08066801E786A2F86E181F949966F492A85B"
|
||||
"58EAA4A6A8CB3697551BB236E87CC7BF8EC1347871C91E15437E8F266BF1EA5E"
|
||||
"B271FDCF374D8B47DF8BCE89E1FAD61C2A088CB4036B359CB72A294973FEDCCF"
|
||||
"0C340AFFD14B64F041165581ACA34147C1C75617047058F7ED7D603E03250809"
|
||||
"4FA73E8B9153DA3BF255D2CBBC5DF301BA8F74D198BEBCE86040FC1D2927C765"
|
||||
"7414490D802F482F3EBF2DE35EE149A1A6DE8D16891FBFBA02A18AFE59F9D6F1"
|
||||
"49744E5F0D559B10203010001\"},\"issuerUniqueID\":null,\"subjectUn"
|
||||
"iqueID\":null,\"extensions\":[{\"_type\":\"Extension\",\"extnID\""
|
||||
":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.5.29.35\",\"compo"
|
||||
"nents\":[2,5,29,35],\"name\":\"id-x509-ce-authorityKeyIdentifier"
|
||||
"\"},\"critical\":false,\"extnValue\":\"301680141ADB994AB58BE57A0"
|
||||
"CC9B900E7851E1A43C08660\",\"_extnValue_choice\":\"ext-AuthorityK"
|
||||
"eyIdentifier\",\"_extnValue\":{\"_type\":\"AuthorityKeyIdentifi"
|
||||
"er\",\"keyIdentifier\":\"1ADB994AB58BE57A0CC9B900E7851E1A43C0866"
|
||||
"0\",\"authorityCertIssuer\":null,\"authorityCertSerialNumber\":n"
|
||||
"ull}},{\"_type\":\"Extension\",\"extnID\":{\"_type\":\"OBJECT ID"
|
||||
"ENTIFIER\",\"oid\":\"2.5.29.32\",\"components\":[2,5,29,32],\"na"
|
||||
"me\":\"id-x509-ce-certificatePolicies\"},\"critical\":false,\"ex"
|
||||
"tnValue\":\"303930370604551D2000302F302D06082B060105050702011621"
|
||||
"687474703A2F2F7777772E73742E636F6D2F54504D2F7265706F7369746F7279"
|
||||
"2F\",\"_extnValue_choice\":\"ext-CertificatePolicies\",\"_extnV"
|
||||
"alue\":[{\"_type\":\"PolicyInformation\",\"policyIdentifier\":{\""
|
||||
"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.5.29.32.0\",\"compone"
|
||||
"nts\":[2,5,29,32,0],\"name\":\"id-x509-ce-certificatePolicies-an"
|
||||
"yPolicy\"},\"policyQualifiers\":[{\"_type\":\"PolicyQualifierInf"
|
||||
"o\",\"policyQualifierId\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid"
|
||||
"\":\"1.3.6.1.5.5.7.2.1\",\"components\":[1,3,6,1,5,5,7,2,1],\"na"
|
||||
"me\":\"id-pkix-qt-cps\"},\"qualifier\":\"1621687474703A2F2F77777"
|
||||
"72E73742E636F6D2F54504D2F7265706F7369746F72792F\"}]}]},{\"_type\""
|
||||
":\"Extension\",\"extnID\":{\"_type\":\"OBJECT IDENTIFIER\",\"oi"
|
||||
"d\":\"2.5.29.17\",\"components\":[2,5,29,17],\"name\":\"id-x509-"
|
||||
"ce-subjectAltName\"},\"critical\":true,\"extnValue\":\"304DA44B3"
|
||||
"04931163014060567810502010C0B69643A35333534344432303117301506056"
|
||||
"7810502020C0C53543333485450484148433031163014060567810502030C0B6"
|
||||
"9643A3030343930303038\",\"_extnValue_choice\":\"ext-SubjectAltNa"
|
||||
"me\",\"_extnValue\":[{\"_choice\":\"directoryName\",\"value\":{"
|
||||
"\"_choice\":\"rdnSequence\",\"value\":[[{\"_type\":\"AttributeTy"
|
||||
"peAndValue\",\"type\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\""
|
||||
"2.23.133.2.1\",\"components\":[2,23,133,2,1],\"name\":\"tcg-at-"
|
||||
"tpmManufacturer\"},\"value\":{\"_choice\":\"utf8String\",\"value"
|
||||
"\":\"id:53544D20\"}}],[{\"_type\":\"AttributeTypeAndValue\",\"ty"
|
||||
"pe\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.23.133.2.2\",\""
|
||||
"components\":[2,23,133,2,2],\"name\":\"tcg-at-tpmModel\"},\"val"
|
||||
"ue\":{\"_choice\":\"utf8String\",\"value\":\"ST33HTPHAHC0\"}}],["
|
||||
"{\"_type\":\"AttributeTypeAndValue\",\"type\":{\"_type\":\"OBJEC"
|
||||
"T IDENTIFIER\",\"oid\":\"2.23.133.2.3\",\"components\":[2,23,133"
|
||||
",2,3],\"name\":\"tcg-at-tpmVersion\"},\"value\":{\"_choice\":\"u"
|
||||
"tf8String\",\"value\":\"id:00490008\"}}]]}}]},{\"_type\":\"Exten"
|
||||
"sion\",\"extnID\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.5"
|
||||
".29.9\",\"components\":[2,5,29,9],\"name\":\"id-x509-ce-subjectD"
|
||||
"irectoryAttributes\"},\"critical\":false,\"extnValue\":\"305E301"
|
||||
"706056781050210310E300C0C03322E300201000202008A30430605678105021"
|
||||
"2313A30380201000101FFA0030A0101A1030A0100A2030A0100A310300E16033"
|
||||
"32E310A01040A01020101FFA40F300D16053134302D320A0102010100\",\"_e"
|
||||
"xtnValue_choice\":\"ext-SubjectDirectoryAttributes\",\"_extnVal"
|
||||
"ue\":[{\"_type\":\"AttributeSet\",\"type\":{\"_type\":\"OBJECT I"
|
||||
"DENTIFIER\",\"oid\":\"2.23.133.2.16\",\"components\":[2,23,133,2"
|
||||
",16],\"name\":\"tcg-at-tpmSpecification\"},\"values\":[\"300C0C0"
|
||||
"3322E300201000202008A\"],\"_values_choice\":\"at-TPMSpecificatio"
|
||||
"n\",\"_values\":[{\"_type\":\"TPMSpecification\",\"family\":\"2"
|
||||
".0\",\"level\":0,\"revision\":138}]},{\"_type\":\"AttributeSet\""
|
||||
",\"type\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.23.133.2."
|
||||
"18\",\"components\":[2,23,133,2,18],\"name\":\"tcg-at-tpmSecurit"
|
||||
"yAssertions\"},\"values\":[\"30380201000101FFA0030A0101A1030A010"
|
||||
"0A2030A0100A310300E1603332E310A01040A01020101FFA40F300D160531343"
|
||||
"02D320A0102010100\"],\"_values_choice\":\"at-TPMSecurityAssertio"
|
||||
"ns\",\"_values\":[{\"_type\":\"TPMSecurityAssertions\",\"versio"
|
||||
"n\":\"0\",\"fieldUpgradable\":true,\"ekGenerationType\":\"655617"
|
||||
"\",\"ekGenerationLocation\":\"655616\",\"ekCertificateGeneration"
|
||||
"Location\":\"655616\",\"ccInfo\":{\"_type\":\"CommonCriteriaMeas"
|
||||
"ures\",\"version\":\"3.1\",\"assurancelevel\":\"4\",\"evaluation"
|
||||
"Status\":\"2\",\"plus\":true,\"strengthOfFunction\":null,\"profi"
|
||||
"leOid\":null,\"profileUri\":null,\"targetOid\":null,\"targetUri\""
|
||||
":null},\"fipsLevel\":{\"_type\":\"FIPSLevel\",\"version\":\"140"
|
||||
"-2\",\"level\":\"2\",\"plus\":false},\"iso9000Certified\":false,"
|
||||
"\"iso9000Uri\":null}]}]},{\"_type\":\"Extension\",\"extnID\":{\""
|
||||
"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.5.29.15\",\"components"
|
||||
"\":[2,5,29,15],\"name\":\"id-x509-ce-keyUsage\"},\"critical\":tr"
|
||||
"ue,\"extnValue\":\"03020520\",\"_extnValue_choice\":\"ext-KeyUsa"
|
||||
"ge\",\"_extnValue\":[\"keyEncipherment\"]},{\"_type\":\"Extensi"
|
||||
"on\",\"extnID\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.5.2"
|
||||
"9.19\",\"components\":[2,5,29,19],\"name\":\"id-x509-ce-basicCon"
|
||||
"straints\"},\"critical\":true,\"extnValue\":\"3000\",\"_extnValu"
|
||||
"e_choice\":\"ext-BasicConstraints\",\"_extnValue\":{\"_type\":\""
|
||||
"BasicConstraints\",\"cA\":false,\"pathLenConstraint\":null}},{\""
|
||||
"_type\":\"Extension\",\"extnID\":{\"_type\":\"OBJECT IDENTIFIER"
|
||||
"\",\"oid\":\"2.5.29.37\",\"components\":[2,5,29,37],\"name\":\"i"
|
||||
"d-x509-ce-extKeyUsage\"},\"critical\":false,\"extnValue\":\"3007"
|
||||
"06056781050801\",\"_extnValue_choice\":\"ext-ExtKeyUsage\",\"_e"
|
||||
"xtnValue\":[{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.23.133."
|
||||
"8.1\",\"components\":[2,23,133,8,1],\"name\":\"tcg-kp-EKCertific"
|
||||
"ate\"}]},{\"_type\":\"Extension\",\"extnID\":{\"_type\":\"OBJECT"
|
||||
" IDENTIFIER\",\"oid\":\"1.3.6.1.5.5.7.1.1\",\"components\":[1,3,"
|
||||
"6,1,5,5,7,1,1],\"name\":\"id-pkix-pe-authorityInfoAccess\"},\"cr"
|
||||
"itical\":false,\"extnValue\":\"303C303A06082B06010505073002862E6"
|
||||
"87474703A2F2F7365637572652E676C6F62616C7369676E2E636F6D2F73746D7"
|
||||
"4706D656B696E7430352E637274\",\"_extnValue_choice\":\"ext-Author"
|
||||
"ityInfoAccess\",\"_extnValue\":[{\"_type\":\"AccessDescription\""
|
||||
",\"accessMethod\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"1."
|
||||
"3.6.1.5.5.7.48.2\",\"components\":[1,3,6,1,5,5,7,48,2],\"name\":"
|
||||
"\"id-pkix-ad-caIssuers\"},\"accessLocation\":{\"_choice\":\"unif"
|
||||
"ormResourceIdentifier\",\"value\":\"http://secure.globalsign.com"
|
||||
"/stmtpmekint05.crt\"}}]}]},\"signatureAlgorithm\":{\"_type\":\"A"
|
||||
"lgorithmIdentifier\",\"algorithm\":{\"_type\":\"OBJECT IDENTIFIE"
|
||||
"R\",\"oid\":\"1.2.840.113549.1.1.11\",\"components\":[1,2,840,11"
|
||||
"3549,1,1,11],\"name\":\"id-pkcs1-sha256WithRSAEncryption\"},\"pa"
|
||||
"rameters\":\"0500\"},\"signatureValue\":\"2048:3D4C381E5B4F1BCBE"
|
||||
"09C63D52F1F04570CAEA142FD9CD942043B11F8E3BDCF50007AE16CF88690130"
|
||||
"41E92CDD3280BA4B51FBBD40582ED750219E261A695095674855AACEB520ADAF"
|
||||
"F9E7E908480A39CDCF900462D9171960FFE55D3AC49E8C981341BBD2EFBCC252"
|
||||
"A4C18A4F3B7C84CCE42CE70A208C84D2630A7ABFBE72D6271E75B9FF1C971D20"
|
||||
"EB3DBD763F1E04D834EAA692D2E4001BBF4730A3E3FDA9711AE386524D91C63B"
|
||||
"E0E516D00D5C6141FCCF6C539F3518E180049865BE16B69CAE1F8CB7FDC474B3"
|
||||
"8F7EE56CBE7D8A89D9BA99B65D5265AEF32AA62426B10E6D75BB8677EC44F755"
|
||||
"BBC2806FD2B4E04BDF5D44259DBEAA42B6F563DF7AA7506\"}"
|
||||
};
|
||||
heim_octet_string os;
|
||||
Certificate c0, c1;
|
||||
size_t i, nknown, size;
|
||||
char *s;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@@ -2200,6 +2375,13 @@ test_ios(void)
|
||||
if (size != sizeof(encoded_sample))
|
||||
return 1;
|
||||
|
||||
s = print_Certificate(&c0, 0);
|
||||
if (!s)
|
||||
return 1;
|
||||
if (strcmp(s, cert_json))
|
||||
return 1;
|
||||
free(s);
|
||||
|
||||
ret = copy_Certificate(&c0, &c1);
|
||||
if (ret)
|
||||
return 1;
|
||||
@@ -2225,6 +2407,7 @@ test_ios(void)
|
||||
if (!nknown)
|
||||
return 1;
|
||||
|
||||
|
||||
/*
|
||||
* Check that this round trips. But note that this attempt to encode will
|
||||
* ignore the automatically decoded open type values from above because
|
||||
@@ -2272,7 +2455,6 @@ test_ios(void)
|
||||
return 1;
|
||||
der_free_octet_string(&os);
|
||||
|
||||
/* XXX Test setting some of the _ioschoice_extnValue._element's to 0 */
|
||||
free_Certificate(&c0);
|
||||
free_Certificate(&c1);
|
||||
return 0;
|
||||
|
227
lib/asn1/der_print.c
Normal file
227
lib/asn1/der_print.c
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
#include "hex.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
char *
|
||||
der_print_general_string(const heim_general_string *str, int flags)
|
||||
{
|
||||
return strdup(*str);
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_boolean(const int *i, int flags)
|
||||
{
|
||||
return *i ? strdup("true") : strdup("false");
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_integer(const int *i, int flags)
|
||||
{
|
||||
char *s = NULL;
|
||||
|
||||
if (asprintf(&s, "%d", *i) == -1 || s == NULL)
|
||||
return NULL;
|
||||
return s;
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_integer64(const int64_t *i, int flags)
|
||||
{
|
||||
char *s = NULL;
|
||||
|
||||
if (asprintf(&s, "%lld", (long long)*i) == -1 || s == NULL)
|
||||
return NULL;
|
||||
return s;
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_unsigned(const unsigned *u, int flags)
|
||||
{
|
||||
char *s = NULL;
|
||||
|
||||
if (asprintf(&s, "%u", *u) == -1 || s == NULL)
|
||||
return NULL;
|
||||
return s;
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_unsigned64(const uint64_t *u, int flags)
|
||||
{
|
||||
char *s = NULL;
|
||||
|
||||
if (asprintf(&s, "%llu", (long long)*u) == -1 || s == NULL)
|
||||
return NULL;
|
||||
return s;
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_generalized_time(const time_t *t, int flags)
|
||||
{
|
||||
struct tm tms;
|
||||
char str[sizeof("1970-01-01T00:00:00Z")];
|
||||
|
||||
#ifdef WIN32
|
||||
if (strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%SZ", gmtime_s(&tms, t)) == 0)
|
||||
return NULL;
|
||||
#else
|
||||
if (strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%SZ", gmtime_r(t, &tms)) == 0)
|
||||
return NULL;
|
||||
#endif
|
||||
return strdup(str);
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_utctime(const time_t *t, int flags)
|
||||
{
|
||||
struct tm tms;
|
||||
char str[sizeof("1970-01-01T00:00:00Z")];
|
||||
|
||||
#ifdef WIN32
|
||||
if (strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%SZ", gmtime_s(&tms, t)) == 0)
|
||||
return NULL;
|
||||
#else
|
||||
if (strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%SZ", gmtime_r(t, &tms)) == 0)
|
||||
return NULL;
|
||||
#endif
|
||||
return strdup(str);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
der_print_utf8string(const heim_utf8_string *str, int flags)
|
||||
{
|
||||
return strdup(*str);
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_printable_string(const heim_printable_string *str, int flags)
|
||||
{
|
||||
return strndup(str->data, str->length);
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_ia5_string(const heim_ia5_string *str, int flags)
|
||||
{
|
||||
return strndup(str->data, str->length);
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_bmp_string(const heim_bmp_string *k, int flags)
|
||||
{
|
||||
return strdup("<BMPString-not-supported>");
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_universal_string(const heim_universal_string *k, int flags)
|
||||
{
|
||||
return strdup("<UniversalString-not-supported>");
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_visible_string(const heim_visible_string *str, int flags)
|
||||
{
|
||||
return strdup(*str);
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_octet_string(const heim_octet_string *k, int flags)
|
||||
{
|
||||
char *s = NULL;
|
||||
|
||||
(void) hex_encode(k->data, k->length, &s);
|
||||
return s;
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_heim_integer(const heim_integer *k, int flags)
|
||||
{
|
||||
char *s = NULL;
|
||||
|
||||
(void) der_print_hex_heim_integer(k, &s);
|
||||
return s;
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_oid(const heim_oid *k, int flags)
|
||||
{
|
||||
struct rk_strpool *r = NULL;
|
||||
const char *sym = NULL;
|
||||
char *s = NULL;
|
||||
size_t i;
|
||||
|
||||
(void) der_print_heim_oid(k, '.', &s);
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
r = rk_strpoolprintf(r, "{\"_type\":\"OBJECT IDENTIFIER\","
|
||||
"\"oid\":\"%s\","
|
||||
"\"components\":[",
|
||||
s);
|
||||
free(s);
|
||||
for (i = 0; i < k->length; i++)
|
||||
r = rk_strpoolprintf(r, "%s%u", i ? "," : "", k->components[i]);
|
||||
if (r)
|
||||
r = rk_strpoolprintf(r, "]");
|
||||
(void) der_find_heim_oid_by_oid(k, &sym);
|
||||
if (sym && r) {
|
||||
if ((s = strdup(sym))) {
|
||||
for (i = 0; s[i]; i++)
|
||||
if (s[i] == '_')
|
||||
s[i] = '-';
|
||||
}
|
||||
r = rk_strpoolprintf(r, ",\"name\":\"%s\"", s ? s : sym);
|
||||
free(s);
|
||||
}
|
||||
if (r)
|
||||
r = rk_strpoolprintf(r, "}");
|
||||
return rk_strpoolcollect(r);
|
||||
}
|
||||
|
||||
char *
|
||||
der_print_bit_string(const heim_bit_string *k, int flags)
|
||||
{
|
||||
char *s2 = NULL;
|
||||
char *s = NULL;
|
||||
|
||||
(void) hex_encode(k->data, k->length / 8, &s);
|
||||
if (asprintf(&s2, "%llu:%s", (unsigned long long)k->length, s) == -1 || !s2)
|
||||
return NULL;
|
||||
free(s);
|
||||
return s2;
|
||||
}
|
@@ -90,6 +90,12 @@ free_heim_any(heim_any *data)
|
||||
der_free_octet_string(data);
|
||||
}
|
||||
|
||||
char *
|
||||
print_heim_any(const heim_any *data)
|
||||
{
|
||||
return der_print_octet_string(data, 0);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_heim_any(const heim_any *data)
|
||||
{
|
||||
@@ -122,6 +128,12 @@ free_HEIM_ANY(heim_any *data)
|
||||
der_free_octet_string(data);
|
||||
}
|
||||
|
||||
char *
|
||||
print_HEIM_ANY(const heim_any *data)
|
||||
{
|
||||
return der_print_octet_string(data, 0);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_HEIM_ANY(const heim_any *data)
|
||||
{
|
||||
@@ -154,6 +166,12 @@ free_heim_any_set(heim_any_set *data)
|
||||
der_free_octet_string(data);
|
||||
}
|
||||
|
||||
char *
|
||||
print_heim_any_set(const heim_any_set *data)
|
||||
{
|
||||
return der_print_octet_string(data, 0);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_heim_any_set(const heim_any *data)
|
||||
{
|
||||
@@ -192,6 +210,12 @@ free_HEIM_ANY_SET(heim_any_set *data)
|
||||
der_free_octet_string(data);
|
||||
}
|
||||
|
||||
char *
|
||||
print_HEIM_ANY_SET(const heim_any_set *data)
|
||||
{
|
||||
return der_print_octet_string(data, 0);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_HEIM_ANY_SET(const heim_any *data)
|
||||
{
|
||||
|
@@ -237,6 +237,11 @@ init_generate (const char *filename, const char *base)
|
||||
"typedef struct heim_base_data heim_any_set;\n"
|
||||
"typedef struct heim_base_data HEIM_ANY;\n"
|
||||
"typedef struct heim_base_data HEIM_ANY_SET;\n\n");
|
||||
|
||||
fprintf (headerfile,
|
||||
"enum asn1_print_flags {\n"
|
||||
" ASN1_PRINT_INDENT = 1,\n"
|
||||
"};\n\n");
|
||||
fputs("#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \\\n"
|
||||
" do { \\\n"
|
||||
" (BL) = length_##T((S)); \\\n"
|
||||
@@ -1675,6 +1680,12 @@ generate_type (const Symbol *s)
|
||||
exp,
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
if (template_flag)
|
||||
fprintf(h,
|
||||
"%schar * ASN1CALL print_%s (const %s *, int);\n",
|
||||
exp,
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf(h, "\n\n");
|
||||
|
||||
if (!one_code_file) {
|
||||
|
@@ -295,6 +295,8 @@ static int tlist_cmp(const struct tlist *, const struct tlist *);
|
||||
|
||||
static void add_line_pointer(struct templatehead *, const char *, const char *, const char *, ...)
|
||||
__attribute__ ((__format__ (__printf__, 4, 5)));
|
||||
static void add_line_string(struct templatehead *, const char *, const char *, const char *, ...)
|
||||
__attribute__ ((__format__ (__printf__, 4, 5)));
|
||||
static void add_line_pointer_reference(struct templatehead *, const char *, const char *, const char *, ...)
|
||||
__attribute__ ((__format__ (__printf__, 4, 5)));
|
||||
|
||||
@@ -384,6 +386,8 @@ tlist_cmp(const struct tlist *tl, const struct tlist *ql)
|
||||
int ret;
|
||||
struct template *t, *q;
|
||||
|
||||
if (tl == ql)
|
||||
return 0;
|
||||
ret = strcmp(tl->header, ql->header);
|
||||
if (ret) return ret;
|
||||
|
||||
@@ -470,6 +474,28 @@ add_line_pointer(struct templatehead *t,
|
||||
q->ptr = strdup(ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
add_line_string(struct templatehead *t,
|
||||
const char *str,
|
||||
const char *offset,
|
||||
const char *ttfmt,
|
||||
...)
|
||||
{
|
||||
struct template *q;
|
||||
va_list ap;
|
||||
char *tt = NULL;
|
||||
|
||||
va_start(ap, ttfmt);
|
||||
if (vasprintf(&tt, ttfmt, ap) < 0 || tt == NULL)
|
||||
errx(1, "malloc");
|
||||
va_end(ap);
|
||||
|
||||
q = add_line(t, "{ %s, %s, \"%s\" }", tt, offset, str);
|
||||
q->tt = tt;
|
||||
q->offset = strdup(offset);
|
||||
q->ptr = strdup(str);
|
||||
}
|
||||
|
||||
static void
|
||||
add_line_pointer_reference(struct templatehead *t,
|
||||
const char *ptr,
|
||||
@@ -755,6 +781,7 @@ template_object_set(IOSObjectSet *os, Field *typeidfield, Field *opentypefield)
|
||||
sort_object_set(os, typeidfield, &objects, &nobjs);
|
||||
|
||||
tl = tlist_new(os->symbol->name);
|
||||
add_line(&tl->template, "{ A1_OP_NAME, 0, \"%s\" }", os->symbol->name);
|
||||
for (i = 0; i < nobjs; i++) {
|
||||
ObjectField *typeidobjf = NULL, *opentypeobjf = NULL;
|
||||
ObjectField *of;
|
||||
@@ -777,6 +804,7 @@ template_object_set(IOSObjectSet *os, Field *typeidfield, Field *opentypefield)
|
||||
continue;
|
||||
}
|
||||
|
||||
add_line(&tl->template, "{ A1_OP_NAME, 0, \"%s\" }", o->symbol->name);
|
||||
/*
|
||||
* Some of this logic could stand to move into sanity checks of object
|
||||
* definitions in asn1parse.y.
|
||||
@@ -849,6 +877,17 @@ template_open_type(struct templatehead *temp,
|
||||
free(s);
|
||||
}
|
||||
|
||||
static void
|
||||
template_names(struct templatehead *temp, const char *basetype, const Type *t)
|
||||
{
|
||||
Member *m;
|
||||
|
||||
add_line_string(temp, basetype, "0", "A1_OP_NAME");
|
||||
HEIM_TAILQ_FOREACH(m, t->members, members) {
|
||||
add_line_string(temp, m->name, "0", "A1_OP_NAME");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
template_members(struct templatehead *temp,
|
||||
const char *basetype,
|
||||
@@ -968,7 +1007,7 @@ template_members(struct templatehead *temp,
|
||||
output_name(bname);
|
||||
|
||||
HEIM_TAILQ_FOREACH(m, t->members, members) {
|
||||
add_line(&template, "{ 0, %d, 0 } /* %s */", m->val, m->gen_name);
|
||||
add_line(&template, "{ 0, %d, \"%s\" }", m->val, m->gen_name);
|
||||
}
|
||||
|
||||
HEIM_TAILQ_FOREACH(q, &template, members) {
|
||||
@@ -1038,6 +1077,9 @@ template_members(struct templatehead *temp,
|
||||
template_open_type(temp, basetype, t, typeididx, opentypeidx,
|
||||
typeidfield, opentypefield, opentypemember,
|
||||
is_array_of_open_type);
|
||||
|
||||
if (isstruct)
|
||||
template_names(temp, basetype, t);
|
||||
break;
|
||||
}
|
||||
case TSequence: {
|
||||
@@ -1086,6 +1128,9 @@ template_members(struct templatehead *temp,
|
||||
template_open_type(temp, basetype, t, typeididx, opentypeidx,
|
||||
typeidfield, opentypefield, opentypemember,
|
||||
is_array_of_open_type);
|
||||
|
||||
if (isstruct)
|
||||
template_names(temp, basetype, t);
|
||||
break;
|
||||
}
|
||||
case TTag: {
|
||||
@@ -1233,6 +1278,10 @@ template_members(struct templatehead *temp,
|
||||
free(newbasename);
|
||||
}
|
||||
|
||||
HEIM_TAILQ_FOREACH(m, t->members, members) {
|
||||
add_line(&template, "{ 0, 0, \"%s\" }", m->name);
|
||||
}
|
||||
|
||||
e = NULL;
|
||||
if (ellipsis) {
|
||||
if (asprintf(&e, "offsetof(%s%s, u.asn1_ellipsis)", isstruct ? "struct " : "", basetype) < 0 || e == NULL)
|
||||
@@ -1276,10 +1325,11 @@ gen_extern_stubs(FILE *f, const char *name)
|
||||
"\t(asn1_type_length)length_%s,\n"
|
||||
"\t(asn1_type_copy)copy_%s,\n"
|
||||
"\t(asn1_type_release)free_%s,\n"
|
||||
"\t(asn1_type_print)print_%s,\n"
|
||||
"\tsizeof(%s)\n"
|
||||
"};\n",
|
||||
name, name, name, name,
|
||||
name, name, name);
|
||||
name, name, name, name);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1463,4 +1513,16 @@ generate_template(const Symbol *s)
|
||||
s->gen_name,
|
||||
s->gen_name,
|
||||
dupname);
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"char *\n"
|
||||
"print_%s(const %s *data, int flags)\n"
|
||||
"{\n"
|
||||
" return _asn1_print_top(asn1_%s, flags, data);\n"
|
||||
"}\n"
|
||||
"\n",
|
||||
s->gen_name,
|
||||
s->gen_name,
|
||||
dupname);
|
||||
}
|
||||
|
@@ -37,6 +37,7 @@
|
||||
int encode_heim_any(unsigned char *, size_t, const heim_any *, size_t *);
|
||||
int decode_heim_any(const unsigned char *, size_t, heim_any *, size_t *);
|
||||
void free_heim_any(heim_any *);
|
||||
char *print_heim_any(const heim_any *);
|
||||
size_t length_heim_any(const heim_any *);
|
||||
int copy_heim_any(const heim_any *, heim_any *);
|
||||
|
||||
@@ -45,6 +46,7 @@ int encode_heim_any_set(unsigned char *, size_t,
|
||||
int decode_heim_any_set(const unsigned char *, size_t,
|
||||
heim_any_set *,size_t *);
|
||||
void free_heim_any_set(heim_any_set *);
|
||||
char *print_heim_any_set(const heim_any_set *);
|
||||
size_t length_heim_any_set(const heim_any_set *);
|
||||
int copy_heim_any_set(const heim_any_set *, heim_any_set *);
|
||||
int heim_any_cmp(const heim_any_set *, const heim_any_set *);
|
||||
@@ -52,6 +54,7 @@ int heim_any_cmp(const heim_any_set *, const heim_any_set *);
|
||||
int encode_HEIM_ANY(unsigned char *, size_t, const heim_any *, size_t *);
|
||||
int decode_HEIM_ANY(const unsigned char *, size_t, heim_any *, size_t *);
|
||||
void free_HEIM_ANY(heim_any *);
|
||||
char *print_HEIM_ANY(const heim_any *);
|
||||
size_t length_HEIM_ANY(const heim_any *);
|
||||
int copy_HEIM_ANY(const heim_any *, heim_any *);
|
||||
|
||||
@@ -60,6 +63,7 @@ int encode_HEIM_ANY_SET(unsigned char *, size_t,
|
||||
int decode_HEIM_ANY_SET(const unsigned char *, size_t,
|
||||
heim_any_set *,size_t *);
|
||||
void free_HEIM_ANY_SET(heim_any_set *);
|
||||
char *print_HEIM_ANY_SET(const heim_any_set *);
|
||||
size_t length_HEIM_ANY_SET(const heim_any_set *);
|
||||
int copy_HEIM_ANY_SET(const heim_any_set *, heim_any_set *);
|
||||
int heim_any_cmp(const heim_any_set *, const heim_any_set *);
|
||||
|
@@ -2221,6 +2221,360 @@ EXPORTS
|
||||
length_X690SampleEmployeeNumber
|
||||
length_X690SampleName
|
||||
length_X690SamplePersonnelRecord
|
||||
print_AccessDescription
|
||||
print_AD_AND_OR
|
||||
print_AD_IF_RELEVANT
|
||||
print_AD_INITIAL_VERIFIED_CAS
|
||||
print_AD_KDCIssued
|
||||
print_AD_LoginAlias
|
||||
print_AD_MANDATORY_FOR_KDC
|
||||
print_AlgorithmIdentifier
|
||||
print_AliasIA5String
|
||||
print_AliasPrintableString
|
||||
print_AliasUTF8String
|
||||
print_APOptions
|
||||
print_AP_REP
|
||||
print_AP_REQ
|
||||
print_AS_REP
|
||||
print_AS_REQ
|
||||
print_Attribute
|
||||
print_AttributeSet
|
||||
print_AttributeType
|
||||
print_AttributeTypeAndValue
|
||||
print_AttributeValue
|
||||
print_AttributeValues
|
||||
print_AUTHDATA_TYPE
|
||||
print_Authenticator
|
||||
print_AuthorityInfoAccessSyntax
|
||||
print_AuthorityKeyIdentifier
|
||||
print_AuthorizationData
|
||||
print_AuthorizationDataElement
|
||||
print_AuthPack
|
||||
print_AuthPack_Win2k
|
||||
print_BaseDistance
|
||||
print_BasicConstraints
|
||||
print_Certificate
|
||||
print_CertificateList
|
||||
print_CertificatePolicies
|
||||
print_CertificateRevocationLists
|
||||
print_Certificates
|
||||
print_CertificateSerialNumber
|
||||
print_CertificateSet
|
||||
print_CertificationRequest
|
||||
print_CertificationRequestInfo
|
||||
print_CertPolicyId
|
||||
print_ChangePasswdDataMS
|
||||
print_Checksum
|
||||
print_CKSUMTYPE
|
||||
print_CMSAttributes
|
||||
print_CMSCBCParameter
|
||||
print_CMSEncryptedData
|
||||
print_CMSIdentifier
|
||||
print_CMSRC2CBCParameter
|
||||
print_CMSVersion
|
||||
print_CommonCriteriaMeasures
|
||||
print_CommunityIdentifier
|
||||
print_CommunityIdentifiers
|
||||
print_ContentEncryptionAlgorithmIdentifier
|
||||
print_ContentInfo
|
||||
print_ContentType
|
||||
print_CPSuri
|
||||
print_CRLCertificateList
|
||||
print_CRLDistributionPoints
|
||||
print_CRLReason
|
||||
print_CurrentFWConfig
|
||||
print_DecryptKeyIdentifier
|
||||
print_DHNonce
|
||||
print_DHParameter
|
||||
print_DHPublicKey
|
||||
print_DHRepInfo
|
||||
print_DigestAlgorithmIdentifier
|
||||
print_DigestAlgorithmIdentifiers
|
||||
print_DigestError
|
||||
print_DigestInfo
|
||||
print_DigestInit
|
||||
print_DigestInitReply
|
||||
print_DigestREP
|
||||
print_DigestRepInner
|
||||
print_DigestREQ
|
||||
print_DigestReqInner
|
||||
print_DigestRequest
|
||||
print_DigestResponse
|
||||
print_DigestTypes
|
||||
print_DirectoryString
|
||||
print_DisplayText
|
||||
print_DistributionPoint
|
||||
print_DistributionPointName
|
||||
print_DistributionPointReasonFlags
|
||||
print_DomainParameters
|
||||
print_DSAParams
|
||||
print_DSAPublicKey
|
||||
print_DSASigValue
|
||||
print_ECDSA_Sig_Value
|
||||
print_ECParameters
|
||||
print_ECPoint
|
||||
print_EKCertificateGenerationLocation
|
||||
print_EKGenerationLocation
|
||||
print_EKGenerationType
|
||||
print_EncAPRepPart
|
||||
print_EncapsulatedContentInfo
|
||||
print_EncASRepPart
|
||||
print_EncKDCRepPart
|
||||
print_EncKrbCredPart
|
||||
print_EncKrbPrivPart
|
||||
print_EncryptedContent
|
||||
print_EncryptedContentInfo
|
||||
print_EncryptedData
|
||||
print_EncryptedKey
|
||||
print_EncryptionKey
|
||||
print_EncTGSRepPart
|
||||
print_EncTicketPart
|
||||
print_ENCTYPE
|
||||
print_EnvelopedData
|
||||
print_ETYPE_INFO
|
||||
print_ETYPE_INFO2
|
||||
print_ETYPE_INFO2_ENTRY
|
||||
print_ETYPE_INFO_ENTRY
|
||||
print_EtypeList
|
||||
print_EvaluationAssuranceLevel
|
||||
print_EvaluationStatus
|
||||
print_Extension
|
||||
print_Extensions
|
||||
print_ExternalPrincipalIdentifier
|
||||
print_ExternalPrincipalIdentifiers
|
||||
print_ExtKeyUsage
|
||||
print_FastOptions
|
||||
print_FIPSLevel
|
||||
print_FirmwarePackageIdentifier
|
||||
print_FirmwarePackageInfo
|
||||
print_FirmwarePackageLoadError
|
||||
print_FirmwarePackageLoadErrorCode
|
||||
print_FirmwarePackageLoadReceipt
|
||||
print_FirmwarePkgData
|
||||
print_FWErrorVersion
|
||||
print_FWReceiptVersion
|
||||
print_GeneralName
|
||||
print_GeneralNames
|
||||
print_GeneralSubtree
|
||||
print_GeneralSubtrees
|
||||
print_HardwareModuleName
|
||||
print_HardwareModules
|
||||
print_HardwareSerialEntry
|
||||
print_heim_any
|
||||
print_HEIM_ANY
|
||||
print_heim_any_set
|
||||
print_HEIM_ANY_SET
|
||||
print_HostAddress
|
||||
print_HostAddresses
|
||||
print_ImplementedCompressAlgorithms
|
||||
print_ImplementedCryptoAlgorithms
|
||||
print_IssuerAndSerialNumber
|
||||
print_KDCDHKeyInfo
|
||||
print_KDCDHKeyInfo_Win2k
|
||||
print_KDCFastCookie
|
||||
print_KDCFastFlags
|
||||
print_KDCFastState
|
||||
print_KDCOptions
|
||||
print_KDC_PROXY_MESSAGE
|
||||
print_KDC_REP
|
||||
print_KDC_REQ
|
||||
print_KDC_REQ_BODY
|
||||
print_KDFAlgorithmId
|
||||
print_KERB_ARMOR_SERVICE_REPLY
|
||||
print_KERB_CRED
|
||||
print_KerberosString
|
||||
print_KerberosTime
|
||||
print_KERB_TGS_REP_IN
|
||||
print_KERB_TGS_REP_OUT
|
||||
print_KERB_TGS_REQ_IN
|
||||
print_KERB_TGS_REQ_OUT
|
||||
print_KERB_TIMES
|
||||
print_KeyEncryptionAlgorithmIdentifier
|
||||
print_KeyIdentifier
|
||||
print_KeyTransRecipientInfo
|
||||
print_KeyUsage
|
||||
print_Krb5Int32
|
||||
print_KRB5PrincipalName
|
||||
print_KRB5SignedPath
|
||||
print_KRB5SignedPathData
|
||||
print_Krb5UInt32
|
||||
print_KRB_CRED
|
||||
print_KrbCredInfo
|
||||
print_KRB_ERROR
|
||||
print_KrbFastArmor
|
||||
print_KrbFastArmoredRep
|
||||
print_KrbFastArmoredReq
|
||||
print_KrbFastFinished
|
||||
print_KrbFastReq
|
||||
print_KrbFastResponse
|
||||
print_KRB_PRIV
|
||||
print_KRB_SAFE
|
||||
print_KRB_SAFE_BODY
|
||||
print_Kx509CSRPlus
|
||||
print_Kx509ErrorCode
|
||||
print_KX509_ERROR_CODE
|
||||
print_Kx509Request
|
||||
print_Kx509Response
|
||||
print_LastReq
|
||||
print_LR_TYPE
|
||||
print_MessageDigest
|
||||
print_MESSAGE_TYPE
|
||||
print_METHOD_DATA
|
||||
print_MS_UPN_SAN
|
||||
print_Name
|
||||
print_NameConstraints
|
||||
print_NAME_TYPE
|
||||
print_NoticeReference
|
||||
print_NTLMInit
|
||||
print_NTLMInitReply
|
||||
print_NTLMReply
|
||||
print_NTLMRequest
|
||||
print_NTLMRequest2
|
||||
print_NTLMResponse
|
||||
print_OCSPBasicOCSPResponse
|
||||
print_OCSPCertID
|
||||
print_OCSPCertStatus
|
||||
print_OCSPInnerRequest
|
||||
print_OCSPKeyHash
|
||||
print_OCSPRequest
|
||||
print_OCSPResponderID
|
||||
print_OCSPResponse
|
||||
print_OCSPResponseBytes
|
||||
print_OCSPResponseData
|
||||
print_OCSPResponseStatus
|
||||
print_OCSPSignature
|
||||
print_OCSPSingleResponse
|
||||
print_OCSPTBSRequest
|
||||
print_OCSPVersion
|
||||
print_OriginatorInfo
|
||||
print_OtherName
|
||||
print_PA_DATA
|
||||
print_PADATA_TYPE
|
||||
print_PA_ENC_SAM_RESPONSE_ENC
|
||||
print_PA_ENC_TS_ENC
|
||||
print_PA_FX_FAST_REPLY
|
||||
print_PA_FX_FAST_REQUEST
|
||||
print_PA_PAC_REQUEST
|
||||
print_PA_PK_AS_REP
|
||||
print_PA_PK_AS_REP_BTMM
|
||||
print_PA_PK_AS_REP_Win2k
|
||||
print_PA_PK_AS_REQ
|
||||
print_PA_PK_AS_REQ_Win2k
|
||||
print_PA_S4U2Self
|
||||
print_PA_SAM_CHALLENGE_2
|
||||
print_PA_SAM_CHALLENGE_2_BODY
|
||||
print_PA_SAM_REDIRECT
|
||||
print_PA_SAM_RESPONSE_2
|
||||
print_PA_SAM_TYPE
|
||||
print_PA_ServerReferralData
|
||||
print_PA_SERVER_REFERRAL_DATA
|
||||
print_PA_SvrReferralData
|
||||
print_PermanentIdentifier
|
||||
print_PKAuthenticator
|
||||
print_PKAuthenticator_Win2k
|
||||
print_PKCS12_Attribute
|
||||
print_PKCS12_Attributes
|
||||
print_PKCS12_AuthenticatedSafe
|
||||
print_PKCS12_CertBag
|
||||
print_PKCS12_MacData
|
||||
print_PKCS12_OctetString
|
||||
print_PKCS12_PBEParams
|
||||
print_PKCS12_PFX
|
||||
print_PKCS12_SafeBag
|
||||
print_PKCS12_SafeContents
|
||||
print_PKCS8Attributes
|
||||
print_PKCS8EncryptedData
|
||||
print_PKCS8EncryptedPrivateKeyInfo
|
||||
print_PKCS8PrivateKey
|
||||
print_PKCS8PrivateKeyAlgorithmIdentifier
|
||||
print_PKCS8PrivateKeyInfo
|
||||
print_PKCS9_BMPString
|
||||
print_PKCS9_friendlyName
|
||||
print_PkinitSP80056AOtherInfo
|
||||
print_PkinitSuppPubInfo
|
||||
print_PKIXXmppAddr
|
||||
print_PolicyConstraints
|
||||
print_PolicyInformation
|
||||
print_PolicyMapping
|
||||
print_PolicyMappings
|
||||
print_PolicyQualifierId
|
||||
print_PolicyQualifierInfo
|
||||
print_PolicyQualifierInfos
|
||||
print_PreferredOrLegacyPackageIdentifier
|
||||
print_PreferredOrLegacyStalePackageIdentifier
|
||||
print_PreferredPackageIdentifier
|
||||
print_Principal
|
||||
print_PrincipalName
|
||||
print_Principals
|
||||
print_PrivateKeyUsagePeriod
|
||||
print_PROV_SRV_LOCATION
|
||||
print_ProxyCertInfo
|
||||
print_ProxyPolicy
|
||||
print_RDNSequence
|
||||
print_Realm
|
||||
print_RecipientIdentifier
|
||||
print_RecipientInfo
|
||||
print_RecipientInfos
|
||||
print_RelativeDistinguishedName
|
||||
print_ReplyKeyPack
|
||||
print_ReplyKeyPack_Win2k
|
||||
print_RSAPrivateKey
|
||||
print_RSAPublicKey
|
||||
print_SAMFlags
|
||||
print_SecurityLevel
|
||||
print_SignatureAlgorithmIdentifier
|
||||
print_SignatureValue
|
||||
print_SignedData
|
||||
print_SignerIdentifier
|
||||
print_SignerInfo
|
||||
print_SignerInfos
|
||||
print_SingleAttribute
|
||||
print_SkipCerts
|
||||
print_SRVName
|
||||
print_StrengthOfFunction
|
||||
print_SubjectDirectoryAttributes
|
||||
print_SubjectInfoAccessSyntax
|
||||
print_SubjectKeyIdentifier
|
||||
print_SubjectPublicKeyInfo
|
||||
print_TargetHardwareIdentifiers
|
||||
print_TBSCertificate
|
||||
print_TBSCRLCertList
|
||||
print_TD_DH_PARAMETERS
|
||||
print_TD_INVALID_CERTIFICATES
|
||||
print_TD_TRUSTED_CERTIFIERS
|
||||
print_TGS_REP
|
||||
print_TGS_REQ
|
||||
print_Ticket
|
||||
print_TicketFlags
|
||||
print_Time
|
||||
print_TPMSecurityAssertions
|
||||
print_TPMSpecification
|
||||
print_TPMVersion
|
||||
print_TransitedEncoding
|
||||
print_TrustedCA
|
||||
print_TrustedCA_Win2k
|
||||
print_TypedData
|
||||
print_TYPED_DATA
|
||||
print_UniqueIdentifier
|
||||
print_UnprotectedAttributes
|
||||
print_URIReference
|
||||
print_UserNotice
|
||||
print_ValidationParms
|
||||
print_Validity
|
||||
print_VendorLoadErrorCode
|
||||
print_Version
|
||||
print_WrappedFirmwareKey
|
||||
print_X520CommonName
|
||||
print_X520LocalityName
|
||||
print_X520name
|
||||
print_X520OrganizationalUnitName
|
||||
print_X520OrganizationName
|
||||
print_X520StateOrProvinceName
|
||||
print_X690SampleChildInformation
|
||||
print_X690SampleDate
|
||||
print_X690SampleEmployeeNumber
|
||||
print_X690SampleName
|
||||
print_X690SamplePersonnelRecord
|
||||
remove_AttributeValues
|
||||
remove_AuthorizationData
|
||||
remove_CertificatePolicies
|
||||
|
@@ -319,6 +319,7 @@ der_print_heim_oid_sym(const heim_oid *oid, char delim, char **strp)
|
||||
const char *sym;
|
||||
char *s1 = NULL;
|
||||
char *s2 = NULL;
|
||||
char *p;
|
||||
int ret;
|
||||
|
||||
if (der_find_heim_oid_by_oid(oid, &sym))
|
||||
@@ -330,6 +331,11 @@ der_print_heim_oid_sym(const heim_oid *oid, char delim, char **strp)
|
||||
*strp = s1;
|
||||
return 0;
|
||||
}
|
||||
p = s2 + strlen(s1) + 1;
|
||||
for (p = s2 + strlen(s1) + 1; *p; p++) {
|
||||
if (*p == '_')
|
||||
*p = '-';
|
||||
}
|
||||
*strp = s2;
|
||||
free(s1);
|
||||
return 0;
|
||||
|
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "der_locl.h"
|
||||
#include <com_err.h>
|
||||
#include <vis.h>
|
||||
|
||||
struct asn1_type_func asn1_template_prim[A1T_NUM_ENTRY] = {
|
||||
#define el(name, type) { \
|
||||
@@ -43,6 +44,7 @@ struct asn1_type_func asn1_template_prim[A1T_NUM_ENTRY] = {
|
||||
(asn1_type_length)der_length_##name, \
|
||||
(asn1_type_copy)der_copy_##name, \
|
||||
(asn1_type_release)der_free_##name, \
|
||||
(asn1_type_print)der_print_##name, \
|
||||
sizeof(type) \
|
||||
}
|
||||
#define elber(name, type) { \
|
||||
@@ -51,6 +53,7 @@ struct asn1_type_func asn1_template_prim[A1T_NUM_ENTRY] = {
|
||||
(asn1_type_length)der_length_##name, \
|
||||
(asn1_type_copy)der_copy_##name, \
|
||||
(asn1_type_release)der_free_##name, \
|
||||
(asn1_type_print)der_print_##name, \
|
||||
sizeof(type) \
|
||||
}
|
||||
el(integer, int),
|
||||
@@ -73,7 +76,8 @@ struct asn1_type_func asn1_template_prim[A1T_NUM_ENTRY] = {
|
||||
el(bit_string, heim_bit_string),
|
||||
{ (asn1_type_encode)der_put_boolean, (asn1_type_decode)der_get_boolean,
|
||||
(asn1_type_length)der_length_boolean, (asn1_type_copy)der_copy_integer,
|
||||
(asn1_type_release)der_free_integer, sizeof(int)
|
||||
(asn1_type_release)der_free_integer, (asn1_type_print)der_print_boolean,
|
||||
sizeof(int)
|
||||
},
|
||||
el(oid, heim_oid),
|
||||
el(general_string, heim_general_string),
|
||||
@@ -524,16 +528,23 @@ _asn1_decode_open_type(const struct asn1_template *t,
|
||||
* An object set template looks like:
|
||||
*
|
||||
* const struct asn1_template asn1_ObjectSetName[] = {
|
||||
* { 0, 0, ((void*)17) }, // HEADER ENTRY, here 17 objects
|
||||
* // then two entries per object:
|
||||
* // Header entry (in this case it says there's 17 objects):
|
||||
* { 0, 0, ((void*)17) },
|
||||
*
|
||||
* // here's the name of the object set:
|
||||
* { A1_OP_NAME, 0, "ObjectSetName" },
|
||||
*
|
||||
* // then three entries per object: object name, object type ID,
|
||||
* // object type:
|
||||
* { A1_OP_NAME, 0, "ext-AuthorityInfoAccess" },
|
||||
* { A1_OP_OPENTYPE_ID, 0, (const void*)&asn1_oid_oidName },
|
||||
* { A1_OP_OPENTYPE, sizeof(SomeType), (const void*)&asn1_SomeType },
|
||||
* ...
|
||||
* };
|
||||
*
|
||||
* `i' will be a logical object offset, so i*2+1 will be the index of the
|
||||
* A1_OP_OPENTYPE_ID entry for the current object, and i*2+2 will be the
|
||||
* index of the A1_OP_OPENTYPE entry for the current object.
|
||||
* `i' being a logical object offset, i*3+3 would be the index of the
|
||||
* A1_OP_OPENTYPE_ID entry for the current object, and i*3+4 the index of
|
||||
* the A1_OP_OPENTYPE entry for the current object.
|
||||
*/
|
||||
if (t->tt & A1_OS_IS_SORTED) {
|
||||
size_t left = 0;
|
||||
@@ -544,13 +555,13 @@ _asn1_decode_open_type(const struct asn1_template *t,
|
||||
while (left <= right) {
|
||||
size_t mid = (left + right) >> 1;
|
||||
|
||||
if ((tos[1 + mid * 2].tt & A1_OP_MASK) != A1_OP_OPENTYPE_ID)
|
||||
if ((tos[3 + mid * 3].tt & A1_OP_MASK) != A1_OP_OPENTYPE_ID)
|
||||
return 0;
|
||||
if (typeid_is_int)
|
||||
c = typeid_int_cmp(vp, (intptr_t)tos[1 + mid * 2].ptr,
|
||||
c = typeid_int_cmp(vp, (intptr_t)tos[3 + mid * 3].ptr,
|
||||
ttypeid_univ);
|
||||
else if (typeid_is_oid)
|
||||
c = der_heim_oid_cmp(vp, tos[1 + mid * 2].ptr);
|
||||
c = der_heim_oid_cmp(vp, tos[3 + mid * 3].ptr);
|
||||
if (c < 0) {
|
||||
if (mid)
|
||||
right = mid - 1;
|
||||
@@ -568,15 +579,15 @@ _asn1_decode_open_type(const struct asn1_template *t,
|
||||
} else {
|
||||
for (i = 0, n = A1_HEADER_LEN(tos); i < n; i++) {
|
||||
/* We add 1 to `i' because we're skipping the header */
|
||||
if ((tos[1 + i*2].tt & A1_OP_MASK) != A1_OP_OPENTYPE_ID)
|
||||
if ((tos[3 + i*3].tt & A1_OP_MASK) != A1_OP_OPENTYPE_ID)
|
||||
return 0;
|
||||
if (typeid_is_int &&
|
||||
typeid_int_cmp(DPO(data, ttypeid->offset),
|
||||
(intptr_t)tos[1 + i*2].ptr,
|
||||
(intptr_t)tos[3 + i*3].ptr,
|
||||
ttypeid_univ))
|
||||
continue;
|
||||
if (typeid_is_oid &&
|
||||
der_heim_oid_cmp(DPO(data, ttypeid->offset), tos[1 + i*2].ptr))
|
||||
der_heim_oid_cmp(DPO(data, ttypeid->offset), tos[3 + i*3].ptr))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
@@ -592,7 +603,7 @@ _asn1_decode_open_type(const struct asn1_template *t,
|
||||
* the object we'll be decoding into, and its `ptr' is the pointer to the
|
||||
* template for decoding that type.
|
||||
*/
|
||||
tactual_type = &tos[i*2 + 2];
|
||||
tactual_type = &tos[i*3 + 4];
|
||||
|
||||
/* Decode the encoded open type value(s) */
|
||||
if (!(t->tt & A1_OS_OT_IS_ARRAY)) {
|
||||
@@ -1074,7 +1085,7 @@ _asn1_decode(const struct asn1_template *t, unsigned flags,
|
||||
*/
|
||||
*element = 1;
|
||||
|
||||
for (i = 1; i < A1_HEADER_LEN(choice) + 1; i++) {
|
||||
for (i = 1; i < A1_HEADER_LEN(choice) + 1 && choice[i].tt; i++) {
|
||||
/*
|
||||
* This is more permissive than is required. CHOICE
|
||||
* alternatives must have different outer tags, so in principle
|
||||
@@ -1102,10 +1113,11 @@ _asn1_decode(const struct asn1_template *t, unsigned flags,
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (i >= A1_HEADER_LEN(choice) + 1) {
|
||||
if (i >= A1_HEADER_LEN(choice) + 1 || !choice[i].tt) {
|
||||
if (choice->tt == 0)
|
||||
return ASN1_BAD_ID;
|
||||
|
||||
/* This is the ellipsis case */
|
||||
*element = 0;
|
||||
ret = der_get_octet_string(p, len,
|
||||
DPO(data, choice->tt), &datalen);
|
||||
@@ -1261,13 +1273,13 @@ _asn1_encode_open_type(const struct asn1_template *t,
|
||||
* field.
|
||||
*/
|
||||
ret = typeid_int_copy(DPO(data, ttypeid->offset),
|
||||
(intptr_t)tos[1 + (element-1)*2].ptr, ttypeid_univ);
|
||||
(intptr_t)tos[3 + (element-1)*3].ptr, ttypeid_univ);
|
||||
} else if (typeid_is_oid) {
|
||||
/*
|
||||
* Copy the OID from the type ID object field to the type ID struct
|
||||
* field.
|
||||
*/
|
||||
ret = der_copy_oid(tos[1 + (element-1)*2].ptr, DPO(data, ttypeid->offset));
|
||||
ret = der_copy_oid(tos[3 + (element-1)*3].ptr, DPO(data, ttypeid->offset));
|
||||
} else
|
||||
enotsup = 1;
|
||||
|
||||
@@ -1278,7 +1290,7 @@ _asn1_encode_open_type(const struct asn1_template *t,
|
||||
if (enotsup)
|
||||
return ENOTSUP;
|
||||
|
||||
tactual_type = &tos[(element-1)*2 + 2];
|
||||
tactual_type = &tos[(element-1)*3 + 4];
|
||||
|
||||
if (!(t->tt & A1_OS_OT_IS_ARRAY)) {
|
||||
struct heim_base_data *os = DPO(data, topentype->offset);
|
||||
@@ -1861,11 +1873,11 @@ _asn1_length_open_type(const struct asn1_template *tbase,
|
||||
} else if (typeid_is_oid) {
|
||||
heim_oid no_oid = { 0, 0 };
|
||||
|
||||
sz = _asn1_length_open_type_id(ttypeid, tos[1 + (element - 1)*2].ptr);
|
||||
sz = _asn1_length_open_type_id(ttypeid, tos[3 + (element - 1)*3].ptr);
|
||||
sz -= _asn1_length_open_type_id(ttypeid, &no_oid);
|
||||
}
|
||||
|
||||
tactual_type = &tos[(element-1)*2 + 2];
|
||||
tactual_type = &tos[(element-1)*3 + 4];
|
||||
|
||||
/* Compute the size of the encoded value(s) */
|
||||
if (!(t->tt & A1_OS_OT_IS_ARRAY)) {
|
||||
@@ -2126,7 +2138,7 @@ _asn1_free_open_type(const struct asn1_template *t, /* object set template */
|
||||
/* XXX We assume sizeof(enum) == sizeof(int) */
|
||||
if (!*elementp || *elementp >= A1_HEADER_LEN(tos) + 1)
|
||||
return; /* Unknown choice -> it's not decoded, nothing to free here */
|
||||
tactual_type = tos[2*(*elementp - 1) + 2].ptr;
|
||||
tactual_type = tos[3*(*elementp - 1) + 4].ptr;
|
||||
|
||||
if (!(t->tt & A1_OS_OT_IS_ARRAY)) {
|
||||
dp = DPO(data, t->offset + sizeof(*elementp));
|
||||
@@ -2271,6 +2283,363 @@ _asn1_free(const struct asn1_template *t, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
getindent(int flags, unsigned int i)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (!(flags & ASN1_PRINT_INDENT) || i == 0)
|
||||
return NULL;
|
||||
if (i > 128)
|
||||
i = 128;
|
||||
if ((s = malloc(i * 2 + 2)) == NULL)
|
||||
return NULL;
|
||||
s[0] = '\n';
|
||||
s[i * 2 + 1] = '\0';
|
||||
memset(s + 1, ' ', i * 2);
|
||||
return s;
|
||||
}
|
||||
|
||||
static struct rk_strpool *_asn1_print(const struct asn1_template *,
|
||||
struct rk_strpool *,
|
||||
int,
|
||||
unsigned int,
|
||||
const void *,
|
||||
const heim_octet_string *);
|
||||
|
||||
/* See commentary in _asn1_decode_open_type() */
|
||||
static struct rk_strpool *
|
||||
_asn1_print_open_type(const struct asn1_template *t, /* object set template */
|
||||
struct rk_strpool *r,
|
||||
int flags,
|
||||
unsigned int indent,
|
||||
const void *data,
|
||||
const char *opentype_name)
|
||||
{
|
||||
const struct asn1_template *tactual_type;
|
||||
const struct asn1_template *tos = t->ptr;
|
||||
const unsigned int *lenp = NULL; /* Pointer to array length field */
|
||||
unsigned int len = 1; /* Array length */
|
||||
size_t i;
|
||||
const void * const *dp;
|
||||
const void * const *val;
|
||||
const int *elementp = DPOC(data, t->offset); /* Choice enum pointer */
|
||||
char *indents = getindent(flags, indent);
|
||||
char *s;
|
||||
|
||||
/* XXX We assume sizeof(enum) == sizeof(int) */
|
||||
if (!*elementp || *elementp >= A1_HEADER_LEN(tos) + 1) {
|
||||
r = rk_strpoolprintf(r, ",%s\"_%s_choice\":\"_ERROR_DECODING_\"",
|
||||
indents ? indents : "", opentype_name);
|
||||
free(indents);
|
||||
}
|
||||
tactual_type = tos[3*(*elementp - 1) + 4].ptr;
|
||||
|
||||
r = rk_strpoolprintf(r, ",%s\"_%s_choice\":\"%s\"",
|
||||
indents ? indents : "", opentype_name,
|
||||
(const char *)tos[3*(*elementp - 1) + 2].ptr);
|
||||
if (!r) {
|
||||
free(indents);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!(t->tt & A1_OS_OT_IS_ARRAY)) {
|
||||
dp = DPOC(data, t->offset + sizeof(*elementp));
|
||||
while (sizeof(void *) != sizeof(*elementp) &&
|
||||
((uintptr_t)dp) % sizeof(void *) != 0)
|
||||
dp = (void *)(((char *)dp) + sizeof(*elementp));
|
||||
if (*dp) {
|
||||
struct rk_strpool *r2 = NULL;
|
||||
|
||||
r2 = _asn1_print(tactual_type, r2, flags, indent + 1, *dp, NULL);
|
||||
if (r2 == NULL) {
|
||||
r = rk_strpoolprintf(r,
|
||||
",%s\"_%s\":\"_ERROR_FORMATTING_\"",
|
||||
indents ? indents : "", opentype_name);
|
||||
free(indents);
|
||||
return r;
|
||||
}
|
||||
s = rk_strpoolcollect(r2);
|
||||
r = rk_strpoolprintf(r, ",%s\"_%s\":%s",
|
||||
indents ? indents : "", opentype_name, s);
|
||||
free(indents);
|
||||
free(s);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
lenp = DPOC(data, t->offset + sizeof(*elementp));
|
||||
len = *lenp;
|
||||
dp = DPOC(data, t->offset + sizeof(*elementp) + sizeof(*lenp));
|
||||
while (sizeof(void *) != sizeof(*elementp) &&
|
||||
((uintptr_t)dp) % sizeof(void *) != 0)
|
||||
dp = (void *)(((char *)dp) + sizeof(*elementp));
|
||||
val = *dp;
|
||||
|
||||
r = rk_strpoolprintf(r, ",%s\"_%s\":[", indents ? indents : "",
|
||||
opentype_name);
|
||||
free(indents);
|
||||
indents = getindent(flags, indent + 1);
|
||||
if (indents)
|
||||
r = rk_strpoolprintf(r, "%s", indents ? indents : "");
|
||||
for (i = 0; r && i < len; i++) {
|
||||
struct rk_strpool *r2 = NULL;
|
||||
if (val[i]) {
|
||||
r2 = _asn1_print(tactual_type, r2, flags, indent + 2, val[i], NULL);
|
||||
if (r2 == NULL)
|
||||
continue;
|
||||
}
|
||||
if (i)
|
||||
r = rk_strpoolprintf(r, ",%s", indents ? indents : "");
|
||||
if (r)
|
||||
r = rk_strpoolprintf(r, "%s", (s = rk_strpoolcollect(r2)));
|
||||
free(s);
|
||||
}
|
||||
return rk_strpoolprintf(r, "]");
|
||||
}
|
||||
|
||||
static struct rk_strpool *
|
||||
_asn1_print(const struct asn1_template *t,
|
||||
struct rk_strpool *r,
|
||||
int flags,
|
||||
unsigned int indent,
|
||||
const void *data,
|
||||
const heim_octet_string *saved)
|
||||
{
|
||||
const struct asn1_template *tbase = t;
|
||||
const struct asn1_template *tnames;
|
||||
size_t nelements = A1_HEADER_LEN(t);
|
||||
size_t elements = nelements;
|
||||
size_t nnames = 0;
|
||||
char *indents = getindent(flags, indent);
|
||||
|
||||
for (t += nelements; t > tbase && (t->tt & A1_OP_MASK) == A1_OP_NAME; t--)
|
||||
nnames++;
|
||||
|
||||
tnames = tbase + nelements - nnames + 1;
|
||||
|
||||
if (nnames)
|
||||
r = rk_strpoolprintf(r, "%s{\"_type\":\"%s\"",
|
||||
indents ? indents : "",
|
||||
(const char *)(tnames++)->ptr);
|
||||
if (saved && r) {
|
||||
char *s = der_print_octet_string(data, 0);
|
||||
|
||||
if (!s) {
|
||||
rk_strpoolfree(r);
|
||||
free(indents);
|
||||
return NULL;
|
||||
}
|
||||
r = rk_strpoolprintf(r, ",%s\"_save\":\"%s\"",
|
||||
indents ? indents : "", s);
|
||||
free(s);
|
||||
}
|
||||
saved = NULL;
|
||||
if (tbase->tt & A1_HF_PRESERVE)
|
||||
saved = data;
|
||||
|
||||
t = tbase + 1;
|
||||
while (elements && (t->tt & A1_OP_MASK) != A1_OP_NAME) {
|
||||
switch (t->tt & A1_OP_MASK) {
|
||||
case A1_OP_NAME:
|
||||
continue;
|
||||
case A1_OP_DEFVAL:
|
||||
t++;
|
||||
elements--;
|
||||
continue;
|
||||
case A1_OP_OPENTYPE_OBJSET: {
|
||||
size_t opentype = (t->tt >> 10) & ((1<<10)-1);
|
||||
r = _asn1_print_open_type(t, r, flags, indent + 1, data,
|
||||
tbase[(nelements - nnames) + 2 + opentype].ptr);
|
||||
t++;
|
||||
elements--;
|
||||
continue;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
if (nnames)
|
||||
r = rk_strpoolprintf(r, ",%s\"%s\":",
|
||||
indents ? indents : "",
|
||||
(const char *)(tnames++)->ptr);
|
||||
switch (t->tt & A1_OP_MASK) {
|
||||
case A1_OP_OPENTYPE_OBJSET:
|
||||
break;
|
||||
case A1_OP_NAME: break;
|
||||
case A1_OP_DEFVAL: break;
|
||||
case A1_OP_TYPE:
|
||||
case A1_OP_TYPE_EXTERN: {
|
||||
const void *el = DPOC(data, t->offset);
|
||||
|
||||
if (t->tt & A1_FLAG_OPTIONAL) {
|
||||
const void * const *pel = (const void *const *)el;
|
||||
if (*pel == NULL) {
|
||||
r = rk_strpoolprintf(r, "null");
|
||||
break;
|
||||
}
|
||||
el = *pel;
|
||||
}
|
||||
|
||||
if ((t->tt & A1_OP_MASK) == A1_OP_TYPE) {
|
||||
r = _asn1_print(t->ptr, r, flags, indent + 1, el, saved);
|
||||
} else {
|
||||
const struct asn1_type_func *f = t->ptr;
|
||||
char *s2 = NULL;
|
||||
char *s = NULL;
|
||||
|
||||
s = (f->print)(el, 0);
|
||||
if (s == NULL ||
|
||||
rk_strasvis(&s2, s, VIS_TAB|VIS_NL|VIS_DQ, "") == -1) {
|
||||
rk_strpoolfree(r);
|
||||
free(indents);
|
||||
free(s);
|
||||
return NULL;
|
||||
}
|
||||
free(s);
|
||||
r = rk_strpoolprintf(r, "\"%s\"", s2);
|
||||
free(s2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case A1_OP_PARSE: {
|
||||
unsigned int type = A1_PARSE_TYPE(t->tt);
|
||||
const void *el = DPOC(data, t->offset);
|
||||
char *s = NULL;
|
||||
|
||||
if (type >= sizeof(asn1_template_prim)/sizeof(asn1_template_prim[0])) {
|
||||
ABORT_ON_ERROR();
|
||||
break;
|
||||
}
|
||||
s = (asn1_template_prim[type].print)(el, flags);
|
||||
switch (type) {
|
||||
case A1T_OID:
|
||||
case A1T_BOOLEAN:
|
||||
case A1T_INTEGER:
|
||||
case A1T_INTEGER64:
|
||||
case A1T_UNSIGNED:
|
||||
case A1T_UNSIGNED64:
|
||||
if (s)
|
||||
r = rk_strpoolprintf(r, "%s", s);
|
||||
break;
|
||||
default: {
|
||||
char *s2 = NULL;
|
||||
|
||||
if (s)
|
||||
(void) rk_strasvis(&s2, s, VIS_TAB|VIS_NL|VIS_DQ, "");
|
||||
free(s);
|
||||
s = s2;
|
||||
if (s)
|
||||
r = rk_strpoolprintf(r, "\"%s\"", s);
|
||||
}
|
||||
}
|
||||
if (!s) {
|
||||
rk_strpoolfree(r);
|
||||
free(indents);
|
||||
return NULL;
|
||||
}
|
||||
free(s);
|
||||
break;
|
||||
}
|
||||
case A1_OP_TAG: {
|
||||
const void *el = DPOC(data, t->offset);
|
||||
|
||||
if (t->tt & A1_FLAG_OPTIONAL) {
|
||||
const void * const *pel = (const void * const *)el;
|
||||
if (*pel == NULL) {
|
||||
r = rk_strpoolprintf(r, "null");
|
||||
break;
|
||||
}
|
||||
el = *pel;
|
||||
}
|
||||
|
||||
r = _asn1_print(t->ptr, r, flags, indent + 1, el, saved);
|
||||
break;
|
||||
}
|
||||
case A1_OP_SETOF:
|
||||
case A1_OP_SEQOF: {
|
||||
const struct template_of *el = DPOC(data, t->offset);
|
||||
size_t ellen = _asn1_sizeofType(t->ptr);
|
||||
const unsigned char *element = el->val;
|
||||
unsigned int i;
|
||||
|
||||
r = rk_strpoolprintf(r, "%s[", indents ? indents : "");
|
||||
for (i = 0; r && i < el->len; i++) {
|
||||
if (i)
|
||||
r = rk_strpoolprintf(r, ",%s", indents ? indents : "");
|
||||
r = _asn1_print(t->ptr, r, flags, indent + 1, element, saved);
|
||||
element += ellen;
|
||||
}
|
||||
if (r)
|
||||
r = rk_strpoolprintf(r, "]");
|
||||
break;
|
||||
}
|
||||
case A1_OP_BMEMBER: {
|
||||
const struct asn1_template *bmember = t->ptr;
|
||||
size_t size = bmember->offset;
|
||||
size_t belements = A1_HEADER_LEN(bmember);
|
||||
int first = 1;
|
||||
|
||||
bmember += belements;
|
||||
r = rk_strpoolprintf(r, "%s[", indents ? indents : "");
|
||||
while (r && belements) {
|
||||
if (!first)
|
||||
r = rk_strpoolprintf(r, ",");
|
||||
if (r && _asn1_bmember_isset_bit(data, bmember->offset, size))
|
||||
r = rk_strpoolprintf(r, "%s\"%s\"", indents ? indents : "",
|
||||
(const char *)bmember->ptr);
|
||||
belements--; bmember--;
|
||||
}
|
||||
if (r)
|
||||
r = rk_strpoolprintf(r, "]");
|
||||
break;
|
||||
}
|
||||
case A1_OP_CHOICE: {
|
||||
const struct asn1_template *choice = t->ptr;
|
||||
const unsigned int *element = DPOC(data, choice->offset);
|
||||
unsigned int nchoices = ((uintptr_t)choice->ptr) >> 1;
|
||||
|
||||
if (*element > A1_HEADER_LEN(choice)) {
|
||||
r = rk_strpoolprintf(r, "null");
|
||||
} else if (*element == 0) {
|
||||
r = rk_strpoolprintf(r, "null");
|
||||
} else {
|
||||
choice += *element;
|
||||
r = rk_strpoolprintf(r, "%s{\"_choice\":\"%s\",%s\"value\":",
|
||||
indents ? indents : "",
|
||||
(const char *)choice[nchoices].ptr,
|
||||
indents ? indents : "");
|
||||
if (r)
|
||||
r = _asn1_print(choice->ptr, r, flags, indent + 1,
|
||||
DPOC(data, choice->offset), NULL);
|
||||
if (r)
|
||||
r = rk_strpoolprintf(r, "}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ABORT_ON_ERROR();
|
||||
break;
|
||||
}
|
||||
t++;
|
||||
elements--;
|
||||
}
|
||||
free(indents);
|
||||
if (nnames && r)
|
||||
return rk_strpoolprintf(r, "}");
|
||||
return r;
|
||||
}
|
||||
|
||||
char *
|
||||
_asn1_print_top(const struct asn1_template *t,
|
||||
int flags,
|
||||
const void *data)
|
||||
{
|
||||
struct rk_strpool *r = _asn1_print(t, NULL, flags, 0, data, NULL);
|
||||
|
||||
if (r == NULL)
|
||||
return NULL;
|
||||
return rk_strpoolcollect(r);
|
||||
}
|
||||
|
||||
/* See commentary in _asn1_decode_open_type() */
|
||||
static int
|
||||
_asn1_copy_open_type(const struct asn1_template *t, /* object set template */
|
||||
@@ -2299,7 +2668,7 @@ _asn1_copy_open_type(const struct asn1_template *t, /* object set template */
|
||||
memset(etop, 0, sizeof(int) + sizeof(void *));
|
||||
return 0; /* Unknown choice -> not copied */
|
||||
}
|
||||
tactual_type = &tos[2*(*efromp - 1) + 2];
|
||||
tactual_type = &tos[3*(*efromp - 1) + 4];
|
||||
|
||||
if (!(t->tt & A1_OS_OT_IS_ARRAY)) {
|
||||
dfromp = DPO(from, t->offset + sizeof(*efromp));
|
||||
|
Reference in New Issue
Block a user