]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added support for name constraints X.509 extension.
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Thu, 13 Feb 2014 13:47:14 +0000 (14:47 +0100)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 17 Feb 2014 12:45:28 +0000 (13:45 +0100)
This allows to generate and read the name constraints extension,
as well as check against the DNSNAME value.

lib/includes/gnutls/x509.h
lib/libgnutls.map
lib/pkix.asn
lib/pkix_asn1_tab.c
lib/x509/Makefile.am
lib/x509/extensions.c
lib/x509/name_constraints.c [new file with mode: 0644]
lib/x509/output.c
lib/x509/x509.c
lib/x509/x509_int.h
tests/Makefile.am

index f67200805cd9e7a02f860e0b15cd8e55a71ef6fe..514d69f540ff3454344703ab619cfcc8cfa69eec 100644 (file)
@@ -233,6 +233,33 @@ int gnutls_x509_crt_get_authority_info_access(gnutls_x509_crt_t
                                              data, unsigned int
                                              *critical);
 
+typedef struct gnutls_name_constraints_st *gnutls_x509_name_constraints_t;
+
+unsigned gnutls_x509_name_constraints_check(gnutls_x509_name_constraints_t nc,
+                                      gnutls_x509_subject_alt_name_t type,
+                                      const gnutls_datum_t * name);
+
+int gnutls_x509_name_constraints_init(gnutls_x509_name_constraints_t *nc);
+void gnutls_x509_name_constraints_deinit(gnutls_x509_name_constraints_t nc);
+int gnutls_x509_crt_get_name_constraints(gnutls_x509_crt_t crt,
+                                        gnutls_x509_name_constraints_t nc,
+                                        unsigned int *critical);
+int gnutls_x509_name_constraints_add_permitted(gnutls_x509_name_constraints_t nc,
+                                              gnutls_x509_subject_alt_name_t type,
+                                              const gnutls_datum_t * name);
+int gnutls_x509_name_constraints_add_excluded(gnutls_x509_name_constraints_t nc,
+                                             gnutls_x509_subject_alt_name_t type,
+                                             const gnutls_datum_t * name);
+int gnutls_x509_crt_set_name_constraints(gnutls_x509_crt_t crt, 
+                                        gnutls_x509_name_constraints_t nc);
+int gnutls_x509_name_constraints_get_permitted(gnutls_x509_name_constraints_t nc,
+                                    unsigned idx,
+                                    unsigned *type, gnutls_datum_t * name);
+int gnutls_x509_name_constraints_get_excluded(gnutls_x509_name_constraints_t nc,
+                                    unsigned idx,
+                                    unsigned *type, gnutls_datum_t * name);
+
+
 #define GNUTLS_CRL_REASON_SUPERSEEDED GNUTLS_CRL_REASON_SUPERSEDED,
   /**
    * gnutls_x509_crl_reason_flags_t:
index dc87f5cf889418eb1c542973ad140beb017caef4..b4cdd3c6ce977429ad7e45b233f7ec2fa90b0224 100644 (file)
@@ -943,6 +943,15 @@ GNUTLS_3_1_0 {
        gnutls_privkey_verify_params;
        gnutls_pubkey_verify_params;
        gnutls_db_get_default_cache_expiration;
+       gnutls_x509_name_constraints_init;
+       gnutls_x509_name_constraints_deinit;
+       gnutls_x509_crt_get_name_constraints;
+       gnutls_x509_name_constraints_add_permitted;
+       gnutls_x509_name_constraints_add_excluded;
+       gnutls_x509_crt_set_name_constraints;
+       gnutls_x509_name_constraints_get_permitted;
+       gnutls_x509_name_constraints_get_excluded;
+       gnutls_x509_name_constraints_check;
 } GNUTLS_3_0_0;
 
 GNUTLS_PRIVATE {
index c468dcea05c26e7f22371b29be2dac65ec4a7fd9..aa0c57492a46261d4aa2fab7ec4716010548becf 100644 (file)
@@ -655,4 +655,15 @@ CRLReason ::= ENUMERATED {
      privilegeWithdrawn      (9),
      aACompromise           (10) }
 
+NameConstraints ::= SEQUENCE {
+     permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
+     excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
+
+GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+
+GeneralSubtree ::= SEQUENCE {
+     base                    GeneralName,
+     minimum         [0]     INTEGER DEFAULT 0,
+     maximum         [1]     INTEGER OPTIONAL }
+
 END
index ec4943db8dd097279d41ca165079e302569d97c8..60dba1876c32d248bb865eba4e92dd8b3789615d 100644 (file)
 #if HAVE_CONFIG_H
-#include "config.h"
+# include "config.h"
 #endif
 
 #include <libtasn1.h>
 
 const asn1_static_node pkix_asn1_tab[] = {
-       {"PKIX1", 536875024, NULL},
-       {NULL, 1073741836, NULL},
-       {"id-pkix", 1879048204, NULL},
-       {"iso", 1073741825, "1"},
-       {"identified-organization", 1073741825, "3"},
-       {"dod", 1073741825, "6"},
-       {"internet", 1073741825, "1"},
-       {"security", 1073741825, "5"},
-       {"mechanisms", 1073741825, "5"},
-       {"pkix", 1, "7"},
-       {"PrivateKeyUsagePeriod", 1610612741, NULL},
-       {"notBefore", 1610637349, NULL},
-       {NULL, 4104, "0"},
-       {"notAfter", 536895525, NULL},
-       {NULL, 4104, "1"},
-       {"AuthorityKeyIdentifier", 1610612741, NULL},
-       {"keyIdentifier", 1610637314, "KeyIdentifier"},
-       {NULL, 4104, "0"},
-       {"authorityCertIssuer", 1610637314, "GeneralNames"},
-       {NULL, 4104, "1"},
-       {"authorityCertSerialNumber", 536895490,
-        "CertificateSerialNumber"},
-       {NULL, 4104, "2"},
-       {"KeyIdentifier", 1073741831, NULL},
-       {"SubjectKeyIdentifier", 1073741826, "KeyIdentifier"},
-       {"KeyUsage", 1073741830, NULL},
-       {"DirectoryString", 1610612754, NULL},
-       {"teletexString", 1612709918, NULL},
-       {"MAX", 524298, "1"},
-       {"printableString", 1612709919, NULL},
-       {"MAX", 524298, "1"},
-       {"universalString", 1612709920, NULL},
-       {"MAX", 524298, "1"},
-       {"utf8String", 1612709922, NULL},
-       {"MAX", 524298, "1"},
-       {"bmpString", 1612709921, NULL},
-       {"MAX", 524298, "1"},
-       {"ia5String", 538968093, NULL},
-       {"MAX", 524298, "1"},
-       {"SubjectAltName", 1073741826, "GeneralNames"},
-       {"GeneralNames", 1612709899, NULL},
-       {"MAX", 1074266122, "1"},
-       {NULL, 2, "GeneralName"},
-       {"GeneralName", 1610612754, NULL},
-       {"otherName", 1610620930, "AnotherName"},
-       {NULL, 4104, "0"},
-       {"rfc822Name", 1610620957, NULL},
-       {NULL, 4104, "1"},
-       {"dNSName", 1610620957, NULL},
-       {NULL, 4104, "2"},
-       {"x400Address", 1610620941, NULL},
-       {NULL, 4104, "3"},
-       {"directoryName", 1610620930, "RDNSequence"},
-       {NULL, 2056, "4"},
-       {"ediPartyName", 1610620941, NULL},
-       {NULL, 4104, "5"},
-       {"uniformResourceIdentifier", 1610620957, NULL},
-       {NULL, 4104, "6"},
-       {"iPAddress", 1610620935, NULL},
-       {NULL, 4104, "7"},
-       {"registeredID", 536879116, NULL},
-       {NULL, 4104, "8"},
-       {"AnotherName", 1610612741, NULL},
-       {"type-id", 1073741836, NULL},
-       {"value", 541073421, NULL},
-       {NULL, 1073743880, "0"},
-       {"type-id", 1, NULL},
-       {"IssuerAltName", 1073741826, "GeneralNames"},
-       {"BasicConstraints", 1610612741, NULL},
-       {"cA", 1610645508, NULL},
-       {NULL, 131081, NULL},
-       {"pathLenConstraint", 537411587, NULL},
-       {"0", 10, "MAX"},
-       {"CRLDistributionPoints", 1612709899, NULL},
-       {"MAX", 1074266122, "1"},
-       {NULL, 2, "DistributionPoint"},
-       {"DistributionPoint", 1610612741, NULL},
-       {"distributionPoint", 1610637314, "DistributionPointName"},
-       {NULL, 2056, "0"},
-       {"reasons", 1610637314, "ReasonFlags"},
-       {NULL, 4104, "1"},
-       {"cRLIssuer", 536895490, "GeneralNames"},
-       {NULL, 4104, "2"},
-       {"DistributionPointName", 1610612754, NULL},
-       {"fullName", 1610620930, "GeneralNames"},
-       {NULL, 4104, "0"},
-       {"nameRelativeToCRLIssuer", 536879106,
-        "RelativeDistinguishedName"},
-       {NULL, 4104, "1"},
-       {"ReasonFlags", 1073741830, NULL},
-       {"ExtKeyUsageSyntax", 1612709899, NULL},
-       {"MAX", 1074266122, "1"},
-       {NULL, 2, "KeyPurposeId"},
-       {"KeyPurposeId", 1073741836, NULL},
-       {"AuthorityInfoAccessSyntax", 1612709899, NULL},
-       {"MAX", 1074266122, "1"},
-       {NULL, 2, "AccessDescription"},
-       {"AccessDescription", 1610612741, NULL},
-       {"accessMethod", 1073741836, NULL},
-       {"accessLocation", 2, "GeneralName"},
-       {"Attribute", 1610612741, NULL},
-       {"type", 1073741826, "AttributeType"},
-       {"values", 536870927, NULL},
-       {NULL, 2, "AttributeValue"},
-       {"AttributeType", 1073741836, NULL},
-       {"AttributeValue", 1614807053, NULL},
-       {"type", 1, NULL},
-       {"AttributeTypeAndValue", 1610612741, NULL},
-       {"type", 1073741826, "AttributeType"},
-       {"value", 2, "AttributeValue"},
-       {"id-at", 1879048204, NULL},
-       {"joint-iso-ccitt", 1073741825, "2"},
-       {"ds", 1073741825, "5"},
-       {NULL, 1, "4"},
-       {"emailAddress", 1880096780, "AttributeType"},
-       {"iso", 1073741825, "1"},
-       {"member-body", 1073741825, "2"},
-       {"us", 1073741825, "840"},
-       {"rsadsi", 1073741825, "113549"},
-       {"pkcs", 1073741825, "1"},
-       {NULL, 1073741825, "9"},
-       {NULL, 1, "1"},
-       {"Name", 1610612754, NULL},
-       {"rdnSequence", 2, "RDNSequence"},
-       {"RDNSequence", 1610612747, NULL},
-       {NULL, 2, "RelativeDistinguishedName"},
-       {"DistinguishedName", 1073741826, "RDNSequence"},
-       {"RelativeDistinguishedName", 1612709903, NULL},
-       {"MAX", 1074266122, "1"},
-       {NULL, 2, "AttributeTypeAndValue"},
-       {"Certificate", 1610612741, NULL},
-       {"tbsCertificate", 1073741826, "TBSCertificate"},
-       {"signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
-       {"signature", 6, NULL},
-       {"TBSCertificate", 1610612741, NULL},
-       {"version", 1610653699, NULL},
-       {NULL, 1073741833, "0"},
-       {NULL, 2056, "0"},
-       {"serialNumber", 1073741826, "CertificateSerialNumber"},
-       {"signature", 1073741826, "AlgorithmIdentifier"},
-       {"issuer", 1073741826, "Name"},
-       {"validity", 1073741826, "Validity"},
-       {"subject", 1073741826, "Name"},
-       {"subjectPublicKeyInfo", 1073741826, "SubjectPublicKeyInfo"},
-       {"issuerUniqueID", 1610637314, "UniqueIdentifier"},
-       {NULL, 4104, "1"},
-       {"subjectUniqueID", 1610637314, "UniqueIdentifier"},
-       {NULL, 4104, "2"},
-       {"extensions", 536895490, "Extensions"},
-       {NULL, 2056, "3"},
-       {"CertificateSerialNumber", 1073741827, NULL},
-       {"Validity", 1610612741, NULL},
-       {"notBefore", 1073741826, "Time"},
-       {"notAfter", 2, "Time"},
-       {"Time", 1610612754, NULL},
-       {"utcTime", 1073741860, NULL},
-       {"generalTime", 37, NULL},
-       {"UniqueIdentifier", 1073741830, NULL},
-       {"SubjectPublicKeyInfo", 1610612741, NULL},
-       {"algorithm", 1073741826, "AlgorithmIdentifier"},
-       {"subjectPublicKey", 6, NULL},
-       {"Extensions", 1612709899, NULL},
-       {"MAX", 1074266122, "1"},
-       {NULL, 2, "Extension"},
-       {"Extension", 1610612741, NULL},
-       {"extnID", 1073741836, NULL},
-       {"critical", 1610645508, NULL},
-       {NULL, 131081, NULL},
-       {"extnValue", 7, NULL},
-       {"CertificateList", 1610612741, NULL},
-       {"tbsCertList", 1073741826, "TBSCertList"},
-       {"signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
-       {"signature", 6, NULL},
-       {"TBSCertList", 1610612741, NULL},
-       {"version", 1073758211, NULL},
-       {"signature", 1073741826, "AlgorithmIdentifier"},
-       {"issuer", 1073741826, "Name"},
-       {"thisUpdate", 1073741826, "Time"},
-       {"nextUpdate", 1073758210, "Time"},
-       {"revokedCertificates", 1610629131, NULL},
-       {NULL, 536870917, NULL},
-       {"userCertificate", 1073741826, "CertificateSerialNumber"},
-       {"revocationDate", 1073741826, "Time"},
-       {"crlEntryExtensions", 16386, "Extensions"},
-       {"crlExtensions", 536895490, "Extensions"},
-       {NULL, 2056, "0"},
-       {"AlgorithmIdentifier", 1610612741, NULL},
-       {"algorithm", 1073741836, NULL},
-       {"parameters", 541081613, NULL},
-       {"algorithm", 1, NULL},
-       {"Dss-Sig-Value", 1610612741, NULL},
-       {"r", 1073741827, NULL},
-       {"s", 3, NULL},
-       {"DomainParameters", 1610612741, NULL},
-       {"p", 1073741827, NULL},
-       {"g", 1073741827, NULL},
-       {"q", 1073741827, NULL},
-       {"j", 1073758211, NULL},
-       {"validationParms", 16386, "ValidationParms"},
-       {"ValidationParms", 1610612741, NULL},
-       {"seed", 1073741830, NULL},
-       {"pgenCounter", 3, NULL},
-       {"Dss-Parms", 1610612741, NULL},
-       {"p", 1073741827, NULL},
-       {"q", 1073741827, NULL},
-       {"g", 3, NULL},
-       {"CountryName", 1610620946, NULL},
-       {NULL, 1073746952, "1"},
-       {"x121-dcc-code", 1612709916, NULL},
-       {NULL, 1048586, "ub-country-name-numeric-length"},
-       {"iso-3166-alpha2-code", 538968095, NULL},
-       {NULL, 1048586, "ub-country-name-alpha-length"},
-       {"OrganizationName", 1612709919, NULL},
-       {"ub-organization-name-length", 524298, "1"},
-       {"NumericUserIdentifier", 1612709916, NULL},
-       {"ub-numeric-user-id-length", 524298, "1"},
-       {"OrganizationalUnitNames", 1612709899, NULL},
-       {"ub-organizational-units", 1074266122, "1"},
-       {NULL, 2, "OrganizationalUnitName"},
-       {"OrganizationalUnitName", 1612709919, NULL},
-       {"ub-organizational-unit-name-length", 524298, "1"},
-       {"CommonName", 1073741855, NULL},
-       {"pkcs-7-ContentInfo", 1610612741, NULL},
-       {"contentType", 1073741826, "pkcs-7-ContentType"},
-       {"content", 541073421, NULL},
-       {NULL, 1073743880, "0"},
-       {"contentType", 1, NULL},
-       {"pkcs-7-DigestInfo", 1610612741, NULL},
-       {"digestAlgorithm", 1073741826, "AlgorithmIdentifier"},
-       {"digest", 7, NULL},
-       {"pkcs-7-ContentType", 1073741836, NULL},
-       {"pkcs-7-SignedData", 1610612741, NULL},
-       {"version", 1073741827, NULL},
-       {"digestAlgorithms", 1073741826,
-        "pkcs-7-DigestAlgorithmIdentifiers"},
-       {"encapContentInfo", 1073741826, "pkcs-7-EncapsulatedContentInfo"},
-       {"certificates", 1610637314, "pkcs-7-CertificateSet"},
-       {NULL, 4104, "0"},
-       {"crls", 1610637314, "pkcs-7-CertificateRevocationLists"},
-       {NULL, 4104, "1"},
-       {"signerInfos", 2, "pkcs-7-SignerInfos"},
-       {"pkcs-7-DigestAlgorithmIdentifiers", 1610612751, NULL},
-       {NULL, 2, "AlgorithmIdentifier"},
-       {"pkcs-7-EncapsulatedContentInfo", 1610612741, NULL},
-       {"eContentType", 1073741826, "pkcs-7-ContentType"},
-       {"eContent", 536895495, NULL},
-       {NULL, 2056, "0"},
-       {"pkcs-7-CertificateRevocationLists", 1610612751, NULL},
-       {NULL, 13, NULL},
-       {"pkcs-7-CertificateChoices", 1610612754, NULL},
-       {"certificate", 13, NULL},
-       {"pkcs-7-CertificateSet", 1610612751, NULL},
-       {NULL, 2, "pkcs-7-CertificateChoices"},
-       {"pkcs-7-SignerInfos", 1610612751, NULL},
-       {NULL, 13, NULL},
-       {"pkcs-10-CertificationRequestInfo", 1610612741, NULL},
-       {"version", 1073741827, NULL},
-       {"subject", 1073741826, "Name"},
-       {"subjectPKInfo", 1073741826, "SubjectPublicKeyInfo"},
-       {"attributes", 536879106, "Attributes"},
-       {NULL, 4104, "0"},
-       {"Attributes", 1610612751, NULL},
-       {NULL, 2, "Attribute"},
-       {"pkcs-10-CertificationRequest", 1610612741, NULL},
-       {"certificationRequestInfo", 1073741826,
-        "pkcs-10-CertificationRequestInfo"},
-       {"signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
-       {"signature", 6, NULL},
-       {"pkcs-9-at-challengePassword", 1879048204, NULL},
-       {"iso", 1073741825, "1"},
-       {"member-body", 1073741825, "2"},
-       {"us", 1073741825, "840"},
-       {"rsadsi", 1073741825, "113549"},
-       {"pkcs", 1073741825, "1"},
-       {NULL, 1073741825, "9"},
-       {NULL, 1, "7"},
-       {"pkcs-9-challengePassword", 1610612754, NULL},
-       {"printableString", 1073741855, NULL},
-       {"utf8String", 34, NULL},
-       {"pkcs-9-localKeyId", 1073741831, NULL},
-       {"pkcs-8-PrivateKeyInfo", 1610612741, NULL},
-       {"version", 1073741827, NULL},
-       {"privateKeyAlgorithm", 1073741826, "AlgorithmIdentifier"},
-       {"privateKey", 1073741831, NULL},
-       {"attributes", 536895490, "Attributes"},
-       {NULL, 4104, "0"},
-       {"pkcs-8-Attributes", 1610612751, NULL},
-       {NULL, 2, "Attribute"},
-       {"pkcs-8-EncryptedPrivateKeyInfo", 1610612741, NULL},
-       {"encryptionAlgorithm", 1073741826, "AlgorithmIdentifier"},
-       {"encryptedData", 2, "pkcs-8-EncryptedData"},
-       {"pkcs-8-EncryptedData", 1073741831, NULL},
-       {"pkcs-5-des-EDE3-CBC-params", 1612709895, NULL},
-       {NULL, 1048586, "8"},
-       {"pkcs-5-aes128-CBC-params", 1612709895, NULL},
-       {NULL, 1048586, "16"},
-       {"pkcs-5-aes192-CBC-params", 1612709895, NULL},
-       {NULL, 1048586, "16"},
-       {"pkcs-5-aes256-CBC-params", 1612709895, NULL},
-       {NULL, 1048586, "16"},
-       {"pkcs-5-PBES2-params", 1610612741, NULL},
-       {"keyDerivationFunc", 1073741826, "AlgorithmIdentifier"},
-       {"encryptionScheme", 2, "AlgorithmIdentifier"},
-       {"pkcs-5-PBKDF2-params", 1610612741, NULL},
-       {"salt", 1610612754, NULL},
-       {"specified", 1073741831, NULL},
-       {"otherSource", 2, "AlgorithmIdentifier"},
-       {"iterationCount", 1611137027, NULL},
-       {"1", 10, "MAX"},
-       {"keyLength", 1611153411, NULL},
-       {"1", 10, "MAX"},
-       {"prf", 16386, "AlgorithmIdentifier"},
-       {"pkcs-12-PFX", 1610612741, NULL},
-       {"version", 1610874883, NULL},
-       {"v3", 1, "3"},
-       {"authSafe", 1073741826, "pkcs-7-ContentInfo"},
-       {"macData", 16386, "pkcs-12-MacData"},
-       {"pkcs-12-PbeParams", 1610612741, NULL},
-       {"salt", 1073741831, NULL},
-       {"iterations", 3, NULL},
-       {"pkcs-12-MacData", 1610612741, NULL},
-       {"mac", 1073741826, "pkcs-7-DigestInfo"},
-       {"macSalt", 1073741831, NULL},
-       {"iterations", 536903683, NULL},
-       {NULL, 9, "1"},
-       {"pkcs-12-AuthenticatedSafe", 1610612747, NULL},
-       {NULL, 2, "pkcs-7-ContentInfo"},
-       {"pkcs-12-SafeContents", 1610612747, NULL},
-       {NULL, 2, "pkcs-12-SafeBag"},
-       {"pkcs-12-SafeBag", 1610612741, NULL},
-       {"bagId", 1073741836, NULL},
-       {"bagValue", 1614815245, NULL},
-       {NULL, 1073743880, "0"},
-       {"badId", 1, NULL},
-       {"bagAttributes", 536887311, NULL},
-       {NULL, 2, "Attribute"},
-       {"pkcs-12-CertBag", 1610612741, NULL},
-       {"certId", 1073741836, NULL},
-       {"certValue", 541073421, NULL},
-       {NULL, 1073743880, "0"},
-       {"certId", 1, NULL},
-       {"pkcs-12-CRLBag", 1610612741, NULL},
-       {"crlId", 1073741836, NULL},
-       {"crlValue", 541073421, NULL},
-       {NULL, 1073743880, "0"},
-       {"crlId", 1, NULL},
-       {"pkcs-12-SecretBag", 1610612741, NULL},
-       {"secretTypeId", 1073741836, NULL},
-       {"secretValue", 541073421, NULL},
-       {NULL, 1073743880, "0"},
-       {"secretTypeId", 1, NULL},
-       {"pkcs-7-Data", 1073741831, NULL},
-       {"pkcs-7-EncryptedData", 1610612741, NULL},
-       {"version", 1073741827, NULL},
-       {"encryptedContentInfo", 1073741826,
-        "pkcs-7-EncryptedContentInfo"},
-       {"unprotectedAttrs", 536895490, "pkcs-7-UnprotectedAttributes"},
-       {NULL, 4104, "1"},
-       {"pkcs-7-EncryptedContentInfo", 1610612741, NULL},
-       {"contentType", 1073741826, "pkcs-7-ContentType"},
-       {"contentEncryptionAlgorithm", 1073741826,
-        "pkcs-7-ContentEncryptionAlgorithmIdentifier"},
-       {"encryptedContent", 536895495, NULL},
-       {NULL, 4104, "0"},
-       {"pkcs-7-ContentEncryptionAlgorithmIdentifier", 1073741826,
-        "AlgorithmIdentifier"},
-       {"pkcs-7-UnprotectedAttributes", 1612709903, NULL},
-       {"MAX", 1074266122, "1"},
-       {NULL, 2, "Attribute"},
-       {"ProxyCertInfo", 1610612741, NULL},
-       {"pCPathLenConstraint", 1611153411, NULL},
-       {"0", 10, "MAX"},
-       {"proxyPolicy", 2, "ProxyPolicy"},
-       {"ProxyPolicy", 1610612741, NULL},
-       {"policyLanguage", 1073741836, NULL},
-       {"policy", 16391, NULL},
-       {"certificatePolicies", 1612709899, NULL},
-       {"MAX", 1074266122, "1"},
-       {NULL, 2, "PolicyInformation"},
-       {"PolicyInformation", 1610612741, NULL},
-       {"policyIdentifier", 1073741836, NULL},
-       {"policyQualifiers", 538984459, NULL},
-       {"MAX", 1074266122, "1"},
-       {NULL, 2, "PolicyQualifierInfo"},
-       {"PolicyQualifierInfo", 1610612741, NULL},
-       {"policyQualifierId", 1073741836, NULL},
-       {"qualifier", 541065229, NULL},
-       {"policyQualifierId", 1, NULL},
-       {"CPSuri", 1073741853, NULL},
-       {"UserNotice", 1610612741, NULL},
-       {"noticeRef", 1073758210, "NoticeReference"},
-       {"explicitText", 16386, "DisplayText"},
-       {"NoticeReference", 1610612741, NULL},
-       {"organization", 1073741826, "DisplayText"},
-       {"noticeNumbers", 536870923, NULL},
-       {NULL, 3, NULL},
-       {"DisplayText", 1610612754, NULL},
-       {"ia5String", 1612709917, NULL},
-       {"200", 524298, "1"},
-       {"visibleString", 1612709923, NULL},
-       {"200", 524298, "1"},
-       {"bmpString", 1612709921, NULL},
-       {"200", 524298, "1"},
-       {"utf8String", 538968098, NULL},
-       {"200", 524298, "1"},
-       {"OCSPRequest", 1610612741, NULL},
-       {"tbsRequest", 1073741826, "TBSRequest"},
-       {"optionalSignature", 536895490, "Signature"},
-       {NULL, 2056, "0"},
-       {"TBSRequest", 1610612741, NULL},
-       {"version", 1610653699, NULL},
-       {NULL, 1073741833, "0"},
-       {NULL, 2056, "0"},
-       {"requestorName", 1610637314, "GeneralName"},
-       {NULL, 2056, "1"},
-       {"requestList", 1610612747, NULL},
-       {NULL, 2, "Request"},
-       {"requestExtensions", 536895490, "Extensions"},
-       {NULL, 2056, "2"},
-       {"Signature", 1610612741, NULL},
-       {"signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
-       {"signature", 1073741830, NULL},
-       {"certs", 536895499, NULL},
-       {NULL, 1073743880, "0"},
-       {NULL, 2, "Certificate"},
-       {"Request", 1610612741, NULL},
-       {"reqCert", 1073741826, "CertID"},
-       {"singleRequestExtensions", 536895490, "Extensions"},
-       {NULL, 2056, "0"},
-       {"CertID", 1610612741, NULL},
-       {"hashAlgorithm", 1073741826, "AlgorithmIdentifier"},
-       {"issuerNameHash", 1073741831, NULL},
-       {"issuerKeyHash", 1073741831, NULL},
-       {"serialNumber", 2, "CertificateSerialNumber"},
-       {"OCSPResponse", 1610612741, NULL},
-       {"responseStatus", 1073741826, "OCSPResponseStatus"},
-       {"responseBytes", 536895490, "ResponseBytes"},
-       {NULL, 2056, "0"},
-       {"OCSPResponseStatus", 1610874901, NULL},
-       {"successful", 1073741825, "0"},
-       {"malformedRequest", 1073741825, "1"},
-       {"internalError", 1073741825, "2"},
-       {"tryLater", 1073741825, "3"},
-       {"sigRequired", 1073741825, "5"},
-       {"unauthorized", 1, "6"},
-       {"ResponseBytes", 1610612741, NULL},
-       {"responseType", 1073741836, NULL},
-       {"response", 7, NULL},
-       {"BasicOCSPResponse", 1610612741, NULL},
-       {"tbsResponseData", 1073741826, "ResponseData"},
-       {"signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
-       {"signature", 1073741830, NULL},
-       {"certs", 536895499, NULL},
-       {NULL, 1073743880, "0"},
-       {NULL, 2, "Certificate"},
-       {"ResponseData", 1610612741, NULL},
-       {"version", 1610653699, NULL},
-       {NULL, 1073741833, "0"},
-       {NULL, 2056, "0"},
-       {"responderID", 1073741826, "ResponderID"},
-       {"producedAt", 1073741861, NULL},
-       {"responses", 1610612747, NULL},
-       {NULL, 2, "SingleResponse"},
-       {"responseExtensions", 536895490, "Extensions"},
-       {NULL, 2056, "1"},
-       {"ResponderID", 1610612754, NULL},
-       {"byName", 1610620930, "RDNSequence"},
-       {NULL, 2056, "1"},
-       {"byKey", 536879111, NULL},
-       {NULL, 4104, "2"},
-       {"SingleResponse", 1610612741, NULL},
-       {"certID", 1073741826, "CertID"},
-       {"certStatus", 1073741826, "CertStatus"},
-       {"thisUpdate", 1073741861, NULL},
-       {"nextUpdate", 1610637349, NULL},
-       {NULL, 2056, "0"},
-       {"singleExtensions", 536895490, "Extensions"},
-       {NULL, 2056, "1"},
-       {"CertStatus", 1610612754, NULL},
-       {"good", 1610620948, NULL},
-       {NULL, 4104, "0"},
-       {"revoked", 1610620930, "RevokedInfo"},
-       {NULL, 4104, "1"},
-       {"unknown", 536879106, "UnknownInfo"},
-       {NULL, 4104, "2"},
-       {"RevokedInfo", 1610612741, NULL},
-       {"revocationTime", 1073741861, NULL},
-       {"revocationReason", 536895490, "CRLReason"},
-       {NULL, 2056, "0"},
-       {"UnknownInfo", 1073741844, NULL},
-       {"CRLReason", 537133077, NULL},
-       {"unspecified", 1073741825, "0"},
-       {"keyCompromise", 1073741825, "1"},
-       {"cACompromise", 1073741825, "2"},
-       {"affiliationChanged", 1073741825, "3"},
-       {"superseded", 1073741825, "4"},
-       {"cessationOfOperation", 1073741825, "5"},
-       {"certificateHold", 1073741825, "6"},
-       {"removeFromCRL", 1073741825, "8"},
-       {"privilegeWithdrawn", 1073741825, "9"},
-       {"aACompromise", 1, "10"},
-       {NULL, 0, NULL}
+  { "PKIX1", 536875024, NULL },
+  { NULL, 1073741836, NULL },
+  { "id-pkix", 1879048204, NULL },
+  { "iso", 1073741825, "1"},
+  { "identified-organization", 1073741825, "3"},
+  { "dod", 1073741825, "6"},
+  { "internet", 1073741825, "1"},
+  { "security", 1073741825, "5"},
+  { "mechanisms", 1073741825, "5"},
+  { "pkix", 1, "7"},
+  { "PrivateKeyUsagePeriod", 1610612741, NULL },
+  { "notBefore", 1610637349, NULL },
+  { NULL, 4104, "0"},
+  { "notAfter", 536895525, NULL },
+  { NULL, 4104, "1"},
+  { "AuthorityKeyIdentifier", 1610612741, NULL },
+  { "keyIdentifier", 1610637314, "KeyIdentifier"},
+  { NULL, 4104, "0"},
+  { "authorityCertIssuer", 1610637314, "GeneralNames"},
+  { NULL, 4104, "1"},
+  { "authorityCertSerialNumber", 536895490, "CertificateSerialNumber"},
+  { NULL, 4104, "2"},
+  { "KeyIdentifier", 1073741831, NULL },
+  { "SubjectKeyIdentifier", 1073741826, "KeyIdentifier"},
+  { "KeyUsage", 1073741830, NULL },
+  { "DirectoryString", 1610612754, NULL },
+  { "teletexString", 1612709918, NULL },
+  { "MAX", 524298, "1"},
+  { "printableString", 1612709919, NULL },
+  { "MAX", 524298, "1"},
+  { "universalString", 1612709920, NULL },
+  { "MAX", 524298, "1"},
+  { "utf8String", 1612709922, NULL },
+  { "MAX", 524298, "1"},
+  { "bmpString", 1612709921, NULL },
+  { "MAX", 524298, "1"},
+  { "ia5String", 538968093, NULL },
+  { "MAX", 524298, "1"},
+  { "SubjectAltName", 1073741826, "GeneralNames"},
+  { "GeneralNames", 1612709899, NULL },
+  { "MAX", 1074266122, "1"},
+  { NULL, 2, "GeneralName"},
+  { "GeneralName", 1610612754, NULL },
+  { "otherName", 1610620930, "AnotherName"},
+  { NULL, 4104, "0"},
+  { "rfc822Name", 1610620957, NULL },
+  { NULL, 4104, "1"},
+  { "dNSName", 1610620957, NULL },
+  { NULL, 4104, "2"},
+  { "x400Address", 1610620941, NULL },
+  { NULL, 4104, "3"},
+  { "directoryName", 1610620930, "RDNSequence"},
+  { NULL, 2056, "4"},
+  { "ediPartyName", 1610620941, NULL },
+  { NULL, 4104, "5"},
+  { "uniformResourceIdentifier", 1610620957, NULL },
+  { NULL, 4104, "6"},
+  { "iPAddress", 1610620935, NULL },
+  { NULL, 4104, "7"},
+  { "registeredID", 536879116, NULL },
+  { NULL, 4104, "8"},
+  { "AnotherName", 1610612741, NULL },
+  { "type-id", 1073741836, NULL },
+  { "value", 541073421, NULL },
+  { NULL, 1073743880, "0"},
+  { "type-id", 1, NULL },
+  { "IssuerAltName", 1073741826, "GeneralNames"},
+  { "BasicConstraints", 1610612741, NULL },
+  { "cA", 1610645508, NULL },
+  { NULL, 131081, NULL },
+  { "pathLenConstraint", 537411587, NULL },
+  { "0", 10, "MAX"},
+  { "CRLDistributionPoints", 1612709899, NULL },
+  { "MAX", 1074266122, "1"},
+  { NULL, 2, "DistributionPoint"},
+  { "DistributionPoint", 1610612741, NULL },
+  { "distributionPoint", 1610637314, "DistributionPointName"},
+  { NULL, 2056, "0"},
+  { "reasons", 1610637314, "ReasonFlags"},
+  { NULL, 4104, "1"},
+  { "cRLIssuer", 536895490, "GeneralNames"},
+  { NULL, 4104, "2"},
+  { "DistributionPointName", 1610612754, NULL },
+  { "fullName", 1610620930, "GeneralNames"},
+  { NULL, 4104, "0"},
+  { "nameRelativeToCRLIssuer", 536879106, "RelativeDistinguishedName"},
+  { NULL, 4104, "1"},
+  { "ReasonFlags", 1073741830, NULL },
+  { "ExtKeyUsageSyntax", 1612709899, NULL },
+  { "MAX", 1074266122, "1"},
+  { NULL, 2, "KeyPurposeId"},
+  { "KeyPurposeId", 1073741836, NULL },
+  { "AuthorityInfoAccessSyntax", 1612709899, NULL },
+  { "MAX", 1074266122, "1"},
+  { NULL, 2, "AccessDescription"},
+  { "AccessDescription", 1610612741, NULL },
+  { "accessMethod", 1073741836, NULL },
+  { "accessLocation", 2, "GeneralName"},
+  { "Attribute", 1610612741, NULL },
+  { "type", 1073741826, "AttributeType"},
+  { "values", 536870927, NULL },
+  { NULL, 2, "AttributeValue"},
+  { "AttributeType", 1073741836, NULL },
+  { "AttributeValue", 1614807053, NULL },
+  { "type", 1, NULL },
+  { "AttributeTypeAndValue", 1610612741, NULL },
+  { "type", 1073741826, "AttributeType"},
+  { "value", 2, "AttributeValue"},
+  { "id-at", 1879048204, NULL },
+  { "joint-iso-ccitt", 1073741825, "2"},
+  { "ds", 1073741825, "5"},
+  { NULL, 1, "4"},
+  { "emailAddress", 1880096780, "AttributeType"},
+  { "iso", 1073741825, "1"},
+  { "member-body", 1073741825, "2"},
+  { "us", 1073741825, "840"},
+  { "rsadsi", 1073741825, "113549"},
+  { "pkcs", 1073741825, "1"},
+  { NULL, 1073741825, "9"},
+  { NULL, 1, "1"},
+  { "Name", 1610612754, NULL },
+  { "rdnSequence", 2, "RDNSequence"},
+  { "RDNSequence", 1610612747, NULL },
+  { NULL, 2, "RelativeDistinguishedName"},
+  { "DistinguishedName", 1073741826, "RDNSequence"},
+  { "RelativeDistinguishedName", 1612709903, NULL },
+  { "MAX", 1074266122, "1"},
+  { NULL, 2, "AttributeTypeAndValue"},
+  { "Certificate", 1610612741, NULL },
+  { "tbsCertificate", 1073741826, "TBSCertificate"},
+  { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+  { "signature", 6, NULL },
+  { "TBSCertificate", 1610612741, NULL },
+  { "version", 1610653699, NULL },
+  { NULL, 1073741833, "0"},
+  { NULL, 2056, "0"},
+  { "serialNumber", 1073741826, "CertificateSerialNumber"},
+  { "signature", 1073741826, "AlgorithmIdentifier"},
+  { "issuer", 1073741826, "Name"},
+  { "validity", 1073741826, "Validity"},
+  { "subject", 1073741826, "Name"},
+  { "subjectPublicKeyInfo", 1073741826, "SubjectPublicKeyInfo"},
+  { "issuerUniqueID", 1610637314, "UniqueIdentifier"},
+  { NULL, 4104, "1"},
+  { "subjectUniqueID", 1610637314, "UniqueIdentifier"},
+  { NULL, 4104, "2"},
+  { "extensions", 536895490, "Extensions"},
+  { NULL, 2056, "3"},
+  { "CertificateSerialNumber", 1073741827, NULL },
+  { "Validity", 1610612741, NULL },
+  { "notBefore", 1073741826, "Time"},
+  { "notAfter", 2, "Time"},
+  { "Time", 1610612754, NULL },
+  { "utcTime", 1073741860, NULL },
+  { "generalTime", 37, NULL },
+  { "UniqueIdentifier", 1073741830, NULL },
+  { "SubjectPublicKeyInfo", 1610612741, NULL },
+  { "algorithm", 1073741826, "AlgorithmIdentifier"},
+  { "subjectPublicKey", 6, NULL },
+  { "Extensions", 1612709899, NULL },
+  { "MAX", 1074266122, "1"},
+  { NULL, 2, "Extension"},
+  { "Extension", 1610612741, NULL },
+  { "extnID", 1073741836, NULL },
+  { "critical", 1610645508, NULL },
+  { NULL, 131081, NULL },
+  { "extnValue", 7, NULL },
+  { "CertificateList", 1610612741, NULL },
+  { "tbsCertList", 1073741826, "TBSCertList"},
+  { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+  { "signature", 6, NULL },
+  { "TBSCertList", 1610612741, NULL },
+  { "version", 1073758211, NULL },
+  { "signature", 1073741826, "AlgorithmIdentifier"},
+  { "issuer", 1073741826, "Name"},
+  { "thisUpdate", 1073741826, "Time"},
+  { "nextUpdate", 1073758210, "Time"},
+  { "revokedCertificates", 1610629131, NULL },
+  { NULL, 536870917, NULL },
+  { "userCertificate", 1073741826, "CertificateSerialNumber"},
+  { "revocationDate", 1073741826, "Time"},
+  { "crlEntryExtensions", 16386, "Extensions"},
+  { "crlExtensions", 536895490, "Extensions"},
+  { NULL, 2056, "0"},
+  { "AlgorithmIdentifier", 1610612741, NULL },
+  { "algorithm", 1073741836, NULL },
+  { "parameters", 541081613, NULL },
+  { "algorithm", 1, NULL },
+  { "Dss-Sig-Value", 1610612741, NULL },
+  { "r", 1073741827, NULL },
+  { "s", 3, NULL },
+  { "DomainParameters", 1610612741, NULL },
+  { "p", 1073741827, NULL },
+  { "g", 1073741827, NULL },
+  { "q", 1073741827, NULL },
+  { "j", 1073758211, NULL },
+  { "validationParms", 16386, "ValidationParms"},
+  { "ValidationParms", 1610612741, NULL },
+  { "seed", 1073741830, NULL },
+  { "pgenCounter", 3, NULL },
+  { "Dss-Parms", 1610612741, NULL },
+  { "p", 1073741827, NULL },
+  { "q", 1073741827, NULL },
+  { "g", 3, NULL },
+  { "CountryName", 1610620946, NULL },
+  { NULL, 1073746952, "1"},
+  { "x121-dcc-code", 1612709916, NULL },
+  { NULL, 1048586, "ub-country-name-numeric-length"},
+  { "iso-3166-alpha2-code", 538968095, NULL },
+  { NULL, 1048586, "ub-country-name-alpha-length"},
+  { "OrganizationName", 1612709919, NULL },
+  { "ub-organization-name-length", 524298, "1"},
+  { "NumericUserIdentifier", 1612709916, NULL },
+  { "ub-numeric-user-id-length", 524298, "1"},
+  { "OrganizationalUnitNames", 1612709899, NULL },
+  { "ub-organizational-units", 1074266122, "1"},
+  { NULL, 2, "OrganizationalUnitName"},
+  { "OrganizationalUnitName", 1612709919, NULL },
+  { "ub-organizational-unit-name-length", 524298, "1"},
+  { "CommonName", 1073741855, NULL },
+  { "pkcs-7-ContentInfo", 1610612741, NULL },
+  { "contentType", 1073741826, "pkcs-7-ContentType"},
+  { "content", 541073421, NULL },
+  { NULL, 1073743880, "0"},
+  { "contentType", 1, NULL },
+  { "pkcs-7-DigestInfo", 1610612741, NULL },
+  { "digestAlgorithm", 1073741826, "AlgorithmIdentifier"},
+  { "digest", 7, NULL },
+  { "pkcs-7-ContentType", 1073741836, NULL },
+  { "pkcs-7-SignedData", 1610612741, NULL },
+  { "version", 1073741827, NULL },
+  { "digestAlgorithms", 1073741826, "pkcs-7-DigestAlgorithmIdentifiers"},
+  { "encapContentInfo", 1073741826, "pkcs-7-EncapsulatedContentInfo"},
+  { "certificates", 1610637314, "pkcs-7-CertificateSet"},
+  { NULL, 4104, "0"},
+  { "crls", 1610637314, "pkcs-7-CertificateRevocationLists"},
+  { NULL, 4104, "1"},
+  { "signerInfos", 2, "pkcs-7-SignerInfos"},
+  { "pkcs-7-DigestAlgorithmIdentifiers", 1610612751, NULL },
+  { NULL, 2, "AlgorithmIdentifier"},
+  { "pkcs-7-EncapsulatedContentInfo", 1610612741, NULL },
+  { "eContentType", 1073741826, "pkcs-7-ContentType"},
+  { "eContent", 536895495, NULL },
+  { NULL, 2056, "0"},
+  { "pkcs-7-CertificateRevocationLists", 1610612751, NULL },
+  { NULL, 13, NULL },
+  { "pkcs-7-CertificateChoices", 1610612754, NULL },
+  { "certificate", 13, NULL },
+  { "pkcs-7-CertificateSet", 1610612751, NULL },
+  { NULL, 2, "pkcs-7-CertificateChoices"},
+  { "pkcs-7-SignerInfos", 1610612751, NULL },
+  { NULL, 13, NULL },
+  { "pkcs-10-CertificationRequestInfo", 1610612741, NULL },
+  { "version", 1073741827, NULL },
+  { "subject", 1073741826, "Name"},
+  { "subjectPKInfo", 1073741826, "SubjectPublicKeyInfo"},
+  { "attributes", 536879106, "Attributes"},
+  { NULL, 4104, "0"},
+  { "Attributes", 1610612751, NULL },
+  { NULL, 2, "Attribute"},
+  { "pkcs-10-CertificationRequest", 1610612741, NULL },
+  { "certificationRequestInfo", 1073741826, "pkcs-10-CertificationRequestInfo"},
+  { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+  { "signature", 6, NULL },
+  { "pkcs-9-at-challengePassword", 1879048204, NULL },
+  { "iso", 1073741825, "1"},
+  { "member-body", 1073741825, "2"},
+  { "us", 1073741825, "840"},
+  { "rsadsi", 1073741825, "113549"},
+  { "pkcs", 1073741825, "1"},
+  { NULL, 1073741825, "9"},
+  { NULL, 1, "7"},
+  { "pkcs-9-challengePassword", 1610612754, NULL },
+  { "printableString", 1073741855, NULL },
+  { "utf8String", 34, NULL },
+  { "pkcs-9-localKeyId", 1073741831, NULL },
+  { "pkcs-8-PrivateKeyInfo", 1610612741, NULL },
+  { "version", 1073741827, NULL },
+  { "privateKeyAlgorithm", 1073741826, "AlgorithmIdentifier"},
+  { "privateKey", 1073741831, NULL },
+  { "attributes", 536895490, "Attributes"},
+  { NULL, 4104, "0"},
+  { "pkcs-8-Attributes", 1610612751, NULL },
+  { NULL, 2, "Attribute"},
+  { "pkcs-8-EncryptedPrivateKeyInfo", 1610612741, NULL },
+  { "encryptionAlgorithm", 1073741826, "AlgorithmIdentifier"},
+  { "encryptedData", 2, "pkcs-8-EncryptedData"},
+  { "pkcs-8-EncryptedData", 1073741831, NULL },
+  { "pkcs-5-des-EDE3-CBC-params", 1612709895, NULL },
+  { NULL, 1048586, "8"},
+  { "pkcs-5-aes128-CBC-params", 1612709895, NULL },
+  { NULL, 1048586, "16"},
+  { "pkcs-5-aes192-CBC-params", 1612709895, NULL },
+  { NULL, 1048586, "16"},
+  { "pkcs-5-aes256-CBC-params", 1612709895, NULL },
+  { NULL, 1048586, "16"},
+  { "pkcs-5-PBES2-params", 1610612741, NULL },
+  { "keyDerivationFunc", 1073741826, "AlgorithmIdentifier"},
+  { "encryptionScheme", 2, "AlgorithmIdentifier"},
+  { "pkcs-5-PBKDF2-params", 1610612741, NULL },
+  { "salt", 1610612754, NULL },
+  { "specified", 1073741831, NULL },
+  { "otherSource", 2, "AlgorithmIdentifier"},
+  { "iterationCount", 1611137027, NULL },
+  { "1", 10, "MAX"},
+  { "keyLength", 1611153411, NULL },
+  { "1", 10, "MAX"},
+  { "prf", 16386, "AlgorithmIdentifier"},
+  { "pkcs-12-PFX", 1610612741, NULL },
+  { "version", 1610874883, NULL },
+  { "v3", 1, "3"},
+  { "authSafe", 1073741826, "pkcs-7-ContentInfo"},
+  { "macData", 16386, "pkcs-12-MacData"},
+  { "pkcs-12-PbeParams", 1610612741, NULL },
+  { "salt", 1073741831, NULL },
+  { "iterations", 3, NULL },
+  { "pkcs-12-MacData", 1610612741, NULL },
+  { "mac", 1073741826, "pkcs-7-DigestInfo"},
+  { "macSalt", 1073741831, NULL },
+  { "iterations", 536903683, NULL },
+  { NULL, 9, "1"},
+  { "pkcs-12-AuthenticatedSafe", 1610612747, NULL },
+  { NULL, 2, "pkcs-7-ContentInfo"},
+  { "pkcs-12-SafeContents", 1610612747, NULL },
+  { NULL, 2, "pkcs-12-SafeBag"},
+  { "pkcs-12-SafeBag", 1610612741, NULL },
+  { "bagId", 1073741836, NULL },
+  { "bagValue", 1614815245, NULL },
+  { NULL, 1073743880, "0"},
+  { "badId", 1, NULL },
+  { "bagAttributes", 536887311, NULL },
+  { NULL, 2, "Attribute"},
+  { "pkcs-12-CertBag", 1610612741, NULL },
+  { "certId", 1073741836, NULL },
+  { "certValue", 541073421, NULL },
+  { NULL, 1073743880, "0"},
+  { "certId", 1, NULL },
+  { "pkcs-12-CRLBag", 1610612741, NULL },
+  { "crlId", 1073741836, NULL },
+  { "crlValue", 541073421, NULL },
+  { NULL, 1073743880, "0"},
+  { "crlId", 1, NULL },
+  { "pkcs-12-SecretBag", 1610612741, NULL },
+  { "secretTypeId", 1073741836, NULL },
+  { "secretValue", 541073421, NULL },
+  { NULL, 1073743880, "0"},
+  { "secretTypeId", 1, NULL },
+  { "pkcs-7-Data", 1073741831, NULL },
+  { "pkcs-7-EncryptedData", 1610612741, NULL },
+  { "version", 1073741827, NULL },
+  { "encryptedContentInfo", 1073741826, "pkcs-7-EncryptedContentInfo"},
+  { "unprotectedAttrs", 536895490, "pkcs-7-UnprotectedAttributes"},
+  { NULL, 4104, "1"},
+  { "pkcs-7-EncryptedContentInfo", 1610612741, NULL },
+  { "contentType", 1073741826, "pkcs-7-ContentType"},
+  { "contentEncryptionAlgorithm", 1073741826, "pkcs-7-ContentEncryptionAlgorithmIdentifier"},
+  { "encryptedContent", 536895495, NULL },
+  { NULL, 4104, "0"},
+  { "pkcs-7-ContentEncryptionAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"},
+  { "pkcs-7-UnprotectedAttributes", 1612709903, NULL },
+  { "MAX", 1074266122, "1"},
+  { NULL, 2, "Attribute"},
+  { "ProxyCertInfo", 1610612741, NULL },
+  { "pCPathLenConstraint", 1611153411, NULL },
+  { "0", 10, "MAX"},
+  { "proxyPolicy", 2, "ProxyPolicy"},
+  { "ProxyPolicy", 1610612741, NULL },
+  { "policyLanguage", 1073741836, NULL },
+  { "policy", 16391, NULL },
+  { "certificatePolicies", 1612709899, NULL },
+  { "MAX", 1074266122, "1"},
+  { NULL, 2, "PolicyInformation"},
+  { "PolicyInformation", 1610612741, NULL },
+  { "policyIdentifier", 1073741836, NULL },
+  { "policyQualifiers", 538984459, NULL },
+  { "MAX", 1074266122, "1"},
+  { NULL, 2, "PolicyQualifierInfo"},
+  { "PolicyQualifierInfo", 1610612741, NULL },
+  { "policyQualifierId", 1073741836, NULL },
+  { "qualifier", 541065229, NULL },
+  { "policyQualifierId", 1, NULL },
+  { "CPSuri", 1073741853, NULL },
+  { "UserNotice", 1610612741, NULL },
+  { "noticeRef", 1073758210, "NoticeReference"},
+  { "explicitText", 16386, "DisplayText"},
+  { "NoticeReference", 1610612741, NULL },
+  { "organization", 1073741826, "DisplayText"},
+  { "noticeNumbers", 536870923, NULL },
+  { NULL, 3, NULL },
+  { "DisplayText", 1610612754, NULL },
+  { "ia5String", 1612709917, NULL },
+  { "200", 524298, "1"},
+  { "visibleString", 1612709923, NULL },
+  { "200", 524298, "1"},
+  { "bmpString", 1612709921, NULL },
+  { "200", 524298, "1"},
+  { "utf8String", 538968098, NULL },
+  { "200", 524298, "1"},
+  { "OCSPRequest", 1610612741, NULL },
+  { "tbsRequest", 1073741826, "TBSRequest"},
+  { "optionalSignature", 536895490, "Signature"},
+  { NULL, 2056, "0"},
+  { "TBSRequest", 1610612741, NULL },
+  { "version", 1610653699, NULL },
+  { NULL, 1073741833, "0"},
+  { NULL, 2056, "0"},
+  { "requestorName", 1610637314, "GeneralName"},
+  { NULL, 2056, "1"},
+  { "requestList", 1610612747, NULL },
+  { NULL, 2, "Request"},
+  { "requestExtensions", 536895490, "Extensions"},
+  { NULL, 2056, "2"},
+  { "Signature", 1610612741, NULL },
+  { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+  { "signature", 1073741830, NULL },
+  { "certs", 536895499, NULL },
+  { NULL, 1073743880, "0"},
+  { NULL, 2, "Certificate"},
+  { "Request", 1610612741, NULL },
+  { "reqCert", 1073741826, "CertID"},
+  { "singleRequestExtensions", 536895490, "Extensions"},
+  { NULL, 2056, "0"},
+  { "CertID", 1610612741, NULL },
+  { "hashAlgorithm", 1073741826, "AlgorithmIdentifier"},
+  { "issuerNameHash", 1073741831, NULL },
+  { "issuerKeyHash", 1073741831, NULL },
+  { "serialNumber", 2, "CertificateSerialNumber"},
+  { "OCSPResponse", 1610612741, NULL },
+  { "responseStatus", 1073741826, "OCSPResponseStatus"},
+  { "responseBytes", 536895490, "ResponseBytes"},
+  { NULL, 2056, "0"},
+  { "OCSPResponseStatus", 1610874901, NULL },
+  { "successful", 1073741825, "0"},
+  { "malformedRequest", 1073741825, "1"},
+  { "internalError", 1073741825, "2"},
+  { "tryLater", 1073741825, "3"},
+  { "sigRequired", 1073741825, "5"},
+  { "unauthorized", 1, "6"},
+  { "ResponseBytes", 1610612741, NULL },
+  { "responseType", 1073741836, NULL },
+  { "response", 7, NULL },
+  { "BasicOCSPResponse", 1610612741, NULL },
+  { "tbsResponseData", 1073741826, "ResponseData"},
+  { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+  { "signature", 1073741830, NULL },
+  { "certs", 536895499, NULL },
+  { NULL, 1073743880, "0"},
+  { NULL, 2, "Certificate"},
+  { "ResponseData", 1610612741, NULL },
+  { "version", 1610653699, NULL },
+  { NULL, 1073741833, "0"},
+  { NULL, 2056, "0"},
+  { "responderID", 1073741826, "ResponderID"},
+  { "producedAt", 1073741861, NULL },
+  { "responses", 1610612747, NULL },
+  { NULL, 2, "SingleResponse"},
+  { "responseExtensions", 536895490, "Extensions"},
+  { NULL, 2056, "1"},
+  { "ResponderID", 1610612754, NULL },
+  { "byName", 1610620930, "RDNSequence"},
+  { NULL, 2056, "1"},
+  { "byKey", 536879111, NULL },
+  { NULL, 4104, "2"},
+  { "SingleResponse", 1610612741, NULL },
+  { "certID", 1073741826, "CertID"},
+  { "certStatus", 1073741826, "CertStatus"},
+  { "thisUpdate", 1073741861, NULL },
+  { "nextUpdate", 1610637349, NULL },
+  { NULL, 2056, "0"},
+  { "singleExtensions", 536895490, "Extensions"},
+  { NULL, 2056, "1"},
+  { "CertStatus", 1610612754, NULL },
+  { "good", 1610620948, NULL },
+  { NULL, 4104, "0"},
+  { "revoked", 1610620930, "RevokedInfo"},
+  { NULL, 4104, "1"},
+  { "unknown", 536879106, "UnknownInfo"},
+  { NULL, 4104, "2"},
+  { "RevokedInfo", 1610612741, NULL },
+  { "revocationTime", 1073741861, NULL },
+  { "revocationReason", 536895490, "CRLReason"},
+  { NULL, 2056, "0"},
+  { "UnknownInfo", 1073741844, NULL },
+  { "CRLReason", 1610874901, NULL },
+  { "unspecified", 1073741825, "0"},
+  { "keyCompromise", 1073741825, "1"},
+  { "cACompromise", 1073741825, "2"},
+  { "affiliationChanged", 1073741825, "3"},
+  { "superseded", 1073741825, "4"},
+  { "cessationOfOperation", 1073741825, "5"},
+  { "certificateHold", 1073741825, "6"},
+  { "removeFromCRL", 1073741825, "8"},
+  { "privilegeWithdrawn", 1073741825, "9"},
+  { "aACompromise", 1, "10"},
+  { "NameConstraints", 1610612741, NULL },
+  { "permittedSubtrees", 1610637314, "GeneralSubtrees"},
+  { NULL, 4104, "0"},
+  { "excludedSubtrees", 536895490, "GeneralSubtrees"},
+  { NULL, 4104, "1"},
+  { "GeneralSubtrees", 1612709899, NULL },
+  { "MAX", 1074266122, "1"},
+  { NULL, 2, "GeneralSubtree"},
+  { "GeneralSubtree", 536870917, NULL },
+  { "base", 1073741826, "GeneralName"},
+  { "minimum", 1610653699, NULL },
+  { NULL, 1073741833, "0"},
+  { NULL, 4104, "0"},
+  { "maximum", 536895491, NULL },
+  { NULL, 4104, "1"},
+  { NULL, 0, NULL }
 };
index 4fc657969bb5929f8c5ccc8ddd4b49a41fd92200..b2e5a17a4806d77b5407878c5efd1275ef012d3e 100644 (file)
@@ -56,6 +56,7 @@ libgnutls_x509_la_SOURCES =   \
        x509.c x509_dn.c        \
        x509_int.h              \
        x509_write.c            \
+       name_constraints.c      \
        verify-high.c           \
        verify-high2.c          \
        verify-high.h
index 4748421b68ea8dbc9b1c927c5768dfab2c14a91f..5b2da0e38c7d53ee9da33dc4ad875cea09a0eb6e 100644 (file)
@@ -820,8 +820,8 @@ int _gnutls_x509_ext_gen_keyUsage(uint16_t usage, gnutls_datum_t * der_ext)
        return 0;
 }
 
-static int
-write_new_general_name(ASN1_TYPE ext, const char *ext_name,
+int
+_gnutls_write_general_name(ASN1_TYPE ext, const char *ext_name,
                       gnutls_x509_subject_alt_name_t type,
                       const void *data, unsigned int data_size)
 {
@@ -829,12 +829,6 @@ write_new_general_name(ASN1_TYPE ext, const char *ext_name,
        int result;
        char name[128];
 
-       result = asn1_write_value(ext, ext_name, "NEW", 1);
-       if (result != ASN1_SUCCESS) {
-               gnutls_assert();
-               return _gnutls_asn2err(result);
-       }
-
        switch (type) {
        case GNUTLS_SAN_DNSNAME:
                str = "dNSName";
@@ -853,21 +847,13 @@ write_new_general_name(ASN1_TYPE ext, const char *ext_name,
                return GNUTLS_E_INTERNAL_ERROR;
        }
 
-       if (ext_name[0] == 0) { /* no dot */
-               _gnutls_str_cpy(name, sizeof(name), "?LAST");
-       } else {
-               _gnutls_str_cpy(name, sizeof(name), ext_name);
-               _gnutls_str_cat(name, sizeof(name), ".?LAST");
-       }
-
-       result = asn1_write_value(ext, name, str, 1);
+       result = asn1_write_value(ext, ext_name, str, 1);
        if (result != ASN1_SUCCESS) {
                gnutls_assert();
                return _gnutls_asn2err(result);
        }
 
-       _gnutls_str_cat(name, sizeof(name), ".");
-       _gnutls_str_cat(name, sizeof(name), str);
+       snprintf(name, sizeof(name), "%s.%s", ext_name, str);
 
        result = asn1_write_value(ext, name, data, data_size);
        if (result != ASN1_SUCCESS) {
@@ -879,6 +865,37 @@ write_new_general_name(ASN1_TYPE ext, const char *ext_name,
        return 0;
 }
 
+static int
+write_new_general_name(ASN1_TYPE ext, const char *ext_name,
+                      gnutls_x509_subject_alt_name_t type,
+                      const void *data, unsigned int data_size)
+{
+       int result;
+       char name[128];
+
+       result = asn1_write_value(ext, ext_name, "NEW", 1);
+       if (result != ASN1_SUCCESS) {
+               gnutls_assert();
+               return _gnutls_asn2err(result);
+       }
+
+       if (ext_name[0] == 0) { /* no dot */
+               _gnutls_str_cpy(name, sizeof(name), "?LAST");
+       } else {
+               _gnutls_str_cpy(name, sizeof(name), ext_name);
+               _gnutls_str_cat(name, sizeof(name), ".?LAST");
+       }
+
+       result = _gnutls_write_general_name(ext, name, type,
+               data, data_size);
+       if (result < 0) {
+               gnutls_assert();
+               return result;
+       }
+
+       return 0;
+}
+
 /* Convert the given name to GeneralNames in a DER encoded extension.
  * This is the same as subject alternative name.
  */
diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c
new file mode 100644 (file)
index 0000000..bdcfdef
--- /dev/null
@@ -0,0 +1,641 @@
+/*
+ * Copyright (C) 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/* Functions on X.509 Certificate parsing
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_datum.h>
+#include <gnutls_global.h>
+#include <gnutls_errors.h>
+#include <common.h>
+#include <gnutls_x509.h>
+#include <x509_b64.h>
+#include <x509_int.h>
+#include <libtasn1.h>
+
+/* Name constraints is limited to DNS names.
+ */
+typedef struct gnutls_name_constraints_st {
+       struct name_constraints_node_st * permitted;
+       struct name_constraints_node_st * excluded;
+} gnutls_name_constraints_st;
+
+typedef struct name_constraints_node_st {
+       unsigned type;
+       gnutls_datum_t name;
+       struct name_constraints_node_st *next;
+} name_constraints_node_st;
+
+static int extract_name_constraints(ASN1_TYPE c2, const char *vstr,
+                                   name_constraints_node_st ** _nc)
+{
+       int ret;
+       char tmpstr[128];
+       unsigned indx = 0;
+       gnutls_datum_t tmp = { NULL, 0 };
+       unsigned int type;
+       struct name_constraints_node_st *nc, *prev;
+
+       nc = prev = *_nc;
+
+       do {
+               indx++;
+               snprintf(tmpstr, sizeof(tmpstr), "%s.?%u.base", vstr, indx);
+
+               ret =
+                   _gnutls_parse_general_name2(c2, tmpstr, -1, &tmp, &type, 0);
+
+               if (ret < 0)
+                       break;
+
+               if (type != GNUTLS_SAN_DNSNAME && type != GNUTLS_SAN_RFC822NAME
+                   && type != GNUTLS_SAN_DN && type != GNUTLS_SAN_URI) {
+                       gnutls_assert();
+                       ret = GNUTLS_E_ILLEGAL_PARAMETER;
+                       goto cleanup;
+               }
+
+               nc = gnutls_malloc(sizeof(struct name_constraints_node_st));
+               if (nc == NULL) {
+                       gnutls_assert();
+                       ret = GNUTLS_E_MEMORY_ERROR;
+                       goto cleanup;
+               }
+
+               memcpy(&nc->name, &tmp, sizeof(gnutls_datum_t));
+               nc->type = type;
+               nc->next = NULL;
+
+               if (prev == NULL) {
+                       *_nc = prev = nc;
+               } else {
+                       prev->next = nc;
+                       prev = nc;
+               }
+
+               tmp.data = NULL;
+       } while (ret >= 0);
+
+       if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       ret = 0;
+ cleanup:
+       if (ret < 0) {
+               nc = *_nc;
+               while (nc != NULL) {
+                       prev = nc->next;
+                       free(nc->name.data);
+                       free(nc);
+                       nc = prev;
+               }
+               *_nc = NULL;
+       }
+       gnutls_free(tmp.data);
+       return ret;
+}
+
+/**
+ * gnutls_x509_crt_get_name_constraints:
+ * @crt: should contain a #gnutls_x509_crt_t structure
+ * @nc: The nameconstraints intermediate structure
+ * @critical: the extension status
+ *
+ * This function will return an intermediate structure containing
+ * the name constraints of the provided CA certificate. That
+ * structure can be used in combination with gnutls_x509_name_constraints_check()
+ * to verify whether a server's name is in accordance with the constraints.
+ *
+ * Note that @nc must be initialized prior to calling this function.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
+ * if the extension is not present, otherwise a negative error value.
+ *
+ * Since: 3.3.0
+ **/
+int gnutls_x509_crt_get_name_constraints(gnutls_x509_crt_t crt,
+                                        gnutls_x509_name_constraints_t nc,
+                                        unsigned int *critical)
+{
+       int result, ret;
+       gnutls_datum_t der = { NULL, 0 };
+       ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
+
+       if (crt == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       ret =
+           _gnutls_x509_crt_get_extension(crt, "2.5.29.30", 0, &der,
+                                          critical);
+       if (ret < 0)
+               return gnutls_assert_val(ret);
+
+       if (der.size == 0 || der.data == NULL)
+               return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+
+       result = asn1_create_element
+           (_gnutls_get_pkix(), "PKIX1.NameConstraints", &c2);
+       if (result != ASN1_SUCCESS) {
+               gnutls_assert();
+               ret = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       result = asn1_der_decoding(&c2, der.data, der.size, NULL);
+       if (result != ASN1_SUCCESS) {
+               gnutls_assert();
+               ret = _gnutls_asn2err(result);
+               goto cleanup;
+       }
+
+       ret = extract_name_constraints(c2, "permittedSubtrees", &nc->permitted);
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       ret = extract_name_constraints(c2, "excludedSubtrees", &nc->excluded);
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       ret = 0;
+
+ cleanup:
+       _gnutls_free_datum(&der);
+       asn1_delete_structure(&c2);
+
+       return ret;
+
+}
+
+/**
+ * gnutls_x509_name_constraints_deinit:
+ * @nc: The nameconstraints structure
+ *
+ * This function will deinitialize a name constraints structure.
+ *
+ * Since: 3.3.0
+ **/
+void gnutls_x509_name_constraints_deinit(gnutls_x509_name_constraints_t nc)
+{
+       name_constraints_node_st * next, *t;
+
+       t = nc->permitted;
+       while (t != NULL) {
+               next = t->next;
+               free(t->name.data);
+               free(t);
+               t = next;
+       }
+
+       t = nc->excluded;
+       while (t != NULL) {
+               next = t->next;
+               free(t->name.data);
+               free(t);
+               t = next;
+       }
+}
+
+/**
+ * gnutls_x509_name_constraints_init:
+ * @nc: The nameconstraints structure
+ *
+ * This function will initialize a name constraints structure.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
+ *
+ * Since: 3.3.0
+ **/
+int gnutls_x509_name_constraints_init(gnutls_x509_name_constraints_t *nc)
+{
+       *nc = gnutls_calloc(1, sizeof(struct gnutls_name_constraints_st));
+       if (*nc == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+
+       return 0;
+}
+
+static
+int name_constraints_add(gnutls_x509_name_constraints_t nc,
+                      gnutls_x509_subject_alt_name_t type,
+                      const gnutls_datum_t * name,
+                      unsigned permitted)
+{
+       struct name_constraints_node_st * tmp, *prev = NULL;
+       int ret;
+
+       if (type != GNUTLS_SAN_DNSNAME && type != GNUTLS_SAN_RFC822NAME &&
+               type != GNUTLS_SAN_DN && type != GNUTLS_SAN_URI)
+               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+       if (type == GNUTLS_SAN_DNSNAME && name->size > 0 && name->data[0] == '.') {
+               _gnutls_debug_log("DNSNAME constraints cannot start with '.'. They must contain a domain name\n");
+               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+       }
+
+       if (permitted != 0)
+               prev = tmp = nc->permitted;
+       else
+               prev = tmp = nc->excluded;
+
+       while(tmp != NULL) {
+               tmp = tmp->next;
+               if (tmp != NULL)
+                       prev = tmp;
+       }
+
+       tmp = gnutls_malloc(sizeof(struct name_constraints_node_st));
+       if (tmp == NULL)
+               return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+       tmp->next = NULL;
+       tmp->type = type;
+       ret = _gnutls_set_datum(&tmp->name, name->data, name->size);
+       if (ret < 0) {
+               gnutls_assert();
+               gnutls_free(tmp);
+               return ret;
+       }
+
+       if (prev == NULL) {
+               if (permitted != 0)
+                       nc->permitted = tmp;
+               else
+                       nc->excluded = tmp;
+       } else
+               prev->next = tmp;
+
+       return 0;
+}
+
+/**
+ * gnutls_x509_name_constraints_add_permitted:
+ * @nc: The nameconstraints structure
+ * @type: The type of the constraints
+ * @name: The data of the constraints
+ *
+ * This function will add a name constraint to the list of permitted
+ * constraints.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
+ *
+ * Since: 3.3.0
+ **/
+int gnutls_x509_name_constraints_add_permitted(gnutls_x509_name_constraints_t nc,
+                                              gnutls_x509_subject_alt_name_t type,
+                                              const gnutls_datum_t * name)
+{
+       return name_constraints_add(nc, type, name, 1);
+}
+
+/**
+ * gnutls_x509_name_constraints_add_excluded:
+ * @nc: The nameconstraints structure
+ * @type: The type of the constraints
+ * @name: The data of the constraints
+ *
+ * This function will add a name constraint to the list of excluded
+ * constraints.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
+ *
+ * Since: 3.3.0
+ **/
+int gnutls_x509_name_constraints_add_excluded(gnutls_x509_name_constraints_t nc,
+                                             gnutls_x509_subject_alt_name_t type,
+                                             const gnutls_datum_t * name)
+{
+       return name_constraints_add(nc, type, name, 0);
+}
+
+/**
+ * gnutls_x509_crt_set_name_constraints:
+ * @crt: The certificate structure
+ * @nc: The nameconstraints structure
+ *
+ * This function will set the provided name constraints to
+ * the certificate extension list. This extension is always
+ * marked as critical.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
+ *
+ * Since: 3.3.0
+ **/
+int gnutls_x509_crt_set_name_constraints(gnutls_x509_crt_t crt, 
+                                        gnutls_x509_name_constraints_t nc)
+{
+int ret, result;
+gnutls_datum_t der_data;
+uint8_t null = 0;
+ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
+struct name_constraints_node_st * tmp;
+
+       if (nc->permitted == NULL && nc->excluded == NULL)
+               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+       result = asn1_create_element
+           (_gnutls_get_pkix(), "PKIX1.NameConstraints", &c2);
+       if (result != ASN1_SUCCESS) {
+               gnutls_assert();
+               return _gnutls_asn2err(result);
+       }
+
+       if (nc->permitted == NULL) {
+               asn1_write_value(c2, "permittedSubtrees", NULL, 0);
+       } else {
+               tmp = nc->permitted;
+               do {
+                       result = asn1_write_value(c2, "permittedSubtrees", "NEW", 1);
+                       if (result != ASN1_SUCCESS) {
+                               gnutls_assert();
+                               ret = _gnutls_asn2err(result);
+                               goto cleanup;
+                       }
+
+                       result = asn1_write_value(c2, "permittedSubtrees.?LAST.maximum", NULL, 0);
+                       if (result != ASN1_SUCCESS) {
+                               gnutls_assert();
+                               ret = _gnutls_asn2err(result);
+                               goto cleanup;
+                       }
+
+                       result = asn1_write_value(c2, "permittedSubtrees.?LAST.minimum", &null, 1);
+                       if (result != ASN1_SUCCESS) {
+                               gnutls_assert();
+                               ret = _gnutls_asn2err(result);
+                               goto cleanup;
+                       }
+
+                       ret = _gnutls_write_general_name(c2, "permittedSubtrees.?LAST.base", 
+                                               tmp->type, tmp->name.data, tmp->name.size);
+                       if (ret < 0) {
+                               gnutls_assert();
+                               goto cleanup;
+                       }
+                       tmp = tmp->next;
+               } while(tmp != NULL);
+       }
+
+       if (nc->excluded == NULL) {
+               asn1_write_value(c2, "excludedSubtrees", NULL, 0);
+       } else {
+               tmp = nc->excluded;
+               do {
+                       result = asn1_write_value(c2, "excludedSubtrees", "NEW", 1);
+                       if (result != ASN1_SUCCESS) {
+                               gnutls_assert();
+                               ret = _gnutls_asn2err(result);
+                               goto cleanup;
+                       }
+
+                       result = asn1_write_value(c2, "excludedSubtrees.?LAST.maximum", NULL, 0);
+                       if (result != ASN1_SUCCESS) {
+                               gnutls_assert();
+                               ret = _gnutls_asn2err(result);
+                               goto cleanup;
+                       }
+
+                       result = asn1_write_value(c2, "excludedSubtrees.?LAST.minimum", &null, 1);
+                       if (result != ASN1_SUCCESS) {
+                               gnutls_assert();
+                               ret = _gnutls_asn2err(result);
+                               goto cleanup;
+                       }
+
+                       ret = _gnutls_write_general_name(c2, "excludedSubtrees.?LAST.base", 
+                                               tmp->type, tmp->name.data, tmp->name.size);
+                       if (ret < 0) {
+                               gnutls_assert();
+                               goto cleanup;
+                       }
+                       tmp = tmp->next;
+               } while(tmp != NULL);
+
+       }
+
+       ret = _gnutls_x509_der_encode(c2, "", &der_data, 0);
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       ret =
+           _gnutls_x509_crt_set_extension(crt, "2.5.29.30", &der_data, 1);
+
+       _gnutls_free_datum(&der_data);
+
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       ret = 0;
+       crt->use_extensions = 1;
+
+cleanup:
+       asn1_delete_structure(&c2);
+       return ret;
+
+}
+
+static
+unsigned ends_with(const gnutls_datum_t * str, const gnutls_datum_t * suffix)
+{
+       if (suffix->size >= str->size)
+               return 0;
+
+       if (memcmp(str->data + str->size - suffix->size, suffix->data, suffix->size) == 0 &&
+               str->data[str->size - suffix->size -1] == '.')
+               return 1;
+
+       return 0;
+}
+
+static unsigned dnsname_matches(const gnutls_datum_t *name, const gnutls_datum_t *suffix)
+{
+       _gnutls_hard_log("matching %.*s with constraint %.*s\n", name->size, name->data,
+               suffix->size, suffix->data);
+
+       if (suffix->size == name->size && memcmp(suffix->data, name->data, suffix->size) == 0)
+               return 1; /* match */
+
+       return ends_with(name, suffix);
+}
+
+/**
+ * gnutls_x509_name_constraints_check:
+ * @nc: the extracted name constraints structure
+ * @type: the type of the constraint to check (of type gnutls_x509_subject_alt_name_t)
+ * @name: the name to be checked
+ *
+ * This function will check the provided name against the constraints in
+ * @nc using the RFC5280 rules. Currently this function is limited to DNS
+ * names (of type %GNUTLS_SAN_DNSNAME).
+ *
+ * Returns: zero if the provided name is not acceptable, and non-zero otherwise.
+ *
+ * Since: 3.3.0
+ **/
+unsigned gnutls_x509_name_constraints_check(gnutls_x509_name_constraints_t nc,
+                                      gnutls_x509_subject_alt_name_t type,
+                                      const gnutls_datum_t * name)
+{
+unsigned i;
+int ret;
+unsigned rtype;
+unsigned allowed_found = 0;
+gnutls_datum_t rname;
+
+       if (type != GNUTLS_SAN_DNSNAME)
+               return gnutls_assert_val(0);
+
+       /* check restrictions */
+       i = 0;
+       do {
+               ret = gnutls_x509_name_constraints_get_excluded(nc, i++, &rtype, &rname);
+               if (ret >= 0 && rtype != type)
+                       continue;
+
+               if (rname.size == 0)
+                       continue;
+
+               if (dnsname_matches(name, &rname) != 0)
+                       return gnutls_assert_val(0); /* rejected */
+       } while(ret == 0);
+
+       /* check allowed */
+       i = 0;
+       do {
+               ret = gnutls_x509_name_constraints_get_permitted(nc, i++, &rtype, &rname);
+               if (ret >= 0 && rtype != type)
+                       continue;
+
+               if (rname.size == 0)
+                       continue;
+
+               allowed_found = 1;
+
+               if (dnsname_matches(name, &rname) != 0)
+                       return 1; /* accepted */
+       } while(ret == 0);
+
+       if (allowed_found != 0) /* there are allowed directives but this host wasn't found */
+               return gnutls_assert_val(0);
+       
+       return 1;
+}
+
+/**
+ * gnutls_x509_name_constraints_get_permitted:
+ * @nc: the extracted name constraints structure
+ * @idx: the index of the constraint
+ * @type: the type of the constraint (of type gnutls_x509_subject_alt_name_t)
+ * @name: the name in the constraint (of the specific type)
+ *
+ * This function will return an intermediate structure containing
+ * the name constraints of the provided CA certificate. That
+ * structure can be used in combination with gnutls_x509_name_constraints_check()
+ * to verify whether a server's name is in accordance with the constraints.
+ *
+ * The name should be treated as constant and valid for the lifetime of @nc.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
+ * if the extension is not present, otherwise a negative error value.
+ *
+ * Since: 3.3.0
+ **/
+int gnutls_x509_name_constraints_get_permitted(gnutls_x509_name_constraints_t nc,
+                                    unsigned idx,
+                                    unsigned *type, gnutls_datum_t * name)
+{
+       unsigned int i;
+       struct name_constraints_node_st * tmp = nc->permitted;
+
+       for (i = 0; i < idx; i++) {
+               if (tmp == NULL)
+                       return
+                           gnutls_assert_val
+                           (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+
+               tmp = tmp->next;
+       }
+
+       if (tmp == NULL)
+               return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+
+       *type = tmp->type;
+       *name = tmp->name;
+
+       return 0;
+}
+
+/**
+ * gnutls_x509_name_constraints_get_excluded:
+ * @nc: the extracted name constraints structure
+ * @idx: the index of the constraint
+ * @type: the type of the constraint (of type gnutls_x509_subject_alt_name_t)
+ * @name: the name in the constraint (of the specific type)
+ *
+ * This function will return an intermediate structure containing
+ * the name constraints of the provided CA certificate. That
+ * structure can be used in combination with gnutls_x509_name_constraints_check()
+ * to verify whether a server's name is in accordance with the constraints.
+ *
+ * The name should be treated as constant and valid for the lifetime of @nc.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
+ * if the extension is not present, otherwise a negative error value.
+ *
+ * Since: 3.3.0
+ **/
+int gnutls_x509_name_constraints_get_excluded(gnutls_x509_name_constraints_t nc,
+                                    unsigned idx,
+                                    unsigned *type, gnutls_datum_t * name)
+{
+       unsigned int i;
+       struct name_constraints_node_st * tmp = nc->excluded;
+
+       for (i = 0; i < idx; i++) {
+               if (tmp == NULL)
+                       return
+                           gnutls_assert_val
+                           (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+
+               tmp = tmp->next;
+       }
+
+       if (tmp == NULL)
+               return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+
+       *type = tmp->type;
+       *name = tmp->name;
+
+       return 0;
+}
index f88b1a802d52dd7c68903c8435cb7135e5cb195c..fd3fd1a72e69724fc233514e7b64f1a629be72dc 100644 (file)
@@ -158,6 +158,69 @@ static void print_proxy(gnutls_buffer_st * str, gnutls_x509_crt_t cert)
        }
 }
 
+static void print_nc(gnutls_buffer_st * str, const char* prefix, gnutls_x509_crt_t cert)
+{
+       gnutls_x509_name_constraints_t nc;
+       int ret;
+       unsigned critical, idx = 0;
+       gnutls_datum_t name;
+       unsigned type;
+
+       ret = gnutls_x509_name_constraints_init(&nc);
+       if (ret < 0)
+               return;
+
+       ret = gnutls_x509_crt_get_name_constraints(cert, nc, &critical);
+       if (ret < 0)
+               goto cleanup;
+
+       do {
+               ret = gnutls_x509_name_constraints_get_permitted(nc, idx++, &type, &name);
+
+               if (ret >= 0) {
+                       if (idx == 1)
+                               addf(str,  _("%s\t\t\tPermitted:\n"), prefix);
+
+                       if (type == GNUTLS_SAN_DNSNAME) {
+                               addf(str,  _("%s\t\t\tDNSname:%s\n"), prefix, name.data);
+                       } else if (type == GNUTLS_SAN_RFC822NAME) {
+                               addf(str,  _("%s\t\t\tRFC822Name:%s\n"), prefix, name.data);
+                       } else if (type == GNUTLS_SAN_URI) {
+                               addf(str,  _("%s\t\t\tURI:%s\n"), prefix, name.data);
+                       } else if (type == GNUTLS_SAN_DN) {
+                               addf(str,  _("%s\t\t\tdirectoryName:"), prefix);
+                               _gnutls_buffer_hexprint(str, name.data, name.size);
+                               adds(str,  _(" \n"));
+                       }
+               }
+       } while (ret == 0);
+
+       idx = 0;
+       do {
+               ret = gnutls_x509_name_constraints_get_excluded(nc, idx++, &type, &name);
+
+               if (ret >= 0) {
+                       if (idx == 1)
+                               addf(str,  _("%s\t\t\tExcluded:\n"), prefix);
+
+                       if (type == GNUTLS_SAN_DNSNAME) {
+                               addf(str,  _("%s\t\t\tDNSname:%s\n"), prefix, name.data);
+                       } else if (type == GNUTLS_SAN_RFC822NAME) {
+                               addf(str,  _("%s\t\t\tRFC822Name:%s\n"), prefix, name.data);
+                       } else if (type == GNUTLS_SAN_URI) {
+                               addf(str,  _("%s\t\t\tURI:%s\n"), prefix, name.data);
+                       } else if (type == GNUTLS_SAN_DN) {
+                               addf(str,  _("%s\t\t\tdirectoryName:"), prefix);
+                               _gnutls_buffer_hexprint(str, name.data, name.size);
+                               adds(str,  _(" \n"));
+                       }
+               }
+       } while (ret == 0);
+
+cleanup:
+       gnutls_x509_name_constraints_deinit(nc);
+}
+
 static void print_aia(gnutls_buffer_st * str, gnutls_x509_crt_t cert)
 {
        int err;
@@ -982,7 +1045,7 @@ print_extensions(gnutls_buffer_st * str, const char *prefix, int type,
        int keyusage_idx = 0;
        int keypurpose_idx = 0;
        int ski_idx = 0;
-       int aki_idx = 0;
+       int aki_idx = 0, nc_idx = 0;
        int crldist_idx = 0, pkey_usage_period_idx = 0;
        char pfx[16];
 
@@ -1225,6 +1288,19 @@ print_extensions(gnutls_buffer_st * str, const char *prefix, int type,
 
                        if (type == TYPE_CRT)
                                print_aia(str, cert.crt);
+               } else if (strcmp(oid, "2.5.29.30") == 0) {
+                       if (nc_idx) {
+                               addf(str,
+                                    "error: more than one name constraints extension\n");
+                               continue;
+                       }
+                       nc_idx++;
+
+                       addf(str, _("%s\t\tName Constraints (%s):\n"), prefix,
+                            critical ? _("critical") : _("not critical"));
+
+                       if (type == TYPE_CRT)
+                               print_nc(str, prefix, cert.crt);
                } else {
                        char *buffer;
                        size_t extlen = 0;
index cf9afa5554ab94251c9a684d6a85f1ef2863a905..24722cff2bfa7ba25d1fca662bbb3883125482c4 100644 (file)
@@ -1108,6 +1108,13 @@ inline static int is_type_printable(int type)
 
 /* returns the type and the name on success.
  * Type is also returned as a parameter in case of an error.
+ *
+ * @seq: in case of GeneralNames it will return the corresponding name.
+ *       in case of GeneralName, it must be -1
+ * @dname: the name returned
+ * @ret_type: The type of the name
+ * @othername_oid: if the name is AnotherName return the OID
+ *
  */
 int
 _gnutls_parse_general_name2(ASN1_TYPE src, const char *src_name,
@@ -1121,12 +1128,16 @@ _gnutls_parse_general_name2(ASN1_TYPE src, const char *src_name,
        char choice_type[128];
        gnutls_x509_subject_alt_name_t type;
 
-       seq++;                  /* 0->1, 1->2 etc */
+       if (seq != -1) {
+               seq++;  /* 0->1, 1->2 etc */
 
-       if (src_name[0] != 0)
-               snprintf(nptr, sizeof(nptr), "%s.?%u", src_name, seq);
-       else
-               snprintf(nptr, sizeof(nptr), "?%u", seq);
+               if (src_name[0] != 0)
+                       snprintf(nptr, sizeof(nptr), "%s.?%u", src_name, seq);
+               else
+                       snprintf(nptr, sizeof(nptr), "?%u", seq);
+       } else {
+               snprintf(nptr, sizeof(nptr), "%s", src_name);
+       }
 
        len = sizeof(choice_type);
        result = asn1_read_value(src, nptr, choice_type, &len);
index ae3871c7796e30aae46011013b4bf160360eedda..0389de8133a497b5a250c46bb7ef58e188927671 100644 (file)
@@ -215,6 +215,11 @@ _gnutls_x509_ext_gen_number(const uint8_t * nuber, size_t nr_size,
                            gnutls_datum_t * der_ext);
 
 
+int
+_gnutls_write_general_name(ASN1_TYPE ext, const char *ext_name,
+                      gnutls_x509_subject_alt_name_t type,
+                      const void *data, unsigned int data_size);
+
 int _gnutls_x509_ext_gen_basicConstraints(int CA, int pathLenConstraint,
                                          gnutls_datum_t * der_ext);
 int _gnutls_x509_ext_gen_keyUsage(uint16_t usage,
index 07ba72cc12d55e0c09f7b6771fdbac134a796999..8e9cdde20dd5974b1b87d5c1358d042aad054d28 100644 (file)
@@ -74,7 +74,7 @@ ctests = mini-record-2 simple gc set_pkcs12_cred certder certuniqueid \
         mini-dtls-srtp mini-xssl rsa-encrypt-decrypt mini-loss-time \
         mini-record mini-dtls-record mini-handshake-timeout mini-record-range \
         mini-cert-status mini-rsa-psk global-init sec-params \
-        fips-test mini-global-load
+        fips-test mini-global-load name-constraints
 
 if ENABLE_OCSP
 ctests += ocsp