asn1: Enrich asn1_print with schema
Our asn1_print, like OpenSSL's, just knows how to parse and dump DER. Ours can attempt to decode OCTET STRING and IMPLICIT-tagged constructed values as DER, which is very useful. But _now_ it's even better. Now it knows about all types exported from all ASN.1 modules in `lib/asn1/` in Heimdal, and if told to print as some type, it will use the new printing interface to print JSON-like representations of values: ``` $ ./asn1_print /tmp/t490/ek2.crt Certificate | jq '.tbsCertificate.extensions[3]._extnValue[]._values' [ { "_type": "TPMSpecification", "family": "2.0", "level": "0", "revision": "138" } ] [ { "_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 } ] ```
This commit is contained in:
@@ -9,10 +9,10 @@ annotations](/lib/asn1/README-X681.md).
|
||||
|
||||
1. [Introduction](#Introduction)
|
||||
2. [ASN.1 Support in Heimdal](#asn1-support-in-heimdal)
|
||||
3. [News](#News)
|
||||
4. [Features](#Features)
|
||||
5. [Limitations](#Limitations)
|
||||
6. [Compiler Usage](#Compiler-usage)
|
||||
3. [Features](#Features)
|
||||
4. [Limitations](#Limitations)
|
||||
5. [Compiler Usage](#Compiler-usage)
|
||||
6. [asn1_print Usage](#asn1_print-usage)
|
||||
7. [Implementation](#implementation)
|
||||
8. [Moving From C](#moving-from-c)
|
||||
|
||||
@@ -164,7 +164,7 @@ make it easy to add support for encoding rules other than X.690.
|
||||
|
||||
```bash
|
||||
$ ./asn1_print ek.crt Certificate |
|
||||
jq '.tbsCertificate.extensions[3]._open_type[]._open_type'
|
||||
jq '.tbsCertificate.extensions[3]._extnValue[]._values'
|
||||
```
|
||||
|
||||
```JSON
|
||||
@@ -180,7 +180,7 @@ make it easy to add support for encoding rules other than X.690.
|
||||
{
|
||||
"_type": "TPMSecurityAssertions",
|
||||
"version": "0",
|
||||
"fieldUpgradable": "1",
|
||||
"fieldUpgradable": true,
|
||||
"ekGenerationType": "655617",
|
||||
"ekGenerationLocation": "655616",
|
||||
"ekCertificateGenerationLocation": "655616",
|
||||
@@ -189,7 +189,7 @@ make it easy to add support for encoding rules other than X.690.
|
||||
"version": "3.1",
|
||||
"assurancelevel": "4",
|
||||
"evaluationStatus": "2",
|
||||
"plus": "1",
|
||||
"plus": true,
|
||||
"strengthOfFunction": null,
|
||||
"profileOid": null,
|
||||
"profileUri": null,
|
||||
@@ -200,14 +200,564 @@ make it easy to add support for encoding rules other than X.690.
|
||||
"_type": "FIPSLevel",
|
||||
"version": "140-2",
|
||||
"level": "2",
|
||||
"plus": "0"
|
||||
"plus": false
|
||||
},
|
||||
"iso9000Certified": "0",
|
||||
"iso9000Certified": false,
|
||||
"iso9000Uri": null
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
A complete dump of such a certificate:
|
||||
|
||||
```bash
|
||||
$ ./asn1_print ek.crt Certificate | jq .
|
||||
```
|
||||
|
||||
```JSON
|
||||
{
|
||||
"_type": "Certificate",
|
||||
"tbsCertificate": {
|
||||
"_type": "TBSCertificate",
|
||||
"_save": "30820376A00302010202146A0597BA71D7E6D3AC0EDC9EDC95A15B998DE40A300D06092A864886F70D01010B05003055310B3009060355040613024348311E301C060355040A131553544D6963726F656C656374726F6E696373204E56312630240603550403131D53544D2054504D20454B20496E7465726D656469617465204341203035301E170D3138313231343030303030305A170D3238313231343030303030305A300030820122300D06092A864886F70D01010105000382010F003082010A0282010100CC14EB27A78CEB0EA486FA2DF7835F5FA8E905B097012B5BDE50380C355B1A2A721BBC3D08DD21796CDB239FA95310651B1B56FD2CFE53C87352EBD996E33256160404CE9302A08066801E786A2F86E181F949966F492A85B58EAA4A6A8CB3697551BB236E87CC7BF8EC1347871C91E15437E8F266BF1EA5EB271FDCF374D8B47DF8BCE89E1FAD61C2A088CB4036B359CB72A294973FEDCCF0C340AFFD14B64F041165581ACA34147C1C75617047058F7ED7D603E032508094FA73E8B9153DA3BF255D2CBBC5DF301BA8F74D198BEBCE86040FC1D2927C7657414490D802F482F3EBF2DE35EE149A1A6DE8D16891FBFBA02A18AFE59F9D6F149744E5F0D559B10203010001A38201A9308201A5301F0603551D230418301680141ADB994AB58BE57A0CC9B900E7851E1A43C0866030420603551D20043B303930370604551D2000302F302D06082B060105050702011621687474703A2F2F7777772E73742E636F6D2F54504D2F7265706F7369746F72792F30590603551D110101FF044F304DA44B304931163014060567810502010C0B69643A353335343444323031173015060567810502020C0C53543333485450484148433031163014060567810502030C0B69643A303034393030303830670603551D090460305E301706056781050210310E300C0C03322E300201000202008A304306056781050212313A30380201000101FFA0030A0101A1030A0100A2030A0100A310300E1603332E310A01040A01020101FFA40F300D16053134302D320A0102010100300E0603551D0F0101FF040403020520300C0603551D130101FF0402300030100603551D250409300706056781050801304A06082B06010505070101043E303C303A06082B06010505073002862E687474703A2F2F7365637572652E676C6F62616C7369676E2E636F6D2F73746D74706D656B696E7430352E637274",
|
||||
"version": "2",
|
||||
"serialNumber": "6A0597BA71D7E6D3AC0EDC9EDC95A15B998DE40A",
|
||||
"signature": {
|
||||
"_type": "AlgorithmIdentifier",
|
||||
"algorithm": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "1.2.840.113549.1.1.11",
|
||||
"components": [
|
||||
1,
|
||||
2,
|
||||
840,
|
||||
113549,
|
||||
1,
|
||||
1,
|
||||
11
|
||||
],
|
||||
"name": "id-pkcs1-sha256WithRSAEncryption"
|
||||
},
|
||||
"parameters": "0500"
|
||||
},
|
||||
"issuer": {
|
||||
"_choice": "rdnSequence",
|
||||
"value": [
|
||||
[
|
||||
{
|
||||
"_type": "AttributeTypeAndValue",
|
||||
"type": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.5.4.6",
|
||||
"components": [
|
||||
2,
|
||||
5,
|
||||
4,
|
||||
6
|
||||
],
|
||||
"name": "id-at-countryName"
|
||||
},
|
||||
"value": {
|
||||
"_choice": "printableString",
|
||||
"value": "CH"
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"_type": "AttributeTypeAndValue",
|
||||
"type": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.5.4.10",
|
||||
"components": [
|
||||
2,
|
||||
5,
|
||||
4,
|
||||
10
|
||||
],
|
||||
"name": "id-at-organizationName"
|
||||
},
|
||||
"value": {
|
||||
"_choice": "printableString",
|
||||
"value": "STMicroelectronics NV"
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"_type": "AttributeTypeAndValue",
|
||||
"type": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.5.4.3",
|
||||
"components": [
|
||||
2,
|
||||
5,
|
||||
4,
|
||||
3
|
||||
],
|
||||
"name": "id-at-commonName"
|
||||
},
|
||||
"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": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "1.2.840.113549.1.1.1",
|
||||
"components": [
|
||||
1,
|
||||
2,
|
||||
840,
|
||||
113549,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"name": "id-pkcs1-rsaEncryption"
|
||||
},
|
||||
"parameters": "0500"
|
||||
},
|
||||
"subjectPublicKey": "2160:3082010A0282010100CC14EB27A78CEB0EA486FA2DF7835F5FA8E905B097012B5BDE50380C355B1A2A721BBC3D08DD21796CDB239FA95310651B1B56FD2CFE53C87352EBD996E33256160404CE9302A08066801E786A2F86E181F949966F492A85B58EAA4A6A8CB3697551BB236E87CC7BF8EC1347871C91E15437E8F266BF1EA5EB271FDCF374D8B47DF8BCE89E1FAD61C2A088CB4036B359CB72A294973FEDCCF0C340AFFD14B64F041165581ACA34147C1C75617047058F7ED7D603E032508094FA73E8B9153DA3BF255D2CBBC5DF301BA8F74D198BEBCE86040FC1D2927C7657414490D802F482F3EBF2DE35EE149A1A6DE8D16891FBFBA02A18AFE59F9D6F149744E5F0D559B10203010001"
|
||||
},
|
||||
"issuerUniqueID": null,
|
||||
"subjectUniqueID": null,
|
||||
"extensions": [
|
||||
{
|
||||
"_type": "Extension",
|
||||
"extnID": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.5.29.35",
|
||||
"components": [
|
||||
2,
|
||||
5,
|
||||
29,
|
||||
35
|
||||
],
|
||||
"name": "id-x509-ce-authorityKeyIdentifier"
|
||||
},
|
||||
"critical": false,
|
||||
"extnValue": "301680141ADB994AB58BE57A0CC9B900E7851E1A43C08660",
|
||||
"_extnValue_choice": "ext-AuthorityKeyIdentifier",
|
||||
"_extnValue": {
|
||||
"_type": "AuthorityKeyIdentifier",
|
||||
"keyIdentifier": "1ADB994AB58BE57A0CC9B900E7851E1A43C08660",
|
||||
"authorityCertIssuer": null,
|
||||
"authorityCertSerialNumber": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"_type": "Extension",
|
||||
"extnID": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.5.29.32",
|
||||
"components": [
|
||||
2,
|
||||
5,
|
||||
29,
|
||||
32
|
||||
],
|
||||
"name": "id-x509-ce-certificatePolicies"
|
||||
},
|
||||
"critical": false,
|
||||
"extnValue": "303930370604551D2000302F302D06082B060105050702011621687474703A2F2F7777772E73742E636F6D2F54504D2F7265706F7369746F72792F",
|
||||
"_extnValue_choice": "ext-CertificatePolicies",
|
||||
"_extnValue": [
|
||||
{
|
||||
"_type": "PolicyInformation",
|
||||
"policyIdentifier": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.5.29.32.0",
|
||||
"components": [
|
||||
2,
|
||||
5,
|
||||
29,
|
||||
32,
|
||||
0
|
||||
],
|
||||
"name": "id-x509-ce-certificatePolicies-anyPolicy"
|
||||
},
|
||||
"policyQualifiers": [
|
||||
{
|
||||
"_type": "PolicyQualifierInfo",
|
||||
"policyQualifierId": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "1.3.6.1.5.5.7.2.1",
|
||||
"components": [
|
||||
1,
|
||||
3,
|
||||
6,
|
||||
1,
|
||||
5,
|
||||
5,
|
||||
7,
|
||||
2,
|
||||
1
|
||||
],
|
||||
"name": "id-pkix-qt-cps"
|
||||
},
|
||||
"qualifier": "1621687474703A2F2F7777772E73742E636F6D2F54504D2F7265706F7369746F72792F"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"_type": "Extension",
|
||||
"extnID": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.5.29.17",
|
||||
"components": [
|
||||
2,
|
||||
5,
|
||||
29,
|
||||
17
|
||||
],
|
||||
"name": "id-x509-ce-subjectAltName"
|
||||
},
|
||||
"critical": true,
|
||||
"extnValue": "304DA44B304931163014060567810502010C0B69643A353335343444323031173015060567810502020C0C53543333485450484148433031163014060567810502030C0B69643A3030343930303038",
|
||||
"_extnValue_choice": "ext-SubjectAltName",
|
||||
"_extnValue": [
|
||||
{
|
||||
"_choice": "directoryName",
|
||||
"value": {
|
||||
"_choice": "rdnSequence",
|
||||
"value": [
|
||||
[
|
||||
{
|
||||
"_type": "AttributeTypeAndValue",
|
||||
"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",
|
||||
"type": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.23.133.2.2",
|
||||
"components": [
|
||||
2,
|
||||
23,
|
||||
133,
|
||||
2,
|
||||
2
|
||||
],
|
||||
"name": "tcg-at-tpmModel"
|
||||
},
|
||||
"value": {
|
||||
"_choice": "utf8String",
|
||||
"value": "ST33HTPHAHC0"
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"_type": "AttributeTypeAndValue",
|
||||
"type": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.23.133.2.3",
|
||||
"components": [
|
||||
2,
|
||||
23,
|
||||
133,
|
||||
2,
|
||||
3
|
||||
],
|
||||
"name": "tcg-at-tpmVersion"
|
||||
},
|
||||
"value": {
|
||||
"_choice": "utf8String",
|
||||
"value": "id:00490008"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"_type": "Extension",
|
||||
"extnID": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.5.29.9",
|
||||
"components": [
|
||||
2,
|
||||
5,
|
||||
29,
|
||||
9
|
||||
],
|
||||
"name": "id-x509-ce-subjectDirectoryAttributes"
|
||||
},
|
||||
"critical": false,
|
||||
"extnValue": "305E301706056781050210310E300C0C03322E300201000202008A304306056781050212313A30380201000101FFA0030A0101A1030A0100A2030A0100A310300E1603332E310A01040A01020101FFA40F300D16053134302D320A0102010100",
|
||||
"_extnValue_choice": "ext-SubjectDirectoryAttributes",
|
||||
"_extnValue": [
|
||||
{
|
||||
"_type": "AttributeSet",
|
||||
"type": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.23.133.2.16",
|
||||
"components": [
|
||||
2,
|
||||
23,
|
||||
133,
|
||||
2,
|
||||
16
|
||||
],
|
||||
"name": "tcg-at-tpmSpecification"
|
||||
},
|
||||
"values": [
|
||||
"300C0C03322E300201000202008A"
|
||||
],
|
||||
"_values_choice": "at-TPMSpecification",
|
||||
"_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-tpmSecurityAssertions"
|
||||
},
|
||||
"values": [
|
||||
"30380201000101FFA0030A0101A1030A0100A2030A0100A310300E1603332E310A01040A01020101FFA40F300D16053134302D320A0102010100"
|
||||
],
|
||||
"_values_choice": "at-TPMSecurityAssertions",
|
||||
"_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": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.5.29.15",
|
||||
"components": [
|
||||
2,
|
||||
5,
|
||||
29,
|
||||
15
|
||||
],
|
||||
"name": "id-x509-ce-keyUsage"
|
||||
},
|
||||
"critical": true,
|
||||
"extnValue": "03020520",
|
||||
"_extnValue_choice": "ext-KeyUsage",
|
||||
"_extnValue": [
|
||||
"keyEncipherment"
|
||||
]
|
||||
},
|
||||
{
|
||||
"_type": "Extension",
|
||||
"extnID": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.5.29.19",
|
||||
"components": [
|
||||
2,
|
||||
5,
|
||||
29,
|
||||
19
|
||||
],
|
||||
"name": "id-x509-ce-basicConstraints"
|
||||
},
|
||||
"critical": true,
|
||||
"extnValue": "3000",
|
||||
"_extnValue_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": "id-x509-ce-extKeyUsage"
|
||||
},
|
||||
"critical": false,
|
||||
"extnValue": "300706056781050801",
|
||||
"_extnValue_choice": "ext-ExtKeyUsage",
|
||||
"_extnValue": [
|
||||
{
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "2.23.133.8.1",
|
||||
"components": [
|
||||
2,
|
||||
23,
|
||||
133,
|
||||
8,
|
||||
1
|
||||
],
|
||||
"name": "tcg-kp-EKCertificate"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"_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"
|
||||
},
|
||||
"critical": false,
|
||||
"extnValue": "303C303A06082B06010505073002862E687474703A2F2F7365637572652E676C6F62616C7369676E2E636F6D2F73746D74706D656B696E7430352E637274",
|
||||
"_extnValue_choice": "ext-AuthorityInfoAccess",
|
||||
"_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": "uniformResourceIdentifier",
|
||||
"value": "http://secure.globalsign.com/stmtpmekint05.crt"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"signatureAlgorithm": {
|
||||
"_type": "AlgorithmIdentifier",
|
||||
"algorithm": {
|
||||
"_type": "OBJECT IDENTIFIER",
|
||||
"oid": "1.2.840.113549.1.1.11",
|
||||
"components": [
|
||||
1,
|
||||
2,
|
||||
840,
|
||||
113549,
|
||||
1,
|
||||
1,
|
||||
11
|
||||
],
|
||||
"name": "id-pkcs1-sha256WithRSAEncryption"
|
||||
},
|
||||
"parameters": "0500"
|
||||
},
|
||||
"signatureValue": "2048:3D4C381E5B4F1BCBE09C63D52F1F04570CAEA142FD9CD942043B11F8E3BDCF50007AE16CF8869013041E92CDD3280BA4B51FBBD40582ED750219E261A695095674855AACEB520ADAFF9E7E908480A39CDCF900462D9171960FFE55D3AC49E8C981341BBD2EFBCC252A4C18A4F3B7C84CCE42CE70A208C84D2630A7ABFBE72D6271E75B9FF1C971D20EB3DBD763F1E04D834EAA692D2E4001BBF4730A3E3FDA9711AE386524D91C63BE0E516D00D5C6141FCCF6C539F3518E180049865BE16B69CAE1F8CB7FDC474B38F7EE56CBE7D8A89D9BA99B65D5265AEF32AA62426B10E6D75BB8677EC44F755BBC2806FD2B4E04BDF5D44259DBEAA42B6F563DF7AA7506"
|
||||
}
|
||||
```
|
||||
|
||||
(Notice that OID names look a bit weird. For reasons that may have been
|
||||
lost to time and may no longer be relevant, these OIDs are defined with
|
||||
slightly different names in the ASN.1 modules in Heimdal's source tree.
|
||||
We'll fix this eventually.)
|
||||
|
||||
- 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
|
||||
@@ -349,6 +899,46 @@ HEIMDAL February 22, 2021 HEIMDAL
|
||||
|
||||
```
|
||||
|
||||
## asn1_print Usage
|
||||
|
||||
```
|
||||
ASN1_PRINT(1) BSD General Commands Manual ASN1_PRINT(1)
|
||||
|
||||
NAME
|
||||
asn1_print — dump ASN.1 DER encoded values
|
||||
|
||||
SYNOPSIS
|
||||
asn1_print [-i | --no-indent] [-I | --inner] [-l | --list-types]
|
||||
[-l -v | --version] [-l -h | --help] [FILE [TypeName]]
|
||||
|
||||
DESCRIPTION
|
||||
asn1_print Dumps ASN.1 DER-encoded values. If a TypeName is given, then
|
||||
asn1_print will print the value in a JSON-like format using its knowledge
|
||||
of the ASN.1 module defining that type. If a TypeName is given, it must
|
||||
be the name of an ASN.1 type exported by an ASN.1 module that is compiled
|
||||
into asn1_print. Use the --list-types option to list ASN.1 types known
|
||||
to asn1_print.
|
||||
|
||||
Options supported:
|
||||
|
||||
-i, --no-indent
|
||||
Do not indent dump.
|
||||
|
||||
-I, --inner
|
||||
Try to parse inner structures of OCTET STRING and constructed
|
||||
values.
|
||||
|
||||
-l, --list-types
|
||||
Try to parse inner structures of OCTET STRING and constructed
|
||||
values.
|
||||
|
||||
-v, --version
|
||||
|
||||
-h, --help
|
||||
|
||||
HEIMDAL February 22, 2021 HEIMDAL
|
||||
```
|
||||
|
||||
## Implementation
|
||||
|
||||
...
|
||||
|
94
lib/asn1/asn1_print.1
Normal file
94
lib/asn1/asn1_print.1
Normal file
@@ -0,0 +1,94 @@
|
||||
.\" Copyright (c) 2021 Kungliga Tekniska Högskolan
|
||||
.\" (Royal Institute of Technology, Stockholm, Sweden).
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd February 22, 2021
|
||||
.Dt ASN1_PRINT 1
|
||||
.Os HEIMDAL
|
||||
.Sh NAME
|
||||
.Nm asn1_print
|
||||
.Nd dump ASN.1 DER encoded values
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Bk -words
|
||||
.Oo Fl i \*(Ba Xo
|
||||
.Fl Fl no-indent
|
||||
.Xc
|
||||
.Oc
|
||||
.Oo Fl I \*(Ba Xo
|
||||
.Fl Fl inner
|
||||
.Xc
|
||||
.Oc
|
||||
.Oo Fl l \*(Ba Xo
|
||||
.Fl Fl list-types
|
||||
.Xc
|
||||
.Oc
|
||||
.Oo Fl l v \*(Ba Xo
|
||||
.Fl Fl version
|
||||
.Xc
|
||||
.Oc
|
||||
.Oo Fl l h \*(Ba Xo
|
||||
.Fl Fl help
|
||||
.Xc
|
||||
.Oc
|
||||
.Op Ar FILE Op Ar TypeName
|
||||
.Ek
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
Dumps ASN.1 DER-encoded values.
|
||||
If a
|
||||
.Ar TypeName
|
||||
is given, then
|
||||
.Nm
|
||||
will print the value in a JSON-like format using its knowledge of
|
||||
the ASN.1 module defining that type.
|
||||
If a
|
||||
.Ar TypeName
|
||||
is given, it must be the name of an ASN.1 type exported by an
|
||||
ASN.1 module that is compiled into
|
||||
.Nm .
|
||||
Use the
|
||||
.Fl Fl list-types
|
||||
option to list ASN.1 types known to
|
||||
.Nm .
|
||||
.Pp
|
||||
Options supported:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl i, Fl Fl no-indent
|
||||
Do not indent dump.
|
||||
.It Fl I, Fl Fl inner
|
||||
Try to parse inner structures of OCTET STRING and constructed values.
|
||||
.It Fl l, Fl Fl list-types
|
||||
Try to parse inner structures of OCTET STRING and constructed values.
|
||||
.It Fl v, Fl Fl version
|
||||
.It Fl h, Fl Fl help
|
||||
.El
|
@@ -37,9 +37,23 @@
|
||||
#include <com_err.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dlfcn.h>
|
||||
#include <getarg.h>
|
||||
#include <err.h>
|
||||
#include <der.h>
|
||||
#include "cms_asn1.h"
|
||||
#include "digest_asn1.h"
|
||||
#include "krb5_asn1.h"
|
||||
#include "kx509_asn1.h"
|
||||
#include "ocsp_asn1.h"
|
||||
#include "pkcs10_asn1.h"
|
||||
#include "pkcs12_asn1.h"
|
||||
#include "pkcs8_asn1.h"
|
||||
#include "pkcs9_asn1.h"
|
||||
#include "pkinit_asn1.h"
|
||||
#include "rfc2459_asn1.h"
|
||||
#include "rfc4108_asn1.h"
|
||||
#include "x690sample_asn1.h"
|
||||
|
||||
static int indent_flag = 1;
|
||||
static int inner_flag = 0;
|
||||
@@ -47,6 +61,41 @@ static int inner_flag = 0;
|
||||
static unsigned long indefinite_form_loop;
|
||||
static unsigned long indefinite_form_loop_max = 10000;
|
||||
|
||||
typedef int (*decoder)(const unsigned char *, size_t, void *, size_t *);
|
||||
typedef char *(*printer)(const void *, int);
|
||||
typedef void (*releaser)(void *);
|
||||
struct types {
|
||||
const char *name;
|
||||
decoder decode;
|
||||
printer print;
|
||||
releaser release;
|
||||
size_t sz;
|
||||
} types[] = {
|
||||
#define ASN1_SYM_INTVAL(n, gn, gns, i)
|
||||
#define ASN1_SYM_OID(n, gn, gns)
|
||||
#define ASN1_SYM_TYPE(n, gn, gns) \
|
||||
{ \
|
||||
n, \
|
||||
(decoder)decode_ ## gns, \
|
||||
(printer)print_ ## gns, \
|
||||
(releaser)free_ ## gns, \
|
||||
sizeof(gns) \
|
||||
},
|
||||
#include "cms_asn1_syms.x"
|
||||
#include "digest_asn1_syms.x"
|
||||
#include "krb5_asn1_syms.x"
|
||||
#include "kx509_asn1_syms.x"
|
||||
#include "ocsp_asn1_syms.x"
|
||||
#include "pkcs10_asn1_syms.x"
|
||||
#include "pkcs12_asn1_syms.x"
|
||||
#include "pkcs8_asn1_syms.x"
|
||||
#include "pkcs9_asn1_syms.x"
|
||||
#include "pkinit_asn1_syms.x"
|
||||
#include "rfc2459_asn1_syms.x"
|
||||
#include "rfc4108_asn1_syms.x"
|
||||
#include "x690sample_asn1_syms.x"
|
||||
};
|
||||
|
||||
static size_t
|
||||
loop (unsigned char *buf, size_t len, int indent)
|
||||
{
|
||||
@@ -289,44 +338,161 @@ loop (unsigned char *buf, size_t len, int indent)
|
||||
}
|
||||
|
||||
static int
|
||||
doit (const char *filename)
|
||||
type_cmp(const void *va, const void *vb)
|
||||
{
|
||||
int fd = open (filename, O_RDONLY);
|
||||
const struct types *ta = (const struct types *)va;
|
||||
const struct types *tb = (const struct types *)vb;
|
||||
|
||||
return strcmp(ta->name, tb->name);
|
||||
}
|
||||
|
||||
static int
|
||||
doit(const char *filename, const char *typename)
|
||||
{
|
||||
int fd = open(filename, O_RDONLY);
|
||||
struct stat sb;
|
||||
unsigned char *buf;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
if(fd < 0)
|
||||
err (1, "opening %s for read", filename);
|
||||
err(1, "opening %s for read", filename);
|
||||
if (fstat (fd, &sb) < 0)
|
||||
err (1, "stat %s", filename);
|
||||
err(1, "stat %s", filename);
|
||||
len = sb.st_size;
|
||||
buf = emalloc (len);
|
||||
if (read (fd, buf, len) != len)
|
||||
errx (1, "read failed");
|
||||
close (fd);
|
||||
ret = loop (buf, len, 0);
|
||||
free (buf);
|
||||
buf = emalloc(len);
|
||||
if (read(fd, buf, len) != len)
|
||||
errx(1, "read failed");
|
||||
close(fd);
|
||||
if (typename) {
|
||||
struct types *sorted_types = emalloc(sizeof(types));
|
||||
size_t right = sizeof(types)/sizeof(types[0]) - 1;
|
||||
size_t left = 0;
|
||||
size_t mid;
|
||||
size_t sz;
|
||||
char *s;
|
||||
void *v;
|
||||
int c = -1;
|
||||
|
||||
memcpy(sorted_types, types, sizeof(types));
|
||||
qsort(sorted_types,
|
||||
sizeof(types)/sizeof(types[0]),
|
||||
sizeof(types[0]),
|
||||
type_cmp);
|
||||
|
||||
while (left <= right) {
|
||||
mid = (left + right) >> 1;
|
||||
c = strcmp(sorted_types[mid].name, typename);
|
||||
if (c < 0)
|
||||
left = mid + 1;
|
||||
else if (c > 0)
|
||||
right = mid - 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (c != 0)
|
||||
errx(1, "Type %s not found", typename);
|
||||
v = ecalloc(1, sorted_types[mid].sz);
|
||||
ret = sorted_types[mid].decode(buf, len, v, &sz);
|
||||
if (ret == 0) {
|
||||
s = sorted_types[mid].print(v,
|
||||
indent_flag ? ASN1_PRINT_INDENT : 0);
|
||||
sorted_types[mid].release(v);
|
||||
if (!s)
|
||||
ret = errno;
|
||||
}
|
||||
if (ret == 0) {
|
||||
fprintf(stdout, "%s\n", s);
|
||||
free(buf);
|
||||
free(s);
|
||||
exit(0);
|
||||
}
|
||||
switch (ret) {
|
||||
case ASN1_BAD_TIMEFORMAT:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"Bad time format", typename);
|
||||
case ASN1_MISSING_FIELD:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"Missing required field", typename);
|
||||
case ASN1_MISPLACED_FIELD:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"Fields out of order", typename);
|
||||
case ASN1_TYPE_MISMATCH:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"Type mismatch", typename);
|
||||
case ASN1_OVERFLOW:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"DER value too large", typename);
|
||||
case ASN1_OVERRUN:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"DER value too short", typename);
|
||||
case ASN1_BAD_ID:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"DER tag is unexpected", typename);
|
||||
case ASN1_BAD_LENGTH:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"DER length does not match value", typename);
|
||||
case ASN1_BAD_FORMAT:
|
||||
case ASN1_PARSE_ERROR:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"DER badly formatted", typename);
|
||||
case ASN1_EXTRA_DATA:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"Extra data past end of end structure", typename);
|
||||
case ASN1_BAD_CHARACTER:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"Invalid character encoding in string", typename);
|
||||
case ASN1_MIN_CONSTRAINT:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"Too few elements", typename);
|
||||
case ASN1_MAX_CONSTRAINT:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"Too many elements", typename);
|
||||
case ASN1_EXACT_CONSTRAINT:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"Wrong count of elements", typename);
|
||||
case ASN1_INDEF_OVERRUN:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"BER indefinte encoding overun", typename);
|
||||
case ASN1_INDEF_UNDERRUN:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"BER indefinte encoding underun", typename);
|
||||
case ASN1_GOT_BER:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"BER encoding when DER expected", typename);
|
||||
case ASN1_INDEF_EXTRA_DATA:
|
||||
errx(1, "Could not decode and print data as type %s: "
|
||||
"End-of-contents tag contains data", typename);
|
||||
default:
|
||||
err(1, "Could not decode and print data as type %s", typename);
|
||||
}
|
||||
|
||||
}
|
||||
ret = loop(buf, len, 0);
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int list_types_flag = 0;
|
||||
static int version_flag;
|
||||
static int help_flag;
|
||||
struct getargs args[] = {
|
||||
{ "indent", 0, arg_negative_flag, &indent_flag, NULL, NULL },
|
||||
{ "inner", 0, arg_flag, &inner_flag,
|
||||
"try to parse inner structures of OCTET STRING", NULL },
|
||||
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
|
||||
{ "help", 0, arg_flag, &help_flag, NULL, NULL }
|
||||
{ "indent", 'i', arg_negative_flag, &indent_flag,
|
||||
"\tdo not indent dump", NULL },
|
||||
{ "inner", 'I', arg_flag, &inner_flag,
|
||||
"\ttry to parse inner structures of OCTET STRING", NULL },
|
||||
{ "list-types", 'l', arg_flag, &list_types_flag,
|
||||
"\tlist ASN.1 types known to this program", NULL },
|
||||
{ "version", 'v', arg_flag, &version_flag, NULL, NULL },
|
||||
{ "help", 'h', arg_flag, &help_flag, NULL, NULL }
|
||||
};
|
||||
int num_args = sizeof(args) / sizeof(args[0]);
|
||||
|
||||
static void
|
||||
usage(int code)
|
||||
{
|
||||
arg_printusage(args, num_args, NULL, "dump-file");
|
||||
arg_printusage(args, num_args, NULL, "dump-file [TypeName]");
|
||||
exit(code);
|
||||
}
|
||||
|
||||
@@ -335,19 +501,29 @@ main(int argc, char **argv)
|
||||
{
|
||||
int optidx = 0;
|
||||
|
||||
setprogname (argv[0]);
|
||||
initialize_asn1_error_table ();
|
||||
if(getarg(args, num_args, argc, argv, &optidx))
|
||||
setprogname(argv[0]);
|
||||
initialize_asn1_error_table();
|
||||
if (getarg(args, num_args, argc, argv, &optidx))
|
||||
usage(1);
|
||||
if(help_flag)
|
||||
if (help_flag)
|
||||
usage(0);
|
||||
if(version_flag) {
|
||||
if (version_flag) {
|
||||
print_version(NULL);
|
||||
exit(0);
|
||||
}
|
||||
argv += optidx;
|
||||
argc -= optidx;
|
||||
if (argc != 1)
|
||||
usage (1);
|
||||
return doit (argv[0]);
|
||||
if (list_types_flag) {
|
||||
size_t i;
|
||||
|
||||
if (argc)
|
||||
usage(1);
|
||||
|
||||
for (i = 0; i < sizeof(types)/sizeof(types[0]); i++)
|
||||
printf("%s\n", types[i].name);
|
||||
exit(0);
|
||||
}
|
||||
if (argc != 1 && argc != 2)
|
||||
usage(1);
|
||||
return doit(argv[0], argv[1]);
|
||||
}
|
||||
|
@@ -41,6 +41,7 @@ extern int prefix_enum;
|
||||
RCSID("$Id$");
|
||||
|
||||
FILE *privheaderfile, *headerfile, *oidsfile, *codefile, *logfile, *templatefile;
|
||||
FILE *symsfile;
|
||||
|
||||
#define STEM "asn1"
|
||||
|
||||
@@ -285,6 +286,11 @@ init_generate (const char *filename, const char *base)
|
||||
oidsfile = fopen(fn, "w");
|
||||
if (oidsfile == NULL)
|
||||
err (1, "open %s", fn);
|
||||
if (asprintf(&fn, "%s_syms.x", base) < 0 || fn == NULL)
|
||||
errx(1, "malloc");
|
||||
symsfile = fopen(fn, "w");
|
||||
if (symsfile == NULL)
|
||||
err (1, "open %s", fn);
|
||||
free(fn);
|
||||
fn = NULL;
|
||||
|
||||
@@ -462,6 +468,10 @@ generate_constant (const Symbol *s)
|
||||
"enum { %s = %lld };\n\n",
|
||||
s->gen_name, s->gen_name, s->gen_name,
|
||||
(long long)s->value->u.integervalue);
|
||||
if (is_export(s->name))
|
||||
fprintf(symsfile, "ASN1_SYM_INTVAL(\"%s\", \"%s\", %s, %lld)\n",
|
||||
s->name, s->gen_name, s->gen_name,
|
||||
(long long)s->value->u.integervalue);
|
||||
break;
|
||||
case nullvalue:
|
||||
break;
|
||||
@@ -508,6 +518,9 @@ generate_constant (const Symbol *s)
|
||||
s->gen_name, (unsigned long)len, s->gen_name);
|
||||
|
||||
fprintf(oidsfile, "DEFINE_OID_WITH_NAME(%s)\n", s->gen_name);
|
||||
if (is_export(s->name))
|
||||
fprintf(symsfile, "ASN1_SYM_OID(\"%s\", \"%s\", %s)\n",
|
||||
s->name, s->gen_name, s->gen_name);
|
||||
|
||||
free(list);
|
||||
|
||||
@@ -1606,6 +1619,9 @@ generate_type_header (const Symbol *s)
|
||||
if (s->emitted_definition)
|
||||
return;
|
||||
|
||||
if (is_export(s->name))
|
||||
fprintf(symsfile, "ASN1_SYM_TYPE(\"%s\", \"%s\", %s)\n",
|
||||
s->name, s->gen_name, s->gen_name);
|
||||
fprintf(headerfile, "typedef ");
|
||||
define_type(0, s->gen_name, s->gen_name, NULL, s->type, TRUE,
|
||||
preserve_type(s->name) ? TRUE : FALSE);
|
||||
@@ -1632,7 +1648,7 @@ generate_type (const Symbol *s)
|
||||
if (!one_code_file)
|
||||
generate_header_of_codefile(s->gen_name);
|
||||
|
||||
generate_type_header (s);
|
||||
generate_type_header(s);
|
||||
|
||||
if (template_flag)
|
||||
generate_template(s);
|
||||
@@ -1691,5 +1707,5 @@ generate_type (const Symbol *s)
|
||||
if (!one_code_file) {
|
||||
fprintf(codefile, "\n\n");
|
||||
close_codefile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user