]> granicus.if.org Git - p11-kit/commitdiff
Add support for openssl TRUSTED CERTIFICATE PEM files
authorStef Walter <stefw@gnome.org>
Mon, 17 Dec 2012 11:51:53 +0000 (12:51 +0100)
committerStef Walter <stefw@gnome.org>
Tue, 5 Feb 2013 13:54:53 +0000 (14:54 +0100)
build/certs/Makefile.am
common/Makefile.am
common/openssl.asn [new file with mode: 0644]
common/openssl.asn.h [new file with mode: 0644]
doc/p11-kit-trust.xml
trust/parser.c
trust/tests/files/cacert3-trusted.pem [new file with mode: 0644]
trust/tests/test-parser.c

index b0439a4f347ed662610a47c12a6f760db3b5dc5e..f8ec1c2127e17e13c5dddb171181743b8ab6acce 100644 (file)
@@ -9,6 +9,9 @@ prepare-certs:
        cp -v cacert3.der $(TRUST)/anchors
        cp -v cacert3.der $(TRUST)/files
        openssl x509 -in cacert3.der -inform DER -out $(TRUST)/files/cacert3.pem
+       openssl x509 -in cacert3.der -inform DER -out $(TRUST)/files/cacert3-trusted.pem \
+               -addtrust clientAuth -addtrust serverAuth -addreject emailProtection \
+               -setalias "Custom Label"
        cp -v cacert-ca.der $(TRUST)/certificates
        cp -v cacert-ca.der $(TRUST)/files
        cp -v self-server.der $(TRUST)/files
index 00c043bc86b46f0e9d2796b236c9f3153e56b36f..d527e957501819f1eeace668ce767ce142485e4e 100644 (file)
@@ -41,11 +41,13 @@ noinst_LTLIBRARIES += \
 libp11_data_la_SOURCES = \
        base64.c base64.h \
        checksum.c checksum.h \
+       openssl.asn openssl.asn.h \
        pem.c pem.h \
        pkix.asn pkix.asn.h \
        $(NULL)
 
 asn:
        asn1Parser -o pkix.asn.h pkix.asn
+       asn1Parser -o openssl.asn.h openssl.asn
 
 endif # WITH_ASN1
diff --git a/common/openssl.asn b/common/openssl.asn
new file mode 100644 (file)
index 0000000..c1f452b
--- /dev/null
@@ -0,0 +1,28 @@
+
+OPENSSL { }
+
+DEFINITIONS IMPLICIT TAGS ::=
+
+BEGIN
+
+-- This module contains structures specific to OpenSSL
+
+CertAux ::= SEQUENCE {
+      trust                     SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
+      reject                    [0] SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
+      alias                     UTF8String OPTIONAL,
+      keyid                     OCTET STRING OPTIONAL,
+      other                     [1] SEQUENCE OF AlgorithmIdentifier OPTIONAL
+}
+
+-- Dependencies brought in from other modules
+
+AlgorithmIdentifier  ::=  SEQUENCE  {
+     algorithm               OBJECT IDENTIFIER,
+     parameters              ANY DEFINED BY algorithm OPTIONAL
+}
+
+UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING
+        -- The content of this type conforms to RFC 2279.
+
+END
diff --git a/common/openssl.asn.h b/common/openssl.asn.h
new file mode 100644 (file)
index 0000000..4e6b240
--- /dev/null
@@ -0,0 +1,28 @@
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <libtasn1.h>
+
+const ASN1_ARRAY_TYPE openssl_asn1_tab[] = {
+  { "OPENSSL", 536875024, NULL },
+  { NULL, 1073741836, NULL },
+  { "CertAux", 1610612741, NULL },
+  { "trust", 1610629131, NULL },
+  { NULL, 12, NULL },
+  { "reject", 1610637323, NULL },
+  { NULL, 1073745928, "0"},
+  { NULL, 12, NULL },
+  { "alias", 1073758210, "UTF8String"},
+  { "keyid", 1073758215, NULL },
+  { "other", 536895499, NULL },
+  { NULL, 1073745928, "1"},
+  { NULL, 2, "AlgorithmIdentifier"},
+  { "AlgorithmIdentifier", 1610612741, NULL },
+  { "algorithm", 1073741836, NULL },
+  { "parameters", 541081613, NULL },
+  { "algorithm", 1, NULL },
+  { "UTF8String", 536879111, NULL },
+  { NULL, 4360, "12"},
+  { NULL, 0, NULL }
+};
index 7496f7b86144f0860c2bbaec9ac82eb793e81b5f..036b422b7cac35bcd3c3828678646994d91d3edc 100644 (file)
@@ -47,6 +47,14 @@ $ pkg-config --variable p11_system_certificates p11-kit-1
                        <term>X.509 certificates</term>
                        <listitem><para>X.509 certificates in raw DER format.</para></listitem>
                </varlistentry>
+               <varlistentry>
+                       <term>OpenSSL trust certificates</term>
+                       <listitem><para>OpenSSL specific certificates in PEM format
+                       that contain trust information. These have a
+                       <literal>TRUSTED CERTIFICATE</literal> PEM header. Both
+                       trust policy and blacklist information can be loaded
+                       from these files.</para></listitem>
+               </varlistentry>
        </variablelist>
 </section>
 
index 65d7855536fde41fbfeaa1affa097d076f8886ff..25af902dee41a94b2e21f4649f78bb28e97fd727 100644 (file)
 #include <string.h>
 #include <unistd.h>
 
+#include "openssl.asn.h"
 #include "pkix.asn.h"
 
 struct _p11_parser {
        node_asn *pkix_definitions;
+       node_asn *openssl_definitions;
        p11_parser_sink sink;
        void *sink_data;
        const char *probable_label;
@@ -90,6 +92,9 @@ decode_asn1 (p11_parser *parser,
        if (strncmp (struct_name, "PKIX1.", 6) == 0) {
                definitions = parser->pkix_definitions;
 
+       } else if (strncmp (struct_name, "OPENSSL.", 8) == 0) {
+               definitions = parser->openssl_definitions;
+
        } else {
                p11_debug_precond ("unknown prefix for element: %s", struct_name);
                return NULL;
@@ -138,11 +143,11 @@ id_generate (p11_parser *parser,
 
 static CK_ATTRIBUTE *
 build_object (p11_parser *parser,
-              CK_ATTRIBUTE *attrs,
               CK_OBJECT_CLASS vclass,
               CK_BYTE *vid,
               const char *explicit_label)
 {
+       CK_ATTRIBUTE *attrs = NULL;
        CK_BBOOL vtrue = CK_TRUE;
        CK_BBOOL vfalse = CK_FALSE;
        const char *vlabel;
@@ -566,11 +571,12 @@ calc_element (node_asn *el,
 
 static CK_ATTRIBUTE *
 build_x509_certificate (p11_parser *parser,
-                        CK_ATTRIBUTE *attrs,
+                        CK_BYTE *vid,
                         node_asn *cert,
                         const unsigned char *data,
                         size_t length)
 {
+       CK_ATTRIBUTE *attrs;
        CK_CERTIFICATE_TYPE vx509 = CKC_X_509;
        CK_BYTE vchecksum[3];
 
@@ -618,6 +624,9 @@ build_x509_certificate (p11_parser *parser,
        if (!calc_element (cert, data, length, "tbsCertificate.serialNumber", &serial_number))
                serial_number.type = CKA_INVALID;
 
+       attrs = build_object (parser, CKO_CERTIFICATE, vid, NULL);
+       return_val_if_fail (attrs != NULL, NULL);
+
        return p11_attrs_build (attrs, &certificate_type, &certificate_category,
                                &check_value, &trusted, &start_date, &end_date,
                                &subject, &issuer, &serial_number, &value,
@@ -828,11 +837,13 @@ has_eku (p11_dict *ekus,
 
 static CK_ATTRIBUTE *
 build_nss_trust_object (p11_parser *parser,
-                        CK_ATTRIBUTE *attrs,
+                        CK_BYTE *vid,
                         node_asn *cert,
                         const unsigned char *data,
                         size_t length)
 {
+       CK_ATTRIBUTE *attrs = NULL;
+
        CK_BYTE vsha1_hash[P11_CHECKSUM_SHA1_LENGTH];
        CK_BYTE vmd5_hash[P11_CHECKSUM_MD5_LENGTH];
        CK_BBOOL vfalse = CK_FALSE;
@@ -920,6 +931,9 @@ build_nss_trust_object (p11_parser *parser,
        vtime_stamping = has_eku (ekus, P11_EKU_TIME_STAMPING) ? value : unknown;
        p11_dict_free (ekus);
 
+       attrs = build_object (parser, CKO_NETSCAPE_TRUST, vid, NULL);
+       return_val_if_fail (attrs != NULL, NULL);
+
        return p11_attrs_build (attrs, &subject, &issuer, &serial_number, &md5_hash, &sha1_hash,
                                &digital_signature, &non_repudiation, &key_encipherment,
                                &data_encipherment, &key_agreement, &key_cert_sign, &crl_sign,
@@ -930,66 +944,211 @@ build_nss_trust_object (p11_parser *parser,
 }
 
 static int
-sink_nss_trust_object (p11_parser *parser,
-                       CK_BYTE *vid,
-                       node_asn *cert,
-                       const unsigned char *data,
-                       size_t length)
+parse_der_x509_certificate (p11_parser *parser,
+                            const unsigned char *data,
+                            size_t length)
 {
-       CK_ATTRIBUTE *attrs = NULL;
+       CK_BYTE vid[ID_LENGTH];
+       CK_ATTRIBUTE *attrs;
+       node_asn *cert;
 
-       attrs = build_object (parser, attrs, CKO_NETSCAPE_TRUST, vid, NULL);
-       return_val_if_fail (attrs != NULL, P11_PARSE_FAILURE);
+       cert = decode_asn1 (parser, "PKIX1.Certificate", data, length, NULL);
+       if (cert == NULL)
+               return P11_PARSE_UNRECOGNIZED;
 
-       attrs = build_nss_trust_object (parser, attrs, cert, data, length);
+       /* The CKA_ID links related objects */
+       id_generate (parser, vid);
+
+       attrs = build_x509_certificate (parser, vid, cert, data, length);
        return_val_if_fail (attrs != NULL, P11_PARSE_FAILURE);
+       sink_object (parser, attrs);
 
+       attrs = build_nss_trust_object (parser, vid, cert, data, length);
+       return_val_if_fail (attrs != NULL, P11_PARSE_FAILURE);
        sink_object (parser, attrs);
+
+       asn1_delete_structure (&cert);
        return P11_PARSE_SUCCESS;
 }
 
-static int
-sink_x509_certificate (p11_parser *parser,
-                       CK_BYTE *vid,
-                       node_asn *cert,
-                       const unsigned char *data,
-                       size_t length)
+static ssize_t
+calc_der_length (const unsigned char *data,
+                 size_t length)
 {
-       CK_ATTRIBUTE *attrs = NULL;
+       unsigned char cls;
+       int counter = 0;
+       int cb, len;
+       unsigned long tag;
+
+       if (asn1_get_tag_der (data, length, &cls, &cb, &tag) == ASN1_SUCCESS) {
+               counter += cb;
+               len = asn1_get_length_der (data + cb, length - cb, &cb);
+               counter += cb;
+               if (len >= 0) {
+                       len += counter;
+                       if (length >= len)
+                               return len;
+               }
+       }
 
-       attrs = build_object (parser, attrs, CKO_CERTIFICATE, vid, NULL);
-       return_val_if_fail (attrs != NULL, P11_PARSE_FAILURE);
+       return -1;
+}
 
-       attrs = build_x509_certificate (parser, attrs, cert, data, length);
-       return_val_if_fail (attrs != NULL, P11_PARSE_FAILURE);
+static CK_ATTRIBUTE *
+overlay_cert_aux_on_nss_trust_object (p11_parser *parser,
+                                      CK_ATTRIBUTE *attrs,
+                                      node_asn *aux)
+{
+       CK_TRUST vserver_auth = CKT_NETSCAPE_TRUST_UNKNOWN;
+       CK_TRUST vclient_auth = CKT_NETSCAPE_TRUST_UNKNOWN;
+       CK_TRUST vcode_signing = CKT_NETSCAPE_TRUST_UNKNOWN;
+       CK_TRUST vemail_protection = CKT_NETSCAPE_TRUST_UNKNOWN;
+       CK_TRUST vipsec_end_system = CKT_NETSCAPE_TRUST_UNKNOWN;
+       CK_TRUST vipsec_tunnel = CKT_NETSCAPE_TRUST_UNKNOWN;
+       CK_TRUST vipsec_user = CKT_NETSCAPE_TRUST_UNKNOWN;
+       CK_TRUST vtime_stamping = CKT_NETSCAPE_TRUST_UNKNOWN;
 
-       sink_object (parser, attrs);
-       return P11_PARSE_SUCCESS;
+       CK_ATTRIBUTE server_auth = { CKA_TRUST_SERVER_AUTH, &vserver_auth, sizeof (vserver_auth) };
+       CK_ATTRIBUTE client_auth = { CKA_TRUST_CLIENT_AUTH, &vclient_auth, sizeof (vclient_auth) };
+       CK_ATTRIBUTE code_signing = { CKA_TRUST_CODE_SIGNING, &vcode_signing, sizeof (vcode_signing) };
+       CK_ATTRIBUTE email_protection = { CKA_TRUST_EMAIL_PROTECTION, &vemail_protection, sizeof (vemail_protection) };
+       CK_ATTRIBUTE ipsec_end_system = { CKA_TRUST_IPSEC_END_SYSTEM, &vipsec_end_system, sizeof (vipsec_end_system) };
+       CK_ATTRIBUTE ipsec_tunnel = { CKA_TRUST_IPSEC_TUNNEL, &vipsec_tunnel, sizeof (vipsec_tunnel) };
+       CK_ATTRIBUTE ipsec_user = { CKA_TRUST_IPSEC_USER, &vipsec_user, sizeof (vipsec_user) };
+       CK_ATTRIBUTE time_stamping = { CKA_TRUST_TIME_STAMPING, &vtime_stamping, sizeof (vtime_stamping) };
+
+       CK_ULONG trust;
+       char field[256];
+       char oid[256];
+       int len;
+       int ret;
+       int i;
+       int j;
+
+       /* The various CertAux SEQ's we look at for trust information */
+       struct {
+               const char *field;
+               CK_ULONG trust;
+       } trust_fields[] = {
+               { "trust", (parser->flags & P11_PARSE_FLAG_ANCHOR) ? CKT_NETSCAPE_TRUSTED_DELEGATOR : CKT_NETSCAPE_TRUSTED },
+               { "reject", CKT_NETSCAPE_UNTRUSTED },
+               { NULL, }
+       };
+
+       /* Various accept/reject usages */
+       for (i = 0; trust_fields[i].field != NULL; i++) {
+               for (j = 1; ; j++) {
+                       if (snprintf (field, sizeof (field), "%s.?%u", trust_fields[i].field, j) < 0)
+                               return_val_if_reached (NULL);
+                       len = sizeof (oid) - 1;
+                       ret = asn1_read_value (aux, field, oid, &len);
+
+                       /* No more extensions */
+                       if (ret == ASN1_ELEMENT_NOT_FOUND)
+                               break;
+
+                       /* A really, really long extension oid, not interested */
+                       else if (ret == ASN1_MEM_ERROR)
+                               continue;
+
+                       return_val_if_fail (ret == ASN1_SUCCESS, NULL);
+                       trust = trust_fields[i].trust;
+
+                       if (strcmp (oid, P11_EKU_SERVER_AUTH) == 0)
+                               vserver_auth = trust;
+                       else if (strcmp (oid, P11_EKU_CLIENT_AUTH) == 0)
+                               vclient_auth = trust;
+                       else if (strcmp (oid, P11_EKU_CODE_SIGNING) == 0)
+                               vcode_signing = trust;
+                       else if (strcmp (oid, P11_EKU_EMAIL) == 0)
+                               vemail_protection = trust;
+                       else if (strcmp (oid, P11_EKU_IPSEC_END_SYSTEM) == 0)
+                               vipsec_end_system = trust;
+                       else if (strcmp (oid, P11_EKU_IPSEC_TUNNEL) == 0)
+                               vipsec_tunnel = trust;
+                       else if (strcmp (oid, P11_EKU_IPSEC_USER) == 0)
+                               vipsec_user = trust;
+                       else if (strcmp (oid, P11_EKU_TIME_STAMPING) == 0)
+                               vtime_stamping = trust;
+               }
+       }
+
+       return p11_attrs_build (attrs, &server_auth, &client_auth, &code_signing,
+                               &email_protection, &ipsec_end_system, &ipsec_tunnel,
+                               &ipsec_user, &time_stamping, NULL);
 }
 
 static int
-parse_der_x509_certificate (p11_parser *parser,
-                            const unsigned char *data,
-                            size_t length)
+parse_openssl_trusted_certificate (p11_parser *parser,
+                                   const unsigned char *data,
+                                   size_t length)
 {
+       CK_ATTRIBUTE *attrs;
        CK_BYTE vid[ID_LENGTH];
+       const char *old_label = NULL;
+       char *label = NULL;
        node_asn *cert;
+       node_asn *aux;
+       ssize_t cert_len;
+       int len;
        int ret;
 
-       cert = decode_asn1 (parser, "PKIX1.Certificate", data, length, NULL);
+       /*
+        * This OpenSSL format is a wierd. It's just two DER structures
+        * placed end to end without any wrapping SEQ. So calculate the
+        * length of the first DER TLV we see and try to parse that as
+        * the X.509 certificate.
+        */
+
+       cert_len = calc_der_length (data, length);
+       if (cert_len <= 0)
+               return P11_PARSE_UNRECOGNIZED;
+
+       cert = decode_asn1 (parser, "PKIX1.Certificate", data, cert_len, NULL);
        if (cert == NULL)
                return P11_PARSE_UNRECOGNIZED;
 
+       aux = decode_asn1 (parser, "OPENSSL.CertAux", data + cert_len, length - cert_len, NULL);
+       if (aux == NULL) {
+               asn1_delete_structure (&cert);
+               return P11_PARSE_UNRECOGNIZED;
+       }
+
+       /* Pull the label out of the CertAux */
+       len = 0;
+       ret = asn1_read_value (aux, "alias", NULL, &len);
+       if (ret != ASN1_ELEMENT_NOT_FOUND) {
+               return_val_if_fail (ret == ASN1_MEM_ERROR, P11_PARSE_FAILURE);
+               label = calloc (len + 1, 1);
+               return_val_if_fail (label != NULL, P11_PARSE_FAILURE);
+               ret = asn1_read_value (aux, "alias", label, &len);
+               return_val_if_fail (ret == ASN1_SUCCESS, P11_PARSE_FAILURE);
+
+               old_label = parser->probable_label;
+               parser->probable_label = label;
+       }
+
        /* The CKA_ID links related objects */
        id_generate (parser, vid);
 
-       ret = sink_x509_certificate (parser, vid, cert, data, length);
-       return_val_if_fail (ret == P11_PARSE_SUCCESS, ret);
+       attrs = build_x509_certificate (parser, vid, cert, data, cert_len);
+       return_val_if_fail (attrs != NULL, P11_PARSE_FAILURE);
+       sink_object (parser, attrs);
 
-       ret = sink_nss_trust_object (parser, vid, cert, data, length);
-       return_val_if_fail (ret == P11_PARSE_SUCCESS, ret);
+       attrs = build_nss_trust_object (parser, vid, cert, data, cert_len);
+       return_val_if_fail (attrs != NULL, P11_PARSE_FAILURE);
+       attrs = overlay_cert_aux_on_nss_trust_object (parser, attrs, aux);
+       return_val_if_fail (attrs != NULL, P11_PARSE_FAILURE);
+       sink_object (parser, attrs);
 
        asn1_delete_structure (&cert);
+       asn1_delete_structure (&aux);
+
+       if (label) {
+               parser->probable_label = old_label;
+               free (label);
+       }
+
        return P11_PARSE_SUCCESS;
 }
 
@@ -1005,6 +1164,9 @@ on_pem_block (const char *type,
        if (strcmp (type, "CERTIFICATE") == 0) {
                ret = parse_der_x509_certificate (parser, contents, length);
 
+       } else if (strcmp (type, "TRUSTED CERTIFICATE") == 0) {
+               ret = parse_openssl_trusted_certificate (parser, contents, length);
+
        } else {
                p11_debug ("Saw unsupported or unrecognized PEM block of type %s", type);
                ret = P11_PARSE_SUCCESS;
@@ -1039,22 +1201,24 @@ p11_parser *
 p11_parser_new (void)
 {
        char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = { 0, };
-       node_asn *definitions = NULL;
-       p11_parser *parser;
+       p11_parser parser = { 0, };
        int ret;
 
-       ret = asn1_array2tree (pkix_asn1_tab, &definitions, message);
+       ret = asn1_array2tree (pkix_asn1_tab, &parser.pkix_definitions, message);
        if (ret != ASN1_SUCCESS) {
                p11_debug_precond ("failed to load pkix_asn1_tab in %s: %d %s",
                                   __func__, ret, message);
                return NULL;
        }
 
-       parser = calloc (1, sizeof (p11_parser));
-       return_val_if_fail (parser != NULL, NULL);
+       ret = asn1_array2tree (openssl_asn1_tab, &parser.openssl_definitions, message);
+       if (ret != ASN1_SUCCESS) {
+               p11_debug_precond ("failed to load openssl_asn1_tab in %s: %d %s",
+                                  __func__, ret, message);
+               return NULL;
+       }
 
-       parser->pkix_definitions = definitions;
-       return parser;
+       return memdup (&parser, sizeof (parser));
 }
 
 void
diff --git a/trust/tests/files/cacert3-trusted.pem b/trust/tests/files/cacert3-trusted.pem
new file mode 100644 (file)
index 0000000..c767eff
--- /dev/null
@@ -0,0 +1,43 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIIHWTCCBUGgAwIBAgIDCkGKMA0GCSqGSIb3DQEBCwUAMHkxEDAOBgNVBAoTB1Jv
+b3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZ
+Q0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9y
+dEBjYWNlcnQub3JnMB4XDTExMDUyMzE3NDgwMloXDTIxMDUyMDE3NDgwMlowVDEU
+MBIGA1UEChMLQ0FjZXJ0IEluYy4xHjAcBgNVBAsTFWh0dHA6Ly93d3cuQ0FjZXJ0
+Lm9yZzEcMBoGA1UEAxMTQ0FjZXJ0IENsYXNzIDMgUm9vdDCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBAKtJNRFIfNImflOUz0Op3SjXQiqL84d4GVh8D57a
+iX3h++tykA10oZZkq5+gJJlz2uJVdscXe/UErEa4w75/ZI0QbCTzYZzA8pD6Ueb1
+aQFjww9W4kpCz+JEjCUoqMV5CX1GuYrz6fM0KQhF5Byfy5QEHIGoFLOYZcRD7E6C
+jQnRvapbjZLQ7N6QxX8KwuPr5jFaXnQ+lzNZ6MMDPWAzv/fRb0fEze5ig1JuLgia
+pNkVGJGmhZJHsK5I6223IeyFGmhyNav/8BBdwPSUp2rVO5J+TJAFfpPBLIukjmJ0
+FXFuC3ED6q8VOJrU0gVyb4z5K+taciX5OUbjchs+BMNkJyIQKopPWKcDrb60LhPt
+XapI19V91Cp7XPpGBFDkzA5CW4zt2/LP/JaT4NsRNlRiNDiPDGCbO5dWOK3z0luL
+oFvqTpa4fNfVoIZwQNORKbeiPK31jLvPGpKK5DR7wNhsX+kKwsOnIJpa3yxdUly6
+R9Wb7yQocDggL9V/KcCyQQNokszgnMyXS0XvOhAKq3A6mJVwrTWx6oUrpByAITGp
+rmB6gCZIALgBwJNjVSKRPFbnr9s6JfOPMVTqJouBWfmh0VMRxXudA/Z0EeBtsSw/
+LIaRmXGapneLNGDRFLQsrJ2vjBDTn8Rq+G8T/HNZ92ZCdB6K4/jc0m+YnMtHmJVA
+BfvpAgMBAAGjggINMIICCTAdBgNVHQ4EFgQUdahxYEyIE/B42Yl3tW3Fid+8sXow
+gaMGA1UdIwSBmzCBmIAUFrUyG9TH8+DmjvO90rA67rI5GNGhfaR7MHkxEDAOBgNV
+BAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAG
+A1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYS
+c3VwcG9ydEBjYWNlcnQub3JnggEAMA8GA1UdEwEB/wQFMAMBAf8wXQYIKwYBBQUH
+AQEEUTBPMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5DQWNlcnQub3JnLzAoBggr
+BgEFBQcwAoYcaHR0cDovL3d3dy5DQWNlcnQub3JnL2NhLmNydDBKBgNVHSAEQzBB
+MD8GCCsGAQQBgZBKMDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuQ0FjZXJ0Lm9y
+Zy9pbmRleC5waHA/aWQ9MTAwNAYJYIZIAYb4QgEIBCcWJWh0dHA6Ly93d3cuQ0Fj
+ZXJ0Lm9yZy9pbmRleC5waHA/aWQ9MTAwUAYJYIZIAYb4QgENBEMWQVRvIGdldCB5
+b3VyIG93biBjZXJ0aWZpY2F0ZSBmb3IgRlJFRSwgZ28gdG8gaHR0cDovL3d3dy5D
+QWNlcnQub3JnMA0GCSqGSIb3DQEBCwUAA4ICAQApKIWuRKm5r6R5E/CooyuXYPNc
+7uMvwfbiZqARrjY3OnYVBFPqQvX56sAV2KaC2eRhrnILKVyQQ+hBsuF32wITRHhH
+Va9Y/MyY9kW50SD42CEH/m2qc9SzxgfpCYXMO/K2viwcJdVxjDm1Luq+GIG6sJO4
+D+Pm1yaMMVpyA4RS5qb1MyJFCsgLDYq4Nm+QCaGrvdfVTi5xotSu+qdUK+s1jVq3
+VIgv7nSf7UgWyg1I0JTTrKSi9iTfkuO960NAkW4cGI5WtIIS86mTn9S8nK2cde5a
+lxuV53QtHA+wLJef+6kzOXrnAzqSjiL2jA3k2X4Ndhj3AfnvlpaiVXPAPHG0HRpW
+Q7fDCo1y/OIQCQtBzoyUoPkD/XFzS4pXM+WOdH4VAQDmzEoc53+VGS3FpQyLu7Xt
+hbNc09+4ufLKxw0BFKxwWMWMjTPUnWajGlCVI/xI4AZDEtnNp4Y5LzZyo4AQ5OHz
+0ctbGsDkgJp8E3MGT9ujayQKurMcvEp4u+XjdTilSKeiHq921F73OIZWWonO1sOn
+ebJSoMbxhbQljPI/lrMQ2Y1sVzufb4Y6GIIiNsiwkTjbKqGTqoQ/9SdlrnPVyNXT
+d+pLncdBu8fA46A/5H2kjXPmEkvfoXNzczqA6NXLji/L6hOn1kGLrPo8idck9U60
+4GGSt/M3mMS+lqO3ijAwMBQGCCsGAQUFBwMCBggrBgEFBQcDAaAKBggrBgEFBQcD
+BAwMQ3VzdG9tIExhYmVs
+-----END TRUSTED CERTIFICATE-----
index 0a0a9d12acea82e295de385aef7937e71601fbca..d402fe8b18141dd18080e158782a716231a50f61 100644 (file)
@@ -44,6 +44,7 @@
 #include "debug.h"
 #include "library.h"
 #include "parser.h"
+#include "pkcs11x.h"
 #include "test-data.h"
 
 struct {
@@ -131,6 +132,56 @@ test_parse_pem_certificate (CuTest *cu)
        teardown (cu);
 }
 
+static void
+test_parse_openssl_trusted (CuTest *cu)
+{
+       CK_TRUST trusted = CKT_NETSCAPE_TRUSTED;
+       CK_TRUST distrusted = CKT_NETSCAPE_UNTRUSTED;
+       CK_TRUST unknown = CKT_NETSCAPE_TRUST_UNKNOWN;
+
+       CK_ATTRIBUTE expected[] = {
+               { CKA_LABEL, "Custom Label", 12 },
+               { CKA_CERT_SHA1_HASH, "\xad\x7c\x3f\x64\xfc\x44\x39\xfe\xf4\xe9\x0b\xe8\xf4\x7c\x6c\xfa\x8a\xad\xfd\xce", 20 },
+               { CKA_CERT_MD5_HASH, "\xf7\x25\x12\x82\x4e\x67\xb5\xd0\x8d\x92\xb7\x7c\x0b\x86\x7a\x42", 16 },
+               { CKA_ISSUER, (void *)test_cacert3_ca_issuer, sizeof (test_cacert3_ca_issuer) },
+               { CKA_SUBJECT, (void *)test_cacert3_ca_subject, sizeof (test_cacert3_ca_subject) },
+               { CKA_SERIAL_NUMBER, (void *)test_cacert3_ca_serial, sizeof (test_cacert3_ca_serial) },
+               { CKA_TRUST_SERVER_AUTH, &trusted, sizeof (trusted) },
+               { CKA_TRUST_CLIENT_AUTH, &trusted, sizeof (trusted) },
+               { CKA_TRUST_EMAIL_PROTECTION, &distrusted, sizeof (distrusted) },
+               { CKA_TRUST_CODE_SIGNING, &unknown, sizeof (unknown) },
+               { CKA_TRUST_IPSEC_END_SYSTEM, &unknown, sizeof (unknown) },
+               { CKA_TRUST_IPSEC_TUNNEL, &unknown, sizeof (unknown) },
+               { CKA_TRUST_IPSEC_USER, &unknown, sizeof (unknown) },
+               { CKA_TRUST_TIME_STAMPING, &unknown, sizeof (unknown) },
+               { CKA_INVALID, }
+       };
+
+       CK_ATTRIBUTE *attrs;
+       CK_ATTRIBUTE *attr;
+       int ret;
+
+       setup (cu);
+
+       ret = p11_parse_file (test.parser, SRCDIR "/files/cacert3-trusted.pem",
+                             0, on_parse_object, cu);
+       CuAssertIntEquals (cu, P11_PARSE_SUCCESS, ret);
+
+       /* Should have gotten certificate and a trust object */
+       CuAssertIntEquals (cu, 2, test.objects->num);
+
+       attrs = test.objects->elem[0];
+       test_check_cacert3_ca (cu, attrs, NULL);
+
+       attr = p11_attrs_find (attrs, CKA_TRUSTED);
+       CuAssertPtrEquals (cu, NULL, attr);
+
+       attrs = test.objects->elem[1];
+       CuAssertTrue (cu, p11_attrs_match (attrs, expected));
+
+       teardown (cu);
+}
+
 static void
 test_parse_anchor (CuTest *cu)
 {
@@ -320,6 +371,7 @@ main (void)
 
        SUITE_ADD_TEST (suite, test_parse_der_certificate);
        SUITE_ADD_TEST (suite, test_parse_pem_certificate);
+       SUITE_ADD_TEST (suite, test_parse_openssl_trusted);
        SUITE_ADD_TEST (suite, test_parse_anchor);
        SUITE_ADD_TEST (suite, test_parse_no_sink);
        SUITE_ADD_TEST (suite, test_parse_invalid_file);