From c2dcd0b3cb1ccac4eff98044d43d3f8696094644 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Mon, 17 Dec 2012 12:51:53 +0100 Subject: Add support for openssl TRUSTED CERTIFICATE PEM files --- build/certs/Makefile.am | 3 + common/Makefile.am | 2 + common/openssl.asn | 28 ++++ common/openssl.asn.h | 28 ++++ doc/p11-kit-trust.xml | 8 ++ trust/parser.c | 244 ++++++++++++++++++++++++++++------ trust/tests/files/cacert3-trusted.pem | 43 ++++++ trust/tests/test-parser.c | 52 ++++++++ 8 files changed, 368 insertions(+), 40 deletions(-) create mode 100644 common/openssl.asn create mode 100644 common/openssl.asn.h create mode 100644 trust/tests/files/cacert3-trusted.pem diff --git a/build/certs/Makefile.am b/build/certs/Makefile.am index b0439a4..f8ec1c2 100644 --- a/build/certs/Makefile.am +++ b/build/certs/Makefile.am @@ -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 diff --git a/common/Makefile.am b/common/Makefile.am index 00c043b..d527e95 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -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 index 0000000..c1f452b --- /dev/null +++ b/common/openssl.asn @@ -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 index 0000000..4e6b240 --- /dev/null +++ b/common/openssl.asn.h @@ -0,0 +1,28 @@ +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +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 } +}; diff --git a/doc/p11-kit-trust.xml b/doc/p11-kit-trust.xml index 7496f7b..036b422 100644 --- a/doc/p11-kit-trust.xml +++ b/doc/p11-kit-trust.xml @@ -47,6 +47,14 @@ $ pkg-config --variable p11_system_certificates p11-kit-1 X.509 certificates X.509 certificates in raw DER format. + + OpenSSL trust certificates + OpenSSL specific certificates in PEM format + that contain trust information. These have a + TRUSTED CERTIFICATE PEM header. Both + trust policy and blacklist information can be loaded + from these files. + diff --git a/trust/parser.c b/trust/parser.c index 65d7855..25af902 100644 --- a/trust/parser.c +++ b/trust/parser.c @@ -58,10 +58,12 @@ #include #include +#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 index 0000000..c767eff --- /dev/null +++ b/trust/tests/files/cacert3-trusted.pem @@ -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----- diff --git a/trust/tests/test-parser.c b/trust/tests/test-parser.c index 0a0a9d1..d402fe8 100644 --- a/trust/tests/test-parser.c +++ b/trust/tests/test-parser.c @@ -44,6 +44,7 @@ #include "debug.h" #include "library.h" #include "parser.h" +#include "pkcs11x.h" #include "test-data.h" struct { @@ -132,6 +133,56 @@ test_parse_pem_certificate (CuTest *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) { CK_ATTRIBUTE *attrs; @@ -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); -- cgit v1.1