From b693517966b1cbe5b81e39aeefad7b52b6f10492 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Wed, 28 Aug 2013 10:37:44 +0200 Subject: trust: Refactor enumeration of certificates to extract Because we want to use this same logic for listing trust --- trust/Makefile.am | 2 +- trust/enumerate.c | 646 +++++++++++++++++++++++++++++++++++++++++++ trust/enumerate.h | 103 +++++++ trust/extract-cer.c | 18 +- trust/extract-info.c | 510 ---------------------------------- trust/extract-jks.c | 13 +- trust/extract-openssl.c | 36 +-- trust/extract-pem.c | 20 +- trust/extract.c | 180 +----------- trust/extract.h | 84 ++---- trust/tests/Makefile.am | 14 +- trust/tests/test-bundle.c | 62 ++--- trust/tests/test-cer.c | 62 ++--- trust/tests/test-enumerate.c | 492 ++++++++++++++++++++++++++++++++ trust/tests/test-extract.c | 507 --------------------------------- trust/tests/test-openssl.c | 111 ++++---- 16 files changed, 1429 insertions(+), 1431 deletions(-) create mode 100644 trust/enumerate.c create mode 100644 trust/enumerate.h delete mode 100644 trust/extract-info.c create mode 100644 trust/tests/test-enumerate.c delete mode 100644 trust/tests/test-extract.c (limited to 'trust') diff --git a/trust/Makefile.am b/trust/Makefile.am index ca7e2d7..87e9899 100644 --- a/trust/Makefile.am +++ b/trust/Makefile.am @@ -97,8 +97,8 @@ trust_SOURCES = \ parser.c parser.h \ persist.c persist.h \ digest.c digest.h \ + enumerate.c enumerate.h \ extract.c extract.h \ - extract-info.c \ extract-jks.c \ extract-openssl.c \ extract-pem.c \ diff --git a/trust/enumerate.c b/trust/enumerate.c new file mode 100644 index 0000000..8743ed6 --- /dev/null +++ b/trust/enumerate.c @@ -0,0 +1,646 @@ +/* + * Copyright (c) 2013, Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * The names of contributors to this software may not be + * used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Author: Stef Walter + */ + +#include "config.h" + +#define P11_DEBUG_FLAG P11_DEBUG_TOOL + +#include "attrs.h" +#include "debug.h" +#include "oid.h" +#include "dict.h" +#include "extract.h" +#include "message.h" +#include "path.h" +#include "pkcs11.h" +#include "pkcs11x.h" +#include "x509.h" + +#include +#include + +static bool +load_stapled_extension (p11_dict *stapled, + p11_dict *asn1_defs, + const unsigned char *der, + size_t len) +{ + char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; + node_asn *ext; + char *oid; + int length; + int start; + int end; + int ret; + + ext = p11_asn1_decode (asn1_defs, "PKIX1.Extension", der, len, message); + if (ext == NULL) { + p11_message ("couldn't parse stapled certificate extension: %s", message); + return false; + } + + ret = asn1_der_decoding_startEnd (ext, der, len, "extnID", &start, &end); + return_val_if_fail (ret == ASN1_SUCCESS, false); + + /* Make sure it's a straightforward oid with certain assumptions */ + length = (end - start) + 1; + if (!p11_oid_simple (der + start, length)) { + p11_debug ("strange complex certificate extension object id"); + return false; + } + + oid = memdup (der + start, length); + return_val_if_fail (oid != NULL, false); + + if (!p11_dict_set (stapled, oid, ext)) + return_val_if_reached (false); + + return true; +} + +static p11_dict * +load_stapled_extensions (p11_enumerate *ex, + CK_ATTRIBUTE *spki) +{ + CK_OBJECT_CLASS extension = CKO_X_CERTIFICATE_EXTENSION; + CK_ATTRIBUTE *attrs; + P11KitIter *iter; + CK_RV rv = CKR_OK; + p11_dict *stapled; + + CK_ATTRIBUTE match[] = { + { CKA_CLASS, &extension, sizeof (extension) }, + { CKA_X_PUBLIC_KEY_INFO, spki->pValue, spki->ulValueLen }, + }; + + CK_ATTRIBUTE template[] = { + { CKA_VALUE, }, + }; + + stapled = p11_dict_new (p11_oid_hash, p11_oid_equal, + free, p11_asn1_free); + + /* No ID to use, just short circuit */ + if (!spki->pValue || !spki->ulValueLen) + return stapled; + + iter = p11_kit_iter_new (NULL, 0); + p11_kit_iter_add_filter (iter, match, 2); + p11_kit_iter_begin_with (iter, p11_kit_iter_get_module (ex->iter), + 0, p11_kit_iter_get_session (ex->iter)); + + while (rv == CKR_OK) { + rv = p11_kit_iter_next (iter); + if (rv == CKR_OK) { + attrs = p11_attrs_buildn (NULL, template, 1); + rv = p11_kit_iter_load_attributes (iter, attrs, 1); + if (rv == CKR_OK) { + if (!load_stapled_extension (stapled, ex->asn1_defs, + attrs[0].pValue, + attrs[0].ulValueLen)) { + rv = CKR_GENERAL_ERROR; + } + } + p11_attrs_free (attrs); + } + } + + if (rv != CKR_OK && rv != CKR_CANCEL) { + p11_message ("couldn't load stapled extensions for certificate: %s", p11_kit_strerror (rv)); + p11_dict_free (stapled); + stapled = NULL; + } + + p11_kit_iter_free (iter); + return stapled; +} + +static bool +extract_purposes (p11_enumerate *ex) +{ + node_asn *ext = NULL; + unsigned char *value = NULL; + size_t length; + + if (ex->stapled) { + ext = p11_dict_get (ex->stapled, P11_OID_EXTENDED_KEY_USAGE); + if (ext != NULL) { + value = p11_asn1_read (ext, "extnValue", &length); + return_val_if_fail (value != NULL, false); + } + } + + if (value == NULL && ex->cert_asn) { + value = p11_x509_find_extension (ex->cert_asn, P11_OID_EXTENDED_KEY_USAGE, + ex->cert_der, ex->cert_len, &length); + } + + /* No such extension, match anything */ + if (value == NULL) + return true; + + ex->purposes = p11_x509_parse_extended_key_usage (ex->asn1_defs, value, length); + + free (value); + return ex->purposes != NULL; +} + +static bool +check_blacklisted (P11KitIter *iter, + CK_ATTRIBUTE *cert) +{ + CK_OBJECT_HANDLE dummy; + CK_FUNCTION_LIST *module; + CK_SESSION_HANDLE session; + CK_BBOOL distrusted = CK_TRUE; + CK_ULONG have; + CK_RV rv; + + CK_ATTRIBUTE match[] = { + { CKA_VALUE, cert->pValue, cert->ulValueLen }, + { CKA_X_DISTRUSTED, &distrusted, sizeof (distrusted) }, + }; + + module = p11_kit_iter_get_module (iter); + session = p11_kit_iter_get_session (iter); + + rv = (module->C_FindObjectsInit) (session, match, 2); + if (rv == CKR_OK) { + rv = (module->C_FindObjects) (session, &dummy, 1, &have); + (module->C_FindObjectsFinal) (session); + } + + if (rv != CKR_OK) { + p11_message ("couldn't check if certificate is on blacklist"); + return true; + } + + if (have == 0) { + p11_debug ("anchor is not on blacklist"); + return false; + } else { + p11_debug ("anchor is on blacklist"); + return true; + } +} + +static bool +check_trust_flags (p11_enumerate *ex, + CK_ATTRIBUTE *cert) +{ + CK_BBOOL trusted; + CK_BBOOL distrusted; + int flags = 0; + + /* If no extract trust flags, then just continue */ + if (!(ex->flags & (P11_ENUMERATE_ANCHORS | P11_ENUMERATE_BLACKLIST))) + return true; + + if (p11_attrs_find_bool (ex->attrs, CKA_TRUSTED, &trusted) && + trusted && !check_blacklisted (ex->iter, cert)) { + flags |= P11_ENUMERATE_ANCHORS; + } + + if (p11_attrs_find_bool (ex->attrs, CKA_X_DISTRUSTED, &distrusted) && + distrusted) { + flags |= P11_ENUMERATE_BLACKLIST; + } + + /* Any of the flags can match */ + if (flags & ex->flags) + return true; + + return false; +} + +static bool +extract_certificate (p11_enumerate *ex) +{ + char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; + CK_ATTRIBUTE *attr; + + CK_ULONG type; + + /* Don't even bother with not X.509 certificates */ + if (!p11_attrs_find_ulong (ex->attrs, CKA_CERTIFICATE_TYPE, &type)) + type = (CK_ULONG)-1; + if (type != CKC_X_509) { + p11_debug ("skipping non X.509 certificate"); + return false; + } + + attr = p11_attrs_find_valid (ex->attrs, CKA_VALUE); + if (!attr || !attr->pValue) { + p11_debug ("skipping certificate without a value"); + return false; + } + + /* + * If collapsing and have already seen this certificate, and shouldn't + * process it even again during this extract procedure. + */ + if (ex->flags & P11_ENUMERATE_COLLAPSE) { + if (!ex->already_seen) { + ex->already_seen = p11_dict_new (p11_attr_hash, p11_attr_equal, + p11_attrs_free, NULL); + return_val_if_fail (ex->already_seen != NULL, true); + } + + if (p11_dict_get (ex->already_seen, attr)) + return false; + } + + if (!check_trust_flags (ex, attr)) { + p11_debug ("skipping certificate that doesn't match trust flags"); + return false; + } + + if (ex->already_seen) { + if (!p11_dict_set (ex->already_seen, + p11_attrs_build (NULL, attr, NULL), "x")) + return_val_if_reached (true); + } + + ex->cert_der = attr->pValue; + ex->cert_len = attr->ulValueLen; + ex->cert_asn = p11_asn1_decode (ex->asn1_defs, "PKIX1.Certificate", + ex->cert_der, ex->cert_len, message); + + if (!ex->cert_asn) { + p11_message ("couldn't parse certificate: %s", message); + return false; + } + + return true; +} + +static bool +extract_info (p11_enumerate *ex) +{ + CK_ATTRIBUTE *attr; + CK_RV rv; + + static const CK_ATTRIBUTE attr_types[] = { + { CKA_ID, }, + { CKA_CLASS, }, + { CKA_CERTIFICATE_TYPE, }, + { CKA_LABEL, }, + { CKA_VALUE, }, + { CKA_SUBJECT, }, + { CKA_ISSUER, }, + { CKA_TRUSTED, }, + { CKA_CERTIFICATE_CATEGORY }, + { CKA_X_DISTRUSTED }, + { CKA_X_PUBLIC_KEY_INFO }, + { CKA_INVALID, }, + }; + + ex->attrs = p11_attrs_dup (attr_types); + rv = p11_kit_iter_load_attributes (ex->iter, ex->attrs, p11_attrs_count (ex->attrs)); + + /* The attributes couldn't be loaded */ + if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID && rv != CKR_ATTRIBUTE_SENSITIVE) { + p11_message ("couldn't load attributes: %s", p11_kit_strerror (rv)); + return false; + } + + /* No class attribute, very strange, just skip */ + if (!p11_attrs_find_ulong (ex->attrs, CKA_CLASS, &ex->klass)) + return false; + + /* If a certificate then */ + if (ex->klass != CKO_CERTIFICATE) { + p11_message ("skipping non-certificate object"); + return false; + } + + if (!extract_certificate (ex)) + return false; + + attr = p11_attrs_find_valid (ex->attrs, CKA_X_PUBLIC_KEY_INFO); + if (attr) { + ex->stapled = load_stapled_extensions (ex, attr); + if (!ex->stapled) + return false; + } + + if (!extract_purposes (ex)) + return false; + + return true; +} + +static void +extract_clear (p11_enumerate *ex) +{ + ex->klass = (CK_ULONG)-1; + + p11_attrs_free (ex->attrs); + ex->attrs = NULL; + + asn1_delete_structure (&ex->cert_asn); + ex->cert_der = NULL; + ex->cert_len = 0; + + p11_dict_free (ex->stapled); + ex->stapled = NULL; + + p11_array_free (ex->purposes); + ex->purposes = NULL; +} + +static CK_RV +on_iterate_load_filter (p11_kit_iter *iter, + CK_BBOOL *matches, + void *data) +{ + p11_enumerate *ex = data; + int i; + + extract_clear (ex); + + /* Try to load the certificate and extensions */ + if (!extract_info (ex)) { + *matches = CK_FALSE; + return CKR_OK; + } + + /* + * Limit to certain purposes. Note that the lack of purposes noted + * on the certificate means they match any purpose. This is the + * behavior of the ExtendedKeyUsage extension. + */ + if (ex->limit_to_purposes && ex->purposes) { + *matches = CK_FALSE; + for (i = 0; i < ex->purposes->num; i++) { + if (p11_dict_get (ex->limit_to_purposes, ex->purposes->elem[i])) { + *matches = CK_TRUE; + break; + } + } + } + + return CKR_OK; +} + +void +p11_enumerate_init (p11_enumerate *ex) +{ + memset (ex, 0, sizeof (p11_enumerate)); + ex->asn1_defs = p11_asn1_defs_load (); + return_if_fail (ex->asn1_defs != NULL); + + ex->iter = p11_kit_iter_new (NULL, 0); + return_if_fail (ex->iter != NULL); + + p11_kit_iter_add_callback (ex->iter, on_iterate_load_filter, ex, NULL); +} + +void +p11_enumerate_cleanup (p11_enumerate *ex) +{ + extract_clear (ex); + + p11_dict_free (ex->limit_to_purposes); + ex->limit_to_purposes = NULL; + + p11_dict_free (ex->already_seen); + ex->already_seen = NULL; + + p11_dict_free (ex->asn1_defs); + ex->asn1_defs = NULL; + + p11_kit_iter_free (ex->iter); + ex->iter = NULL; + + if (ex->modules) { + p11_kit_modules_finalize_and_release (ex->modules); + ex->modules = NULL; + } + + if (ex->uri) { + p11_kit_uri_free (ex->uri); + ex->uri = NULL; + } +} + +bool +p11_enumerate_opt_filter (p11_enumerate *ex, + const char *option) +{ + CK_ATTRIBUTE *attrs; + int ret; + + CK_OBJECT_CLASS vcertificate = CKO_CERTIFICATE; + CK_ULONG vauthority = 2; + CK_CERTIFICATE_TYPE vx509 = CKC_X_509; + + CK_ATTRIBUTE certificate = { CKA_CLASS, &vcertificate, sizeof (vcertificate) }; + CK_ATTRIBUTE authority = { CKA_CERTIFICATE_CATEGORY, &vauthority, sizeof (vauthority) }; + CK_ATTRIBUTE x509= { CKA_CERTIFICATE_TYPE, &vx509, sizeof (vx509) }; + + if (strncmp (option, "pkcs11:", 7) == 0) { + if (ex->uri != NULL) { + p11_message ("a PKCS#11 URI has already been specified"); + return false; + } + + ex->uri = p11_kit_uri_new (); + ret = p11_kit_uri_parse (option, P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE, ex->uri); + if (ret != P11_KIT_URI_OK) { + p11_message ("couldn't parse pkcs11 uri filter: %s", option); + return false; + } + + if (p11_kit_uri_any_unrecognized (ex->uri)) + p11_message ("uri contained unrecognized components, nothing will be extracted"); + + p11_kit_iter_set_uri (ex->iter, ex->uri); + ex->num_filters++; + return true; + } + + if (strcmp (option, "ca-anchors") == 0) { + attrs = p11_attrs_build (NULL, &certificate, &authority, &x509, NULL); + ex->flags |= P11_ENUMERATE_ANCHORS | P11_ENUMERATE_COLLAPSE; + + } else if (strcmp (option, "trust-policy") == 0) { + attrs = p11_attrs_build (NULL, &certificate, &x509, NULL); + ex->flags |= P11_ENUMERATE_ANCHORS | P11_ENUMERATE_BLACKLIST | P11_ENUMERATE_COLLAPSE; + + } else if (strcmp (option, "blacklist") == 0) { + attrs = p11_attrs_build (NULL, &certificate, &x509, NULL); + ex->flags |= P11_ENUMERATE_BLACKLIST | P11_ENUMERATE_COLLAPSE; + + } else if (strcmp (option, "certificates") == 0) { + attrs = p11_attrs_build (NULL, &certificate, &x509, NULL); + ex->flags |= P11_ENUMERATE_COLLAPSE; + + } else { + p11_message ("unsupported or unrecognized filter: %s", option); + return false; + } + + p11_kit_iter_add_filter (ex->iter, attrs, p11_attrs_count (attrs)); + ex->num_filters++; + return true; +} + +static int +is_valid_oid_rough (const char *string) +{ + size_t len; + + len = strlen (string); + + /* Rough check if a valid OID */ + return (strspn (string, "0123456789.") == len && + !strstr (string, "..") && string[0] != '\0' && string[0] != '.' && + string[len - 1] != '.'); +} + +bool +p11_enumerate_opt_purpose (p11_enumerate *ex, + const char *option) +{ + const char *oid; + char *value; + + if (strcmp (option, "server-auth") == 0) { + oid = P11_OID_SERVER_AUTH_STR; + } else if (strcmp (option, "client-auth") == 0) { + oid = P11_OID_CLIENT_AUTH_STR; + } else if (strcmp (option, "email-protection") == 0 || strcmp (option, "email") == 0) { + oid = P11_OID_EMAIL_PROTECTION_STR; + } else if (strcmp (option, "code-signing") == 0) { + oid = P11_OID_CODE_SIGNING_STR; + } else if (strcmp (option, "ipsec-end-system") == 0) { + oid = P11_OID_IPSEC_END_SYSTEM_STR; + } else if (strcmp (option, "ipsec-tunnel") == 0) { + oid = P11_OID_IPSEC_TUNNEL_STR; + } else if (strcmp (option, "ipsec-user") == 0) { + oid = P11_OID_IPSEC_USER_STR; + } else if (strcmp (option, "time-stamping") == 0) { + oid = P11_OID_TIME_STAMPING_STR; + } else if (is_valid_oid_rough (option)) { + oid = option; + } else { + p11_message ("unsupported or unregonized purpose: %s", option); + return false; + } + + if (!ex->limit_to_purposes) { + ex->limit_to_purposes = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, free, NULL); + return_val_if_fail (ex->limit_to_purposes != NULL, false); + } + + value = strdup (oid); + return_val_if_fail (value != NULL, false); + if (!p11_dict_set (ex->limit_to_purposes, value, value)) + return_val_if_reached (false); + + return true; +} + +bool +p11_enumerate_ready (p11_enumerate *ex, + const char *def_filter) +{ + if (ex->num_filters == 0) { + if (!p11_enumerate_opt_filter (ex, def_filter)) + return_val_if_reached (false); + } + + /* + * We only "believe" the CKA_TRUSTED and CKA_X_DISTRUSTED attributes + * we get from modules explicitly marked as containing trust-policy. + */ + ex->modules = p11_kit_modules_load_and_initialize (P11_KIT_MODULE_TRUSTED); + if (!ex->modules) + return false; + if (ex->modules[0] == NULL) + p11_message ("no modules containing trust policy are registered"); + + p11_kit_iter_begin (ex->iter, ex->modules); + return true; +} + +static char * +extract_label (p11_enumerate *ex) +{ + CK_ATTRIBUTE *attr; + + /* Look for a label and just use that */ + attr = p11_attrs_find_valid (ex->attrs, CKA_LABEL); + if (attr && attr->pValue && attr->ulValueLen) + return strndup (attr->pValue, attr->ulValueLen); + + /* For extracting certificates */ + if (ex->klass == CKO_CERTIFICATE) + return strdup ("certificate"); + + return strdup ("unknown"); +} + +char * +p11_enumerate_filename (p11_enumerate *ex) +{ + char *label; + + label = extract_label (ex); + return_val_if_fail (label != NULL, NULL); + + p11_path_canon (label); + return label; +} + +char * +p11_enumerate_comment (p11_enumerate *ex, + bool first) +{ + char *comment; + char *label; + + if (!(ex->flags & P11_EXTRACT_COMMENT)) + return NULL; + + label = extract_label (ex); + if (!asprintf (&comment, "%s# %s\n", + first ? "" : "\n", + label ? label : "")) + return_val_if_reached (NULL); + + free (label); + return comment; +} diff --git a/trust/enumerate.h b/trust/enumerate.h new file mode 100644 index 0000000..8b1e7e4 --- /dev/null +++ b/trust/enumerate.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2013, Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * The names of contributors to this software may not be + * used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Author: Stef Walter + */ + +#include "config.h" + +#ifndef P11_ENUMERATE_H_ +#define P11_ENUMERATE_H_ + +#include "array.h" +#include "asn1.h" +#include "dict.h" +#include "iter.h" +#include "pkcs11.h" + +enum { + /* These overlap with the flags in save.h, so start higher */ + P11_ENUMERATE_ANCHORS = 1 << 21, + P11_ENUMERATE_BLACKLIST = 1 << 22, + P11_ENUMERATE_COLLAPSE = 1 << 23, +}; + +typedef struct { + CK_FUNCTION_LIST **modules; + p11_kit_iter *iter; + p11_kit_uri *uri; + + p11_dict *asn1_defs; + p11_dict *limit_to_purposes; + p11_dict *already_seen; + int num_filters; + int flags; + + /* + * Stuff below is parsed info for the current iteration. + * Currently this information is generally all relevant + * just for certificates. + */ + + CK_OBJECT_CLASS klass; + CK_ATTRIBUTE *attrs; + + /* Pre-parsed data for certificates */ + node_asn *cert_asn; + const unsigned char *cert_der; + size_t cert_len; + + /* DER OID -> CK_ATTRIBUTE list */ + p11_dict *stapled; + + /* Set of OID purposes as strings */ + p11_array *purposes; +} p11_enumerate; + +char * p11_enumerate_filename (p11_enumerate *ex); + +char * p11_enumerate_comment (p11_enumerate *ex, + bool first); + +void p11_enumerate_init (p11_enumerate *ex); + +bool p11_enumerate_opt_filter (p11_enumerate *ex, + const char *option); + +bool p11_enumerate_opt_purpose (p11_enumerate *ex, + const char *option); + +bool p11_enumerate_ready (p11_enumerate *ex, + const char *def_filter); + +void p11_enumerate_cleanup (p11_enumerate *ex); + +#endif /* P11_ENUMERATE_H_ */ diff --git a/trust/extract-cer.c b/trust/extract-cer.c index 81a5bf6..b59be80 100644 --- a/trust/extract-cer.c +++ b/trust/extract-cer.c @@ -43,20 +43,20 @@ #include bool -p11_extract_x509_file (P11KitIter *iter, - p11_extract_info *ex) +p11_extract_x509_file (p11_enumerate *ex, + const char *destination) { bool found = false; p11_save_file *file; CK_RV rv; - while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { + while ((rv = p11_kit_iter_next (ex->iter)) == CKR_OK) { if (found) { p11_message ("multiple certificates found but could only write one to file"); break; } - file = p11_save_open_file (ex->destination, NULL, ex->flags); + file = p11_save_open_file (destination, NULL, ex->flags); if (!p11_save_write_and_finish (file, ex->cert_der, ex->cert_len)) return false; @@ -78,8 +78,8 @@ p11_extract_x509_file (P11KitIter *iter, } bool -p11_extract_x509_directory (P11KitIter *iter, - p11_extract_info *ex) +p11_extract_x509_directory (p11_enumerate *ex, + const char *destination) { p11_save_file *file; p11_save_dir *dir; @@ -87,12 +87,12 @@ p11_extract_x509_directory (P11KitIter *iter, CK_RV rv; bool ret; - dir = p11_save_open_directory (ex->destination, ex->flags); + dir = p11_save_open_directory (destination, ex->flags); if (dir == NULL) return false; - while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { - filename = p11_extract_info_filename (ex); + while ((rv = p11_kit_iter_next (ex->iter)) == CKR_OK) { + filename = p11_enumerate_filename (ex); return_val_if_fail (filename != NULL, -1); file = p11_save_open_file_in (dir, filename, ".cer"); diff --git a/trust/extract-info.c b/trust/extract-info.c deleted file mode 100644 index 8468abb..0000000 --- a/trust/extract-info.c +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Copyright (c) 2013, Red Hat Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the - * above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * * The names of contributors to this software may not be - * used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * Author: Stef Walter - */ - -#include "config.h" - -#define P11_DEBUG_FLAG P11_DEBUG_TOOL - -#include "attrs.h" -#include "debug.h" -#include "oid.h" -#include "dict.h" -#include "extract.h" -#include "message.h" -#include "path.h" -#include "pkcs11.h" -#include "pkcs11x.h" -#include "x509.h" - -#include -#include - -static bool -load_stapled_extension (p11_dict *stapled, - p11_dict *asn1_defs, - const unsigned char *der, - size_t len) -{ - char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - node_asn *ext; - char *oid; - int length; - int start; - int end; - int ret; - - ext = p11_asn1_decode (asn1_defs, "PKIX1.Extension", der, len, message); - if (ext == NULL) { - p11_message ("couldn't parse stapled certificate extension: %s", message); - return false; - } - - ret = asn1_der_decoding_startEnd (ext, der, len, "extnID", &start, &end); - return_val_if_fail (ret == ASN1_SUCCESS, false); - - /* Make sure it's a straightforward oid with certain assumptions */ - length = (end - start) + 1; - if (!p11_oid_simple (der + start, length)) { - p11_debug ("strange complex certificate extension object id"); - return false; - } - - oid = memdup (der + start, length); - return_val_if_fail (oid != NULL, false); - - if (!p11_dict_set (stapled, oid, ext)) - return_val_if_reached (false); - - return true; -} - -static p11_dict * -load_stapled_extensions (p11_extract_info *ex, - CK_FUNCTION_LIST_PTR module, - CK_SESSION_HANDLE session, - CK_ATTRIBUTE *spki) -{ - CK_OBJECT_CLASS extension = CKO_X_CERTIFICATE_EXTENSION; - CK_ATTRIBUTE *attrs; - P11KitIter *iter; - CK_RV rv = CKR_OK; - p11_dict *stapled; - - CK_ATTRIBUTE match[] = { - { CKA_CLASS, &extension, sizeof (extension) }, - { CKA_X_PUBLIC_KEY_INFO, spki->pValue, spki->ulValueLen }, - }; - - CK_ATTRIBUTE template[] = { - { CKA_VALUE, }, - }; - - stapled = p11_dict_new (p11_oid_hash, p11_oid_equal, - free, p11_asn1_free); - - /* No ID to use, just short circuit */ - if (!spki->pValue || !spki->ulValueLen) - return stapled; - - iter = p11_kit_iter_new (NULL, 0); - p11_kit_iter_add_filter (iter, match, 2); - p11_kit_iter_begin_with (iter, module, 0, session); - - while (rv == CKR_OK) { - rv = p11_kit_iter_next (iter); - if (rv == CKR_OK) { - attrs = p11_attrs_buildn (NULL, template, 1); - rv = p11_kit_iter_load_attributes (iter, attrs, 1); - if (rv == CKR_OK) { - if (!load_stapled_extension (stapled, ex->asn1_defs, - attrs[0].pValue, - attrs[0].ulValueLen)) { - rv = CKR_GENERAL_ERROR; - } - } - p11_attrs_free (attrs); - } - } - - if (rv != CKR_OK && rv != CKR_CANCEL) { - p11_message ("couldn't load stapled extensions for certificate: %s", p11_kit_strerror (rv)); - p11_dict_free (stapled); - stapled = NULL; - } - - p11_kit_iter_free (iter); - return stapled; -} - -static bool -extract_purposes (p11_extract_info *ex) -{ - node_asn *ext = NULL; - unsigned char *value = NULL; - size_t length; - - if (ex->stapled) { - ext = p11_dict_get (ex->stapled, P11_OID_EXTENDED_KEY_USAGE); - if (ext != NULL) { - value = p11_asn1_read (ext, "extnValue", &length); - return_val_if_fail (value != NULL, false); - } - } - - if (value == NULL && ex->cert_asn) { - value = p11_x509_find_extension (ex->cert_asn, P11_OID_EXTENDED_KEY_USAGE, - ex->cert_der, ex->cert_len, &length); - } - - /* No such extension, match anything */ - if (value == NULL) - return true; - - ex->purposes = p11_x509_parse_extended_key_usage (ex->asn1_defs, value, length); - - free (value); - return ex->purposes != NULL; -} - -static bool -check_blacklisted (P11KitIter *iter, - CK_ATTRIBUTE *cert) -{ - CK_OBJECT_HANDLE dummy; - CK_FUNCTION_LIST *module; - CK_SESSION_HANDLE session; - CK_BBOOL distrusted = CK_TRUE; - CK_ULONG have; - CK_RV rv; - - CK_ATTRIBUTE match[] = { - { CKA_VALUE, cert->pValue, cert->ulValueLen }, - { CKA_X_DISTRUSTED, &distrusted, sizeof (distrusted) }, - }; - - module = p11_kit_iter_get_module (iter); - session = p11_kit_iter_get_session (iter); - - rv = (module->C_FindObjectsInit) (session, match, 2); - if (rv == CKR_OK) { - rv = (module->C_FindObjects) (session, &dummy, 1, &have); - (module->C_FindObjectsFinal) (session); - } - - if (rv != CKR_OK) { - p11_message ("couldn't check if certificate is on blacklist"); - return true; - } - - if (have == 0) { - p11_debug ("anchor is not on blacklist"); - return false; - } else { - p11_debug ("anchor is on blacklist"); - return true; - } -} - -static bool -check_trust_flags (P11KitIter *iter, - p11_extract_info *ex, - CK_ATTRIBUTE *cert) -{ - CK_BBOOL trusted; - CK_BBOOL distrusted; - int flags = 0; - - /* If no extract trust flags, then just continue */ - if (!(ex->flags & (P11_EXTRACT_ANCHORS | P11_EXTRACT_BLACKLIST))) - return true; - - if (p11_attrs_find_bool (ex->attrs, CKA_TRUSTED, &trusted) && - trusted && !check_blacklisted (iter, cert)) { - flags |= P11_EXTRACT_ANCHORS; - } - - if (p11_attrs_find_bool (ex->attrs, CKA_X_DISTRUSTED, &distrusted) && - distrusted) { - flags |= P11_EXTRACT_BLACKLIST; - } - - /* Any of the flags can match */ - if (flags & ex->flags) - return true; - - return false; -} - -static bool -extract_certificate (P11KitIter *iter, - p11_extract_info *ex) -{ - char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - CK_ATTRIBUTE *attr; - - CK_ULONG type; - - /* Don't even bother with not X.509 certificates */ - if (!p11_attrs_find_ulong (ex->attrs, CKA_CERTIFICATE_TYPE, &type)) - type = (CK_ULONG)-1; - if (type != CKC_X_509) { - p11_debug ("skipping non X.509 certificate"); - return false; - } - - attr = p11_attrs_find_valid (ex->attrs, CKA_VALUE); - if (!attr || !attr->pValue) { - p11_debug ("skipping certificate without a value"); - return false; - } - - /* - * If collapsing and have already seen this certificate, and shouldn't - * process it even again during this extract procedure. - */ - if (ex->flags & P11_EXTRACT_COLLAPSE) { - if (!ex->already_seen) { - ex->already_seen = p11_dict_new (p11_attr_hash, p11_attr_equal, - p11_attrs_free, NULL); - return_val_if_fail (ex->already_seen != NULL, true); - } - - if (p11_dict_get (ex->already_seen, attr)) - return false; - } - - if (!check_trust_flags (iter, ex, attr)) { - p11_debug ("skipping certificate that doesn't match trust flags"); - return false; - } - - if (ex->already_seen) { - if (!p11_dict_set (ex->already_seen, - p11_attrs_build (NULL, attr, NULL), "x")) - return_val_if_reached (true); - } - - ex->cert_der = attr->pValue; - ex->cert_len = attr->ulValueLen; - ex->cert_asn = p11_asn1_decode (ex->asn1_defs, "PKIX1.Certificate", - ex->cert_der, ex->cert_len, message); - - if (!ex->cert_asn) { - p11_message ("couldn't parse certificate: %s", message); - return false; - } - - return true; -} - -static bool -extract_info (P11KitIter *iter, - p11_extract_info *ex) -{ - CK_ATTRIBUTE *attr; - CK_RV rv; - - static const CK_ATTRIBUTE attr_types[] = { - { CKA_ID, }, - { CKA_CLASS, }, - { CKA_CERTIFICATE_TYPE, }, - { CKA_LABEL, }, - { CKA_VALUE, }, - { CKA_SUBJECT, }, - { CKA_ISSUER, }, - { CKA_TRUSTED, }, - { CKA_CERTIFICATE_CATEGORY }, - { CKA_X_DISTRUSTED }, - { CKA_X_PUBLIC_KEY_INFO }, - { CKA_INVALID, }, - }; - - ex->attrs = p11_attrs_dup (attr_types); - rv = p11_kit_iter_load_attributes (iter, ex->attrs, p11_attrs_count (ex->attrs)); - - /* The attributes couldn't be loaded */ - if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID && rv != CKR_ATTRIBUTE_SENSITIVE) { - p11_message ("couldn't load attributes: %s", p11_kit_strerror (rv)); - return false; - } - - /* No class attribute, very strange, just skip */ - if (!p11_attrs_find_ulong (ex->attrs, CKA_CLASS, &ex->klass)) - return false; - - /* If a certificate then */ - if (ex->klass != CKO_CERTIFICATE) { - p11_message ("skipping non-certificate object"); - return false; - } - - if (!extract_certificate (iter, ex)) - return false; - - attr = p11_attrs_find_valid (ex->attrs, CKA_X_PUBLIC_KEY_INFO); - if (attr) { - ex->stapled = load_stapled_extensions (ex, p11_kit_iter_get_module (iter), - p11_kit_iter_get_session (iter), attr); - if (!ex->stapled) - return false; - } - - if (!extract_purposes (ex)) - return false; - - return true; -} - -static void -extract_clear (p11_extract_info *ex) -{ - ex->klass = (CK_ULONG)-1; - - p11_attrs_free (ex->attrs); - ex->attrs = NULL; - - asn1_delete_structure (&ex->cert_asn); - ex->cert_der = NULL; - ex->cert_len = 0; - - p11_dict_free (ex->stapled); - ex->stapled = NULL; - - p11_array_free (ex->purposes); - ex->purposes = NULL; -} - -CK_RV -p11_extract_info_load_filter (P11KitIter *iter, - CK_BBOOL *matches, - void *data) -{ - p11_extract_info *ex = data; - int i; - - extract_clear (ex); - - /* Try to load the certificate and extensions */ - if (!extract_info (iter, ex)) { - *matches = CK_FALSE; - return CKR_OK; - } - - /* - * Limit to certain purposes. Note that the lack of purposes noted - * on the certificate means they match any purpose. This is the - * behavior of the ExtendedKeyUsage extension. - */ - if (ex->limit_to_purposes && ex->purposes) { - *matches = CK_FALSE; - for (i = 0; i < ex->purposes->num; i++) { - if (p11_dict_get (ex->limit_to_purposes, ex->purposes->elem[i])) { - *matches = CK_TRUE; - break; - } - } - } - - return CKR_OK; -} - -void -p11_extract_info_init (p11_extract_info *ex) -{ - memset (ex, 0, sizeof (p11_extract_info)); - ex->asn1_defs = p11_asn1_defs_load (); - return_if_fail (ex->asn1_defs != NULL); -} - -void -p11_extract_info_cleanup (p11_extract_info *ex) -{ - extract_clear (ex); - - p11_dict_free (ex->limit_to_purposes); - ex->limit_to_purposes = NULL; - - p11_dict_free (ex->already_seen); - ex->already_seen = NULL; - - p11_dict_free (ex->asn1_defs); - ex->asn1_defs = NULL; -} - -void -p11_extract_info_limit_purpose (p11_extract_info *ex, - const char *purpose) -{ - char *value; - - if (!ex->limit_to_purposes) { - ex->limit_to_purposes = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, free, NULL); - return_if_fail (ex->limit_to_purposes != NULL); - } - - value = strdup (purpose); - return_if_fail (value != NULL); - - if (!p11_dict_set (ex->limit_to_purposes, value, value)) - return_if_reached (); -} - -static char * -extract_label (p11_extract_info *extract) -{ - CK_ATTRIBUTE *attr; - - /* Look for a label and just use that */ - attr = p11_attrs_find_valid (extract->attrs, CKA_LABEL); - if (attr && attr->pValue && attr->ulValueLen) - return strndup (attr->pValue, attr->ulValueLen); - - /* For extracting certificates */ - if (extract->klass == CKO_CERTIFICATE) - return strdup ("certificate"); - - return strdup ("unknown"); -} - -char * -p11_extract_info_filename (p11_extract_info *extract) -{ - char *label; - - label = extract_label (extract); - return_val_if_fail (label != NULL, NULL); - - p11_path_canon (label); - return label; -} - -char * -p11_extract_info_comment (p11_extract_info *ex, - bool first) -{ - char *comment; - char *label; - - if (!(ex->flags & P11_EXTRACT_COMMENT)) - return NULL; - - label = extract_label (ex); - if (!asprintf (&comment, "%s# %s\n", - first ? "" : "\n", - label ? label : "")) - return_val_if_reached (NULL); - - free (label); - return comment; -} diff --git a/trust/extract-jks.c b/trust/extract-jks.c index e12b2de..b409046 100644 --- a/trust/extract-jks.c +++ b/trust/extract-jks.c @@ -210,8 +210,7 @@ add_alias (p11_buffer *buffer, } static bool -prepare_jks_buffer (P11KitIter *iter, - p11_extract_info *ex, +prepare_jks_buffer (p11_enumerate *ex, p11_buffer *buffer) { const unsigned char magic[] = { 0xfe, 0xed, 0xfe, 0xed }; @@ -258,7 +257,7 @@ prepare_jks_buffer (P11KitIter *iter, return_val_if_fail (aliases != NULL, false); /* For every certificate */ - while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { + while ((rv = p11_kit_iter_next (ex->iter)) == CKR_OK) { count++; /* The type of entry */ @@ -312,17 +311,17 @@ prepare_jks_buffer (P11KitIter *iter, } bool -p11_extract_jks_cacerts (P11KitIter *iter, - p11_extract_info *ex) +p11_extract_jks_cacerts (p11_enumerate *ex, + const char *destination) { p11_buffer buffer; p11_save_file *file; bool ret; p11_buffer_init (&buffer, 1024 * 10); - ret = prepare_jks_buffer (iter, ex, &buffer); + ret = prepare_jks_buffer (ex, &buffer); if (ret) { - file = p11_save_open_file (ex->destination, NULL, ex->flags); + file = p11_save_open_file (destination, NULL, ex->flags); ret = p11_save_write_and_finish (file, buffer.data, buffer.len); } diff --git a/trust/extract-openssl.c b/trust/extract-openssl.c index 1f12f11..912c90d 100644 --- a/trust/extract-openssl.c +++ b/trust/extract-openssl.c @@ -102,7 +102,7 @@ known_usages (p11_array *oids) } static bool -load_usage_ext (p11_extract_info *ex, +load_usage_ext (p11_enumerate *ex, const unsigned char *ext_oid, p11_array **oids) { @@ -161,7 +161,7 @@ write_usages (node_asn *asn, } static bool -write_trust_and_rejects (p11_extract_info *ex, +write_trust_and_rejects (p11_enumerate *ex, node_asn *asn) { p11_array *trusts = NULL; @@ -222,7 +222,7 @@ write_trust_and_rejects (p11_extract_info *ex, } static bool -write_keyid (p11_extract_info *ex, +write_keyid (p11_enumerate *ex, node_asn *asn) { unsigned char *value = NULL; @@ -245,7 +245,7 @@ write_keyid (p11_extract_info *ex, } static bool -write_alias (p11_extract_info *ex, +write_alias (p11_enumerate *ex, node_asn *asn) { CK_ATTRIBUTE *label; @@ -264,7 +264,7 @@ write_alias (p11_extract_info *ex, } static bool -write_other (p11_extract_info *ex, +write_other (p11_enumerate *ex, node_asn *asn) { int ret; @@ -276,7 +276,7 @@ write_other (p11_extract_info *ex, } static bool -prepare_pem_contents (p11_extract_info *ex, +prepare_pem_contents (p11_enumerate *ex, p11_buffer *buffer) { char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; @@ -315,8 +315,8 @@ prepare_pem_contents (p11_extract_info *ex, } bool -p11_extract_openssl_bundle (P11KitIter *iter, - p11_extract_info *ex) +p11_extract_openssl_bundle (p11_enumerate *ex, + const char *destination) { p11_save_file *file; p11_buffer output; @@ -326,13 +326,13 @@ p11_extract_openssl_bundle (P11KitIter *iter, bool first; CK_RV rv; - file = p11_save_open_file (ex->destination, NULL, ex->flags); + file = p11_save_open_file (destination, NULL, ex->flags); if (!file) return false; first = true; p11_buffer_init (&output, 0); - while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { + while ((rv = p11_kit_iter_next (ex->iter)) == CKR_OK) { p11_buffer_init (&buf, 1024); if (!p11_buffer_reset (&output, 2048)) return_val_if_reached (false); @@ -341,7 +341,7 @@ p11_extract_openssl_bundle (P11KitIter *iter, if (!p11_pem_write (buf.data, buf.len, "TRUSTED CERTIFICATE", &output)) return_val_if_reached (false); - comment = p11_extract_info_comment (ex, first); + comment = p11_enumerate_comment (ex, first); first = false; ret = p11_save_write (file, comment, -1) && @@ -528,7 +528,7 @@ p11_openssl_canon_name_der (p11_dict *asn1_defs, #ifdef OS_UNIX static char * -symlink_for_subject_hash (p11_extract_info *ex) +symlink_for_subject_hash (p11_enumerate *ex) { unsigned char md[P11_DIGEST_SHA1_LEN]; p11_buffer der; @@ -561,7 +561,7 @@ symlink_for_subject_hash (p11_extract_info *ex) } static char * -symlink_for_subject_old_hash (p11_extract_info *ex) +symlink_for_subject_old_hash (p11_enumerate *ex) { unsigned char md[P11_DIGEST_MD5_LEN]; CK_ATTRIBUTE *subject; @@ -588,8 +588,8 @@ symlink_for_subject_old_hash (p11_extract_info *ex) #endif /* OS_UNIX */ bool -p11_extract_openssl_directory (P11KitIter *iter, - p11_extract_info *ex) +p11_extract_openssl_directory (p11_enumerate *ex, + const char *destination) { char *filename; p11_save_file *file; @@ -605,14 +605,14 @@ p11_extract_openssl_directory (P11KitIter *iter, char *linkname; #endif - dir = p11_save_open_directory (ex->destination, ex->flags); + dir = p11_save_open_directory (destination, ex->flags); if (dir == NULL) return false; p11_buffer_init (&buf, 0); p11_buffer_init (&output, 0); - while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { + while ((rv = p11_kit_iter_next (ex->iter)) == CKR_OK) { if (!p11_buffer_reset (&buf, 1024)) return_val_if_reached (false); if (!p11_buffer_reset (&output, 2048)) @@ -622,7 +622,7 @@ p11_extract_openssl_directory (P11KitIter *iter, if (!p11_pem_write (buf.data, buf.len, "TRUSTED CERTIFICATE", &output)) return_val_if_reached (false); - name = p11_extract_info_filename (ex); + name = p11_enumerate_filename (ex); return_val_if_fail (name != NULL, false); filename = NULL; diff --git a/trust/extract-pem.c b/trust/extract-pem.c index 718cd99..1e1c857 100644 --- a/trust/extract-pem.c +++ b/trust/extract-pem.c @@ -46,8 +46,8 @@ #include bool -p11_extract_pem_bundle (P11KitIter *iter, - p11_extract_info *ex) +p11_extract_pem_bundle (p11_enumerate *ex, + const char *destination) { char *comment; p11_buffer buf; @@ -56,19 +56,19 @@ p11_extract_pem_bundle (P11KitIter *iter, bool first = true; CK_RV rv; - file = p11_save_open_file (ex->destination, NULL, ex->flags); + file = p11_save_open_file (destination, NULL, ex->flags); if (!file) return false; p11_buffer_init (&buf, 0); - while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { + while ((rv = p11_kit_iter_next (ex->iter)) == CKR_OK) { if (!p11_buffer_reset (&buf, 2048)) return_val_if_reached (false); if (!p11_pem_write (ex->cert_der, ex->cert_len, "CERTIFICATE", &buf)) return_val_if_reached (false); - comment = p11_extract_info_comment (ex, first); + comment = p11_enumerate_comment (ex, first); first = false; ret = p11_save_write (file, comment, -1) && @@ -99,8 +99,8 @@ p11_extract_pem_bundle (P11KitIter *iter, } bool -p11_extract_pem_directory (P11KitIter *iter, - p11_extract_info *ex) +p11_extract_pem_directory (p11_enumerate *ex, + const char *destination) { p11_save_file *file; p11_save_dir *dir; @@ -109,19 +109,19 @@ p11_extract_pem_directory (P11KitIter *iter, char *filename; CK_RV rv; - dir = p11_save_open_directory (ex->destination, ex->flags); + dir = p11_save_open_directory (destination, ex->flags); if (dir == NULL) return false; p11_buffer_init (&buf, 0); - while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { + while ((rv = p11_kit_iter_next (ex->iter)) == CKR_OK) { if (!p11_buffer_reset (&buf, 2048)) return_val_if_reached (false); if (!p11_pem_write (ex->cert_der, ex->cert_len, "CERTIFICATE", &buf)) return_val_if_reached (false); - filename = p11_extract_info_filename (ex); + filename = p11_enumerate_filename (ex); return_val_if_fail (filename != NULL, false); file = p11_save_open_file_in (dir, filename, ".pem"); diff --git a/trust/extract.c b/trust/extract.c index 1aec3e6..0389d29 100644 --- a/trust/extract.c +++ b/trust/extract.c @@ -55,114 +55,6 @@ #include static bool -filter_argument (const char *optarg, - P11KitUri **uri, - CK_ATTRIBUTE **match, - int *flags) -{ - CK_ATTRIBUTE *attrs; - int ret; - - CK_OBJECT_CLASS vcertificate = CKO_CERTIFICATE; - CK_ULONG vauthority = 2; - CK_CERTIFICATE_TYPE vx509 = CKC_X_509; - - CK_ATTRIBUTE certificate = { CKA_CLASS, &vcertificate, sizeof (vcertificate) }; - CK_ATTRIBUTE authority = { CKA_CERTIFICATE_CATEGORY, &vauthority, sizeof (vauthority) }; - CK_ATTRIBUTE x509 = { CKA_CERTIFICATE_TYPE, &vx509, sizeof (vx509) }; - - if (strncmp (optarg, "pkcs11:", 7) == 0) { - if (*uri != NULL) { - p11_message ("only one pkcs11 uri filter may be specified"); - return false; - } - *uri = p11_kit_uri_new (); - ret = p11_kit_uri_parse (optarg, P11_KIT_URI_FOR_OBJECT_ON_TOKEN_AND_MODULE, *uri); - if (ret != P11_KIT_URI_OK) { - p11_message ("couldn't parse pkcs11 uri filter: %s", optarg); - return false; - } - return true; - } - - if (strcmp (optarg, "ca-anchors") == 0) { - attrs = p11_attrs_build (NULL, &certificate, &authority, &x509, NULL); - *flags |= P11_EXTRACT_ANCHORS | P11_EXTRACT_COLLAPSE; - - } else if (strcmp (optarg, "trust-policy") == 0) { - attrs = p11_attrs_build (NULL, &certificate, &x509, NULL); - *flags |= P11_EXTRACT_ANCHORS | P11_EXTRACT_BLACKLIST | P11_EXTRACT_COLLAPSE; - - } else if (strcmp (optarg, "blacklist") == 0) { - attrs = p11_attrs_build (NULL, &certificate, &x509, NULL); - *flags |= P11_EXTRACT_BLACKLIST | P11_EXTRACT_COLLAPSE; - - } else if (strcmp (optarg, "certificates") == 0) { - attrs = p11_attrs_build (NULL, &certificate, &x509, NULL); - *flags |= P11_EXTRACT_COLLAPSE; - - } else { - p11_message ("unsupported or unrecognized filter: %s", optarg); - return false; - } - - if (*match != NULL) { - p11_message ("a conflicting filter has already been specified"); - p11_attrs_free (attrs); - return false; - } - - *match = attrs; - return true; -} - -static int -is_valid_oid_rough (const char *string) -{ - size_t len; - - len = strlen (string); - - /* Rough check if a valid OID */ - return (strspn (string, "0123456789.") == len && - !strstr (string, "..") && string[0] != '\0' && string[0] != '.' && - string[len - 1] != '.'); -} - -static bool -purpose_argument (const char *optarg, - p11_extract_info *ex) -{ - const char *oid; - - if (strcmp (optarg, "server-auth") == 0) { - oid = P11_OID_SERVER_AUTH_STR; - } else if (strcmp (optarg, "client-auth") == 0) { - oid = P11_OID_CLIENT_AUTH_STR; - } else if (strcmp (optarg, "email-protection") == 0 || strcmp (optarg, "email") == 0) { - oid = P11_OID_EMAIL_PROTECTION_STR; - } else if (strcmp (optarg, "code-signing") == 0) { - oid = P11_OID_CODE_SIGNING_STR; - } else if (strcmp (optarg, "ipsec-end-system") == 0) { - oid = P11_OID_IPSEC_END_SYSTEM_STR; - } else if (strcmp (optarg, "ipsec-tunnel") == 0) { - oid = P11_OID_IPSEC_TUNNEL_STR; - } else if (strcmp (optarg, "ipsec-user") == 0) { - oid = P11_OID_IPSEC_USER_STR; - } else if (strcmp (optarg, "time-stamping") == 0) { - oid = P11_OID_TIME_STAMPING_STR; - } else if (is_valid_oid_rough (optarg)) { - oid = optarg; - } else { - p11_message ("unsupported or unregonized purpose: %s", optarg); - return false; - } - - p11_extract_info_limit_purpose (ex, oid); - return true; -} - -static bool format_argument (const char *optarg, p11_extract_func *func) { @@ -209,9 +101,8 @@ format_argument (const char *optarg, } static bool -validate_filter_and_format (p11_extract_info *ex, - p11_extract_func func, - CK_ATTRIBUTE *match) +validate_filter_and_format (p11_enumerate *ex, + p11_extract_func func) { int i; @@ -233,8 +124,8 @@ validate_filter_and_format (p11_extract_info *ex, return true; } - if ((ex->flags & P11_EXTRACT_ANCHORS) && - (ex->flags & P11_EXTRACT_BLACKLIST)) { + if ((ex->flags & P11_ENUMERATE_ANCHORS) && + (ex->flags & P11_ENUMERATE_BLACKLIST)) { /* * If we're extracting *both* anchors and blacklist, then we must have * a format that can represent the different types of information. @@ -243,7 +134,7 @@ validate_filter_and_format (p11_extract_info *ex, p11_message ("format does not support trust policy"); return false; - } else if (ex->flags & P11_EXTRACT_ANCHORS) { + } else if (ex->flags & P11_ENUMERATE_ANCHORS) { /* * If we're extracting anchors, then we must have either limited the @@ -252,7 +143,7 @@ validate_filter_and_format (p11_extract_info *ex, if (!ex->limit_to_purposes) { p11_message ("format does not support multiple purposes, defaulting to 'server-auth'"); - p11_extract_info_limit_purpose (ex, P11_OID_SERVER_AUTH_STR); + p11_enumerate_opt_purpose (ex, "server-auth"); } } @@ -264,12 +155,7 @@ p11_trust_extract (int argc, char **argv) { p11_extract_func format = NULL; - CK_FUNCTION_LIST_PTR *modules; - P11KitIter *iter; - p11_extract_info ex; - CK_ATTRIBUTE *match; - P11KitUri *uri; - int flags; + p11_enumerate ex; int opt = 0; int ret; @@ -334,10 +220,7 @@ p11_trust_extract (int argc, { 0 }, }; - match = NULL; - uri = NULL; - - p11_extract_info_init (&ex); + p11_enumerate_init (&ex); while ((opt = p11_tool_getopt (argc, argv, options)) != -1) { switch (opt) { @@ -352,11 +235,11 @@ p11_trust_extract (int argc, ex.flags |= P11_EXTRACT_COMMENT; break; case opt_filter: - if (!filter_argument (optarg, &uri, &match, &ex.flags)) + if (!p11_enumerate_opt_filter (&ex, optarg)) exit (2); break; case opt_purpose: - if (!purpose_argument (optarg, &ex)) + if (!p11_enumerate_opt_purpose (&ex, optarg)) exit (2); break; case opt_format: @@ -381,55 +264,20 @@ p11_trust_extract (int argc, p11_message ("specify one destination file or directory"); exit (2); } - ex.destination = argv[0]; if (!format) { p11_message ("no output format specified"); exit (2); } - /* If nothing that was useful to enumerate was specified, then bail */ - if (uri == NULL && match == NULL) { - p11_message ("no filter specified, defaulting to 'ca-anchors'"); - filter_argument ("ca-anchors", &uri, &match, &ex.flags); - } - - if (!validate_filter_and_format (&ex, format, match)) + if (!validate_filter_and_format (&ex, format)) exit (1); - if (uri && p11_kit_uri_any_unrecognized (uri)) - p11_message ("uri contained unrecognized components, nothing will be extracted"); - - /* - * We only "believe" the CKA_TRUSTED and CKA_X_DISTRUSTED attributes - * we get from modules explicitly marked as containing trust-policy. - */ - flags = 0; - if (ex.flags & (P11_EXTRACT_ANCHORS | P11_EXTRACT_BLACKLIST)) - flags |= P11_KIT_MODULE_TRUSTED; - - modules = p11_kit_modules_load_and_initialize (flags); - if (!modules) + if (!p11_enumerate_ready (&ex, "ca-anchors")) exit (1); - if (modules[0] == NULL) - p11_message ("no modules containing trust policy are registered"); - - iter = p11_kit_iter_new (uri, 0); - - p11_kit_iter_add_callback (iter, p11_extract_info_load_filter, &ex, NULL); - p11_kit_iter_add_filter (iter, match, p11_attrs_count (match)); - - p11_kit_iter_begin (iter, modules); - - ret = (format) (iter, &ex) ? 0 : 1; - - p11_extract_info_cleanup (&ex); - p11_kit_iter_free (iter); - p11_kit_uri_free (uri); - - p11_kit_modules_finalize (modules); - p11_kit_modules_release (modules); + ret = (format) (&ex, argv[0]) ? 0 : 1; + p11_enumerate_cleanup (&ex); return ret; } diff --git a/trust/extract.h b/trust/extract.h index 7db61c1..1bd8e4a 100644 --- a/trust/extract.h +++ b/trust/extract.h @@ -37,87 +37,37 @@ #ifndef P11_EXTRACT_H_ #define P11_EXTRACT_H_ -#include "array.h" -#include "asn1.h" -#include "dict.h" -#include "iter.h" +#include "enumerate.h" #include "pkcs11.h" enum { /* These overlap with the flags in save.h, so start higher */ P11_EXTRACT_COMMENT = 1 << 10, - P11_EXTRACT_ANCHORS = 1 << 11, - P11_EXTRACT_BLACKLIST = 1 << 12, - P11_EXTRACT_COLLAPSE = 1 << 13, }; -typedef struct { - p11_dict *asn1_defs; - p11_dict *limit_to_purposes; - p11_dict *already_seen; - char *destination; - int flags; +typedef bool (* p11_extract_func) (p11_enumerate *ex, + const char *destination); - /* - * Stuff below is parsed info for the current iteration. - * Currently this information is generally all relevant - * just for certificates. - */ +bool p11_extract_x509_file (p11_enumerate *ex, + const char *destination); - CK_OBJECT_CLASS klass; - CK_ATTRIBUTE *attrs; +bool p11_extract_x509_directory (p11_enumerate *ex, + const char *destination); - /* Pre-parsed data for certificates */ - node_asn *cert_asn; - const unsigned char *cert_der; - size_t cert_len; +bool p11_extract_pem_bundle (p11_enumerate *ex, + const char *destination); - /* DER OID -> CK_ATTRIBUTE list */ - p11_dict *stapled; +bool p11_extract_pem_directory (p11_enumerate *ex, + const char *destination); - /* Set of OID purposes as strings */ - p11_array *purposes; -} p11_extract_info; +bool p11_extract_jks_cacerts (p11_enumerate *ex, + const char *destination); -void p11_extract_info_init (p11_extract_info *ex); +bool p11_extract_openssl_bundle (p11_enumerate *ex, + const char *destination); -CK_RV p11_extract_info_load_filter (P11KitIter *iter, - CK_BBOOL *matches, - void *data); - -void p11_extract_info_limit_purpose (p11_extract_info *ex, - const char *purpose); - -void p11_extract_info_cleanup (p11_extract_info *ex); - -char * p11_extract_info_filename (p11_extract_info *ex); - -char * p11_extract_info_comment (p11_extract_info *ex, - bool first); - -typedef bool (* p11_extract_func) (P11KitIter *iter, - p11_extract_info *ex); - -bool p11_extract_x509_file (P11KitIter *iter, - p11_extract_info *ex); - -bool p11_extract_x509_directory (P11KitIter *iter, - p11_extract_info *ex); - -bool p11_extract_pem_bundle (P11KitIter *iter, - p11_extract_info *ex); - -bool p11_extract_pem_directory (P11KitIter *iter, - p11_extract_info *ex); - -bool p11_extract_jks_cacerts (P11KitIter *iter, - p11_extract_info *ex); - -bool p11_extract_openssl_bundle (P11KitIter *iter, - p11_extract_info *ex); - -bool p11_extract_openssl_directory (P11KitIter *iter, - p11_extract_info *ex); +bool p11_extract_openssl_directory (p11_enumerate *ex, + const char *destination); int p11_trust_extract (int argc, char **argv); diff --git a/trust/tests/Makefile.am b/trust/tests/Makefile.am index c1e8127..e53a6ae 100644 --- a/trust/tests/Makefile.am +++ b/trust/tests/Makefile.am @@ -50,7 +50,7 @@ CHECK_PROGS = \ test-token \ test-module \ test-save \ - test-extract \ + test-enumerate \ test-cer \ test-bundle \ test-openssl \ @@ -89,28 +89,28 @@ test_save_SOURCES = \ $(TRUST)/save.c \ $(NULL) -test_extract_SOURCES = \ - test-extract.c \ - $(TRUST)/extract-info.c \ +test_enumerate_SOURCES = \ + test-enumerate.c \ + $(TRUST)/enumerate.c \ $(NULL) test_cer_SOURCES = \ test-cer.c \ - $(TRUST)/extract-info.c \ + $(TRUST)/enumerate.c \ $(TRUST)/extract-cer.c \ $(TRUST)/save.c \ $(NULL) test_bundle_SOURCES = \ test-bundle.c \ - $(TRUST)/extract-info.c \ + $(TRUST)/enumerate.c \ $(TRUST)/extract-pem.c \ $(TRUST)/save.c \ $(NULL) test_openssl_SOURCES = \ test-openssl.c \ - $(TRUST)/extract-info.c \ + $(TRUST)/enumerate.c \ $(TRUST)/extract-openssl.c \ $(TRUST)/save.c \ $(NULL) diff --git a/trust/tests/test-bundle.c b/trust/tests/test-bundle.c index 397787f..85c0b5f 100644 --- a/trust/tests/test-bundle.c +++ b/trust/tests/test-bundle.c @@ -59,8 +59,7 @@ struct { CK_FUNCTION_LIST module; - P11KitIter *iter; - p11_extract_info ex; + p11_enumerate ex; char *directory; } test; @@ -74,9 +73,7 @@ setup (void *unused) rv = test.module.C_Initialize (NULL); assert_num_eq (CKR_OK, rv); - test.iter = p11_kit_iter_new (NULL, 0); - - p11_extract_info_init (&test.ex); + p11_enumerate_init (&test.ex); test.directory = p11_test_directory ("test-extract"); } @@ -90,8 +87,7 @@ teardown (void *unused) assert_not_reached (); free (test.directory); - p11_extract_info_cleanup (&test.ex); - p11_kit_iter_free (test.iter); + p11_enumerate_cleanup (&test.ex); rv = test.module.C_Finalize (NULL); assert_num_eq (CKR_OK, rv); @@ -118,66 +114,66 @@ static CK_ATTRIBUTE certificate_filter[] = { static void test_file (void) { + char *destination; bool ret; mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); - if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.pem") < 0) + if (asprintf (&destination, "%s/%s", test.directory, "extract.pem") < 0) assert_not_reached (); - ret = p11_extract_pem_bundle (test.iter, &test.ex); + ret = p11_extract_pem_bundle (&test.ex, destination); assert_num_eq (true, ret); test_check_file (test.directory, "extract.pem", SRCDIR "/files/cacert3.pem"); - free (test.ex.destination); + free (destination); } static void test_file_multiple (void) { + char *destination; bool ret; mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs); mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); - if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.pem") < 0) + if (asprintf (&destination, "%s/%s", test.directory, "extract.pem") < 0) assert_not_reached (); - ret = p11_extract_pem_bundle (test.iter, &test.ex); + ret = p11_extract_pem_bundle (&test.ex, destination); assert_num_eq (true, ret); test_check_file (test.directory, "extract.pem", SRCDIR "/files/cacert3-twice.pem"); - free (test.ex.destination); + free (destination); } static void test_file_without (void) { + char *destination; bool ret; - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); - if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.pem") < 0) + if (asprintf (&destination, "%s/%s", test.directory, "extract.pem") < 0) assert_not_reached (); - ret = p11_extract_pem_bundle (test.iter, &test.ex); + ret = p11_extract_pem_bundle (&test.ex, destination); assert_num_eq (true, ret); test_check_data (test.directory, "extract.pem", "", 0); - free (test.ex.destination); + free (destination); } static void @@ -188,16 +184,14 @@ test_directory (void) mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs); mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); /* Yes, this is a race, and why you shouldn't build software as root */ if (rmdir (test.directory) < 0) assert_not_reached (); - test.ex.destination = test.directory; - ret = p11_extract_pem_directory (test.iter, &test.ex); + ret = p11_extract_pem_directory (&test.ex, test.directory); assert_num_eq (true, ret); test_check_directory (test.directory, ("Cacert3_Here.pem", "Cacert3_Here.1.pem", NULL)); @@ -210,16 +204,14 @@ test_directory_empty (void) { bool ret; - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); /* Yes, this is a race, and why you shouldn't build software as root */ if (rmdir (test.directory) < 0) assert_not_reached (); - test.ex.destination = test.directory; - ret = p11_extract_pem_directory (test.iter, &test.ex); + ret = p11_extract_pem_directory (&test.ex, test.directory); assert_num_eq (true, ret); test_check_directory (test.directory, (NULL, NULL)); diff --git a/trust/tests/test-cer.c b/trust/tests/test-cer.c index 846cabf..ba0b9ca 100644 --- a/trust/tests/test-cer.c +++ b/trust/tests/test-cer.c @@ -59,8 +59,7 @@ struct { CK_FUNCTION_LIST module; - P11KitIter *iter; - p11_extract_info ex; + p11_enumerate ex; char *directory; } test; @@ -74,9 +73,7 @@ setup (void *unused) rv = test.module.C_Initialize (NULL); assert_num_eq (CKR_OK, rv); - test.iter = p11_kit_iter_new (NULL, 0); - - p11_extract_info_init (&test.ex); + p11_enumerate_init (&test.ex); test.directory = p11_test_directory ("test-extract"); } @@ -90,8 +87,7 @@ teardown (void *unused) assert_fail ("rmdir() failed", test.directory); free (test.directory); - p11_extract_info_cleanup (&test.ex); - p11_kit_iter_free (test.iter); + p11_enumerate_cleanup (&test.ex); rv = test.module.C_Finalize (NULL); assert_num_eq (CKR_OK, rv); @@ -118,43 +114,43 @@ static CK_ATTRIBUTE certificate_filter[] = { static void test_file (void) { + char *destination; bool ret; mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); - if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.cer") < 0) + if (asprintf (&destination, "%s/%s", test.directory, "extract.cer") < 0) assert_not_reached (); - ret = p11_extract_x509_file (test.iter, &test.ex); + ret = p11_extract_x509_file (&test.ex, destination); assert_num_eq (true, ret); test_check_file (test.directory, "extract.cer", SRCDIR "/files/cacert3.der"); - free (test.ex.destination); + free (destination); } static void test_file_multiple (void) { + char *destination; bool ret; mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs); mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); - if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.cer") < 0) + if (asprintf (&destination, "%s/%s", test.directory, "extract.cer") < 0) assert_not_reached (); p11_message_quiet (); - ret = p11_extract_x509_file (test.iter, &test.ex); + ret = p11_extract_x509_file (&test.ex, destination); assert_num_eq (true, ret); assert (strstr (p11_message_last (), "multiple certificates") != NULL); @@ -163,31 +159,31 @@ test_file_multiple (void) test_check_file (test.directory, "extract.cer", SRCDIR "/files/cacert3.der"); - free (test.ex.destination); + free (destination); } static void test_file_without (void) { + char *destination; bool ret; - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); - if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.cer") < 0) + if (asprintf (&destination, "%s/%s", test.directory, "extract.cer") < 0) assert_not_reached (); p11_message_quiet (); - ret = p11_extract_x509_file (test.iter, &test.ex); + ret = p11_extract_x509_file (&test.ex, destination); assert_num_eq (false, ret); assert (strstr (p11_message_last (), "no certificate") != NULL); p11_message_loud (); - free (test.ex.destination); + free (destination); } static void @@ -198,16 +194,14 @@ test_directory (void) mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs); mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_authority_attrs); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); /* Yes, this is a race, and why you shouldn't build software as root */ if (rmdir (test.directory) < 0) assert_not_reached (); - test.ex.destination = test.directory; - ret = p11_extract_x509_directory (test.iter, &test.ex); + ret = p11_extract_x509_directory (&test.ex, test.directory); assert_num_eq (true, ret); test_check_directory (test.directory, ("Cacert3_Here.cer", "Cacert3_Here.1.cer", NULL)); @@ -220,16 +214,14 @@ test_directory_empty (void) { bool ret; - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); /* Yes, this is a race, and why you shouldn't build software as root */ if (rmdir (test.directory) < 0) assert_not_reached (); - test.ex.destination = test.directory; - ret = p11_extract_x509_directory (test.iter, &test.ex); + ret = p11_extract_x509_directory (&test.ex, test.directory); assert_num_eq (true, ret); test_check_directory (test.directory, (NULL, NULL)); diff --git a/trust/tests/test-enumerate.c b/trust/tests/test-enumerate.c new file mode 100644 index 0000000..027abbe --- /dev/null +++ b/trust/tests/test-enumerate.c @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2011, Collabora Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * The names of contributors to this software may not be + * used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Author: Stef Walter + */ + +#define P11_KIT_DISABLE_DEPRECATED + +#include "config.h" + +#include "test-trust.h" + +#include "attrs.h" +#include "compat.h" +#include "debug.h" +#include "dict.h" +#include "extract.h" +#include "message.h" +#include "mock.h" +#include "pkcs11.h" +#include "pkcs11x.h" +#include "oid.h" +#include "test.h" + +#include +#include + + +static void +test_file_name_for_label (void) +{ + CK_ATTRIBUTE label = { CKA_LABEL, "The Label!", 10 }; + p11_enumerate ex; + char *name; + + p11_enumerate_init (&ex); + + ex.attrs = p11_attrs_build (NULL, &label, NULL); + + name = p11_enumerate_filename (&ex); + assert_str_eq ("The_Label_", name); + free (name); + + p11_enumerate_cleanup (&ex); +} + +static void +test_file_name_for_class (void) +{ + p11_enumerate ex; + char *name; + + p11_enumerate_init (&ex); + + ex.klass = CKO_CERTIFICATE; + + name = p11_enumerate_filename (&ex); + assert_str_eq ("certificate", name); + free (name); + + ex.klass = CKO_DATA; + + name = p11_enumerate_filename (&ex); + assert_str_eq ("unknown", name); + free (name); + + p11_enumerate_cleanup (&ex); +} + +static void +test_comment_for_label (void) +{ + CK_ATTRIBUTE label = { CKA_LABEL, "The Label!", 10 }; + p11_enumerate ex; + char *comment; + + p11_enumerate_init (&ex); + + ex.flags = P11_EXTRACT_COMMENT; + ex.attrs = p11_attrs_build (NULL, &label, NULL); + + comment = p11_enumerate_comment (&ex, true); + assert_str_eq ("# The Label!\n", comment); + free (comment); + + comment = p11_enumerate_comment (&ex, false); + assert_str_eq ("\n# The Label!\n", comment); + free (comment); + + p11_enumerate_cleanup (&ex); +} + +static void +test_comment_not_enabled (void) +{ + CK_ATTRIBUTE label = { CKA_LABEL, "The Label!", 10 }; + p11_enumerate ex; + char *comment; + + p11_enumerate_init (&ex); + + ex.attrs = p11_attrs_build (NULL, &label, NULL); + + comment = p11_enumerate_comment (&ex, true); + assert_ptr_eq (NULL, comment); + + comment = p11_enumerate_comment (&ex, false); + assert_ptr_eq (NULL, comment); + + p11_enumerate_cleanup (&ex); +} + +struct { + CK_FUNCTION_LIST module; + p11_enumerate ex; +} test; + +static void +setup (void *unused) +{ + CK_RV rv; + + mock_module_reset (); + memcpy (&test.module, &mock_module, sizeof (CK_FUNCTION_LIST)); + + rv = test.module.C_Initialize (NULL); + assert_num_eq (CKR_OK, rv); + + p11_enumerate_init (&test.ex); +} + +static void +teardown (void *unused) +{ + CK_RV rv; + + p11_enumerate_cleanup (&test.ex); + + rv = test.module.C_Finalize (NULL); + assert_num_eq (CKR_OK, rv); +} + +static CK_OBJECT_CLASS certificate_class = CKO_CERTIFICATE; +static CK_OBJECT_CLASS extension_class = CKO_X_CERTIFICATE_EXTENSION; +static CK_CERTIFICATE_TYPE x509_type = CKC_X_509; +static CK_BBOOL truev = CK_TRUE; + +static CK_ATTRIBUTE cacert3_trusted[] = { + { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) }, + { CKA_CLASS, &certificate_class, sizeof (certificate_class) }, + { CKA_CERTIFICATE_TYPE, &x509_type, sizeof (x509_type) }, + { CKA_LABEL, "Cacert3 Here", 11 }, + { CKA_SUBJECT, (void *)test_cacert3_ca_subject, sizeof (test_cacert3_ca_subject) }, + { CKA_X_PUBLIC_KEY_INFO, (void *)test_cacert3_ca_public_key, sizeof (test_cacert3_ca_public_key) }, + { CKA_TRUSTED, &truev, sizeof (truev) }, + { CKA_ID, "ID1", 3 }, + { CKA_INVALID }, +}; + +static CK_ATTRIBUTE cacert3_distrusted[] = { + { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) }, + { CKA_CLASS, &certificate_class, sizeof (certificate_class) }, + { CKA_CERTIFICATE_TYPE, &x509_type, sizeof (x509_type) }, + { CKA_LABEL, "Another CaCert", 11 }, + { CKA_SUBJECT, (void *)test_cacert3_ca_subject, sizeof (test_cacert3_ca_subject) }, + { CKA_X_DISTRUSTED, &truev, sizeof (truev) }, + { CKA_INVALID }, +}; + +static CK_ATTRIBUTE certificate_filter[] = { + { CKA_CLASS, &certificate_class, sizeof (certificate_class) }, + { CKA_INVALID }, +}; + +static CK_ATTRIBUTE extension_eku_server_client[] = { + { CKA_CLASS, &extension_class, sizeof (extension_class) }, + { CKA_ID, "ID1", 3 }, + { CKA_OBJECT_ID, (void *)P11_OID_EXTENDED_KEY_USAGE, sizeof (P11_OID_EXTENDED_KEY_USAGE) }, + { CKA_VALUE, "\x30\x1d\x06\x03\x55\x1d\x25\x04\x16\x30\x14\x06\x08\x2b\x06\x01\x05\x05\x07\x03\x01\x06\x08\x2b\x06\x01\x05\x05\x07\x03\x02", 31 }, + { CKA_X_PUBLIC_KEY_INFO, (void *)test_cacert3_ca_public_key, sizeof (test_cacert3_ca_public_key) }, + { CKA_INVALID }, +}; + +static CK_ATTRIBUTE extension_eku_invalid[] = { + { CKA_CLASS, &extension_class, sizeof (extension_class) }, + { CKA_ID, "ID1", 3 }, + { CKA_OBJECT_ID, (void *)P11_OID_EXTENDED_KEY_USAGE, sizeof (P11_OID_EXTENDED_KEY_USAGE) }, + { CKA_X_PUBLIC_KEY_INFO, (void *)test_cacert3_ca_public_key, sizeof (test_cacert3_ca_public_key) }, + { CKA_VALUE, "\x30\x0e\x06\x03\x55\x1d\x25\x04\x07\x69\x6e\x76\x61\x6c\x69\x64", 16 }, + { CKA_INVALID }, +}; + +static void +test_info_simple_certificate (void) +{ + void *value; + size_t length; + CK_RV rv; + + assert_ptr_not_null (test.ex.asn1_defs); + + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); + mock_module_add_object (MOCK_SLOT_ONE_ID, extension_eku_server_client); + + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_OK, rv); + + assert_num_eq (CKO_CERTIFICATE, test.ex.klass); + assert_ptr_not_null (test.ex.attrs); + value = p11_attrs_find_value (test.ex.attrs, CKA_VALUE, &length); + assert_ptr_not_null (value); + assert (memcmp (value, test_cacert3_ca_der, length) == 0); + assert_ptr_not_null (test.ex.cert_der); + assert (memcmp (test.ex.cert_der, test_cacert3_ca_der, test.ex.cert_len) == 0); + assert_ptr_not_null (test.ex.cert_asn); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_CANCEL, rv); +} + +static void +test_info_limit_purposes (void) +{ + CK_RV rv; + + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); + mock_module_add_object (MOCK_SLOT_ONE_ID, extension_eku_server_client); + + /* This should not match the above, with the stapled certificat ext */ + assert_ptr_eq (NULL, test.ex.limit_to_purposes); + p11_enumerate_opt_purpose (&test.ex, "1.1.1"); + assert_ptr_not_null (test.ex.limit_to_purposes); + + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_CANCEL, rv); +} + +static void +test_info_invalid_purposes (void) +{ + CK_RV rv; + + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); + mock_module_add_object (MOCK_SLOT_ONE_ID, extension_eku_invalid); + + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); + + p11_kit_be_quiet (); + + /* No results due to invalid purpose on certificate */ + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_CANCEL, rv); + + p11_kit_be_loud (); +} + +static void +test_info_skip_non_certificate (void) +{ + CK_RV rv; + + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); + + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); + + p11_message_quiet (); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_OK, rv); + + assert_num_eq (CKO_CERTIFICATE, test.ex.klass); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_CANCEL, rv); + + p11_message_loud (); +} + +static void +test_limit_to_purpose_match (void) +{ + CK_RV rv; + + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); + mock_module_add_object (MOCK_SLOT_ONE_ID, extension_eku_server_client); + + p11_enumerate_opt_purpose (&test.ex, P11_OID_SERVER_AUTH_STR); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); + + p11_message_quiet (); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_OK, rv); + + p11_message_loud (); +} + +static void +test_limit_to_purpose_no_match (void) +{ + CK_RV rv; + + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); + mock_module_add_object (MOCK_SLOT_ONE_ID, extension_eku_server_client); + + p11_enumerate_opt_purpose (&test.ex, "3.3.3.3"); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); + + p11_message_quiet (); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_CANCEL, rv); + + p11_message_loud (); +} + +static void +test_duplicate_extract (void) +{ + CK_ATTRIBUTE certificate = { CKA_CLASS, &certificate_class, sizeof (certificate_class) }; + CK_RV rv; + + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_distrusted); + + p11_kit_iter_add_filter (test.ex.iter, &certificate, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_OK, rv); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_OK, rv); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_CANCEL, rv); +} + +static void +test_duplicate_distrusted (void) +{ + CK_ATTRIBUTE certificate = { CKA_CLASS, &certificate_class, sizeof (certificate_class) }; + CK_ATTRIBUTE attrs[] = { + { CKA_X_DISTRUSTED, NULL, 0 }, + }; + + CK_BBOOL val; + CK_RV rv; + + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_distrusted); + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); + + test.ex.flags = P11_ENUMERATE_COLLAPSE; + p11_kit_iter_add_filter (test.ex.iter, &certificate, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_OK, rv); + + rv = p11_kit_iter_load_attributes (test.ex.iter, attrs, 1); + assert_num_eq (CKR_OK, rv); + assert (p11_attrs_findn_bool (attrs, 1, CKA_X_DISTRUSTED, &val)); + assert_num_eq (val, CK_TRUE); + free (attrs[0].pValue); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_CANCEL, rv); +} + +static void +test_trusted_match (void) +{ + CK_ATTRIBUTE certificate = { CKA_CLASS, &certificate_class, sizeof (certificate_class) }; + CK_RV rv; + + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_distrusted); + + test.ex.flags = P11_ENUMERATE_ANCHORS; + p11_kit_iter_add_filter (test.ex.iter, &certificate, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_CANCEL, rv); +} + +static void +test_distrust_match (void) +{ + CK_ATTRIBUTE certificate = { CKA_CLASS, &certificate_class, sizeof (certificate_class) }; + CK_BBOOL boolv; + CK_RV rv; + + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_distrusted); + + test.ex.flags = P11_ENUMERATE_BLACKLIST; + p11_kit_iter_add_filter (test.ex.iter, &certificate, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_OK, rv); + + if (!p11_attrs_find_bool (test.ex.attrs, CKA_X_DISTRUSTED, &boolv)) + boolv = CK_FALSE; + assert_num_eq (CK_TRUE, boolv); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_CANCEL, rv); +} + +static void +test_anytrust_match (void) +{ + CK_ATTRIBUTE certificate = { CKA_CLASS, &certificate_class, sizeof (certificate_class) }; + CK_RV rv; + + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); + mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_distrusted); + + test.ex.flags = P11_ENUMERATE_ANCHORS | P11_ENUMERATE_BLACKLIST; + p11_kit_iter_add_filter (test.ex.iter, &certificate, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_OK, rv); + + rv = p11_kit_iter_next (test.ex.iter); + assert_num_eq (CKR_CANCEL, rv); +} + +int +main (int argc, + char *argv[]) +{ + mock_module_init (); + + p11_test (test_file_name_for_label, "/extract/test_file_name_for_label"); + p11_test (test_file_name_for_class, "/extract/test_file_name_for_class"); + p11_test (test_comment_for_label, "/extract/test_comment_for_label"); + p11_test (test_comment_not_enabled, "/extract/test_comment_not_enabled"); + + p11_fixture (setup, teardown); + p11_test (test_info_simple_certificate, "/extract/test_info_simple_certificate"); + p11_test (test_info_limit_purposes, "/extract/test_info_limit_purposes"); + p11_test (test_info_invalid_purposes, "/extract/test_info_invalid_purposes"); + p11_test (test_info_skip_non_certificate, "/extract/test_info_skip_non_certificate"); + p11_test (test_limit_to_purpose_match, "/extract/test_limit_to_purpose_match"); + p11_test (test_limit_to_purpose_no_match, "/extract/test_limit_to_purpose_no_match"); + p11_test (test_duplicate_extract, "/extract/test_duplicate_extract"); + p11_test (test_duplicate_distrusted, "/extract/test-duplicate-distrusted"); + p11_test (test_trusted_match, "/extract/test_trusted_match"); + p11_test (test_distrust_match, "/extract/test_distrust_match"); + p11_test (test_anytrust_match, "/extract/test_anytrust_match"); + + return p11_test_run (argc, argv); +} diff --git a/trust/tests/test-extract.c b/trust/tests/test-extract.c deleted file mode 100644 index 4fce711..0000000 --- a/trust/tests/test-extract.c +++ /dev/null @@ -1,507 +0,0 @@ -/* - * Copyright (c) 2011, Collabora Ltd. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the - * above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * * The names of contributors to this software may not be - * used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * Author: Stef Walter - */ - -#define P11_KIT_DISABLE_DEPRECATED - -#include "config.h" - -#include "test-trust.h" - -#include "attrs.h" -#include "compat.h" -#include "debug.h" -#include "dict.h" -#include "extract.h" -#include "message.h" -#include "mock.h" -#include "pkcs11.h" -#include "pkcs11x.h" -#include "oid.h" -#include "test.h" - -#include -#include - -static void -test_file_name_for_label (void) -{ - CK_ATTRIBUTE label = { CKA_LABEL, "The Label!", 10 }; - p11_extract_info ex; - char *name; - - p11_extract_info_init (&ex); - - ex.attrs = p11_attrs_build (NULL, &label, NULL); - - name = p11_extract_info_filename (&ex); - assert_str_eq ("The_Label_", name); - free (name); - - p11_extract_info_cleanup (&ex); -} - -static void -test_file_name_for_class (void) -{ - p11_extract_info ex; - char *name; - - p11_extract_info_init (&ex); - - ex.klass = CKO_CERTIFICATE; - - name = p11_extract_info_filename (&ex); - assert_str_eq ("certificate", name); - free (name); - - ex.klass = CKO_DATA; - - name = p11_extract_info_filename (&ex); - assert_str_eq ("unknown", name); - free (name); - - p11_extract_info_cleanup (&ex); -} - -static void -test_comment_for_label (void) -{ - CK_ATTRIBUTE label = { CKA_LABEL, "The Label!", 10 }; - p11_extract_info ex; - char *comment; - - p11_extract_info_init (&ex); - - ex.flags = P11_EXTRACT_COMMENT; - ex.attrs = p11_attrs_build (NULL, &label, NULL); - - comment = p11_extract_info_comment (&ex, true); - assert_str_eq ("# The Label!\n", comment); - free (comment); - - comment = p11_extract_info_comment (&ex, false); - assert_str_eq ("\n# The Label!\n", comment); - free (comment); - - p11_extract_info_cleanup (&ex); -} - -static void -test_comment_not_enabled (void) -{ - CK_ATTRIBUTE label = { CKA_LABEL, "The Label!", 10 }; - p11_extract_info ex; - char *comment; - - p11_extract_info_init (&ex); - - ex.attrs = p11_attrs_build (NULL, &label, NULL); - - comment = p11_extract_info_comment (&ex, true); - assert_ptr_eq (NULL, comment); - - comment = p11_extract_info_comment (&ex, false); - assert_ptr_eq (NULL, comment); - - p11_extract_info_cleanup (&ex); -} - -struct { - CK_FUNCTION_LIST module; - P11KitIter *iter; - p11_extract_info ex; -} test; - -static void -setup (void *unused) -{ - CK_RV rv; - - mock_module_reset (); - memcpy (&test.module, &mock_module, sizeof (CK_FUNCTION_LIST)); - - rv = test.module.C_Initialize (NULL); - assert_num_eq (CKR_OK, rv); - - test.iter = p11_kit_iter_new (NULL, 0); - - p11_extract_info_init (&test.ex); -} - -static void -teardown (void *unused) -{ - CK_RV rv; - - p11_extract_info_cleanup (&test.ex); - - p11_kit_iter_free (test.iter); - - rv = test.module.C_Finalize (NULL); - assert_num_eq (CKR_OK, rv); -} - -static CK_OBJECT_CLASS certificate_class = CKO_CERTIFICATE; -static CK_OBJECT_CLASS extension_class = CKO_X_CERTIFICATE_EXTENSION; -static CK_CERTIFICATE_TYPE x509_type = CKC_X_509; -static CK_BBOOL truev = CK_TRUE; - -static CK_ATTRIBUTE cacert3_trusted[] = { - { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) }, - { CKA_CLASS, &certificate_class, sizeof (certificate_class) }, - { CKA_CERTIFICATE_TYPE, &x509_type, sizeof (x509_type) }, - { CKA_LABEL, "Cacert3 Here", 11 }, - { CKA_SUBJECT, (void *)test_cacert3_ca_subject, sizeof (test_cacert3_ca_subject) }, - { CKA_X_PUBLIC_KEY_INFO, (void *)test_cacert3_ca_public_key, sizeof (test_cacert3_ca_public_key) }, - { CKA_TRUSTED, &truev, sizeof (truev) }, - { CKA_ID, "ID1", 3 }, - { CKA_INVALID }, -}; - -static CK_ATTRIBUTE cacert3_distrusted[] = { - { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) }, - { CKA_CLASS, &certificate_class, sizeof (certificate_class) }, - { CKA_CERTIFICATE_TYPE, &x509_type, sizeof (x509_type) }, - { CKA_LABEL, "Another CaCert", 11 }, - { CKA_SUBJECT, (void *)test_cacert3_ca_subject, sizeof (test_cacert3_ca_subject) }, - { CKA_X_DISTRUSTED, &truev, sizeof (truev) }, - { CKA_INVALID }, -}; - -static CK_ATTRIBUTE certificate_filter[] = { - { CKA_CLASS, &certificate_class, sizeof (certificate_class) }, - { CKA_INVALID }, -}; - -static CK_ATTRIBUTE extension_eku_server_client[] = { - { CKA_CLASS, &extension_class, sizeof (extension_class) }, - { CKA_ID, "ID1", 3 }, - { CKA_OBJECT_ID, (void *)P11_OID_EXTENDED_KEY_USAGE, sizeof (P11_OID_EXTENDED_KEY_USAGE) }, - { CKA_VALUE, "\x30\x1d\x06\x03\x55\x1d\x25\x04\x16\x30\x14\x06\x08\x2b\x06\x01\x05\x05\x07\x03\x01\x06\x08\x2b\x06\x01\x05\x05\x07\x03\x02", 31 }, - { CKA_X_PUBLIC_KEY_INFO, (void *)test_cacert3_ca_public_key, sizeof (test_cacert3_ca_public_key) }, - { CKA_INVALID }, -}; - -static CK_ATTRIBUTE extension_eku_invalid[] = { - { CKA_CLASS, &extension_class, sizeof (extension_class) }, - { CKA_ID, "ID1", 3 }, - { CKA_OBJECT_ID, (void *)P11_OID_EXTENDED_KEY_USAGE, sizeof (P11_OID_EXTENDED_KEY_USAGE) }, - { CKA_X_PUBLIC_KEY_INFO, (void *)test_cacert3_ca_public_key, sizeof (test_cacert3_ca_public_key) }, - { CKA_VALUE, "\x30\x0e\x06\x03\x55\x1d\x25\x04\x07\x69\x6e\x76\x61\x6c\x69\x64", 16 }, - { CKA_INVALID }, -}; - -static void -test_info_simple_certificate (void) -{ - void *value; - size_t length; - CK_RV rv; - - assert_ptr_not_null (test.ex.asn1_defs); - - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); - mock_module_add_object (MOCK_SLOT_ONE_ID, extension_eku_server_client); - - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_OK, rv); - - assert_num_eq (CKO_CERTIFICATE, test.ex.klass); - assert_ptr_not_null (test.ex.attrs); - value = p11_attrs_find_value (test.ex.attrs, CKA_VALUE, &length); - assert_ptr_not_null (value); - assert (memcmp (value, test_cacert3_ca_der, length) == 0); - assert_ptr_not_null (test.ex.cert_der); - assert (memcmp (test.ex.cert_der, test_cacert3_ca_der, test.ex.cert_len) == 0); - assert_ptr_not_null (test.ex.cert_asn); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_CANCEL, rv); -} - -static void -test_info_limit_purposes (void) -{ - CK_RV rv; - - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); - mock_module_add_object (MOCK_SLOT_ONE_ID, extension_eku_server_client); - - /* This should not match the above, with the stapled certificat ext */ - assert_ptr_eq (NULL, test.ex.limit_to_purposes); - p11_extract_info_limit_purpose (&test.ex, "1.1.1"); - assert_ptr_not_null (test.ex.limit_to_purposes); - - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_CANCEL, rv); -} - -static void -test_info_invalid_purposes (void) -{ - CK_RV rv; - - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); - mock_module_add_object (MOCK_SLOT_ONE_ID, extension_eku_invalid); - - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); - - p11_kit_be_quiet (); - - /* No results due to invalid purpose on certificate */ - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_CANCEL, rv); - - p11_kit_be_loud (); -} - -static void -test_info_skip_non_certificate (void) -{ - CK_RV rv; - - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); - - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); - - p11_message_quiet (); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_OK, rv); - - assert_num_eq (CKO_CERTIFICATE, test.ex.klass); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_CANCEL, rv); - - p11_message_loud (); -} - -static void -test_limit_to_purpose_match (void) -{ - CK_RV rv; - - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); - mock_module_add_object (MOCK_SLOT_ONE_ID, extension_eku_server_client); - - p11_extract_info_limit_purpose (&test.ex, P11_OID_SERVER_AUTH_STR); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); - - p11_message_quiet (); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_OK, rv); - - p11_message_loud (); -} - -static void -test_limit_to_purpose_no_match (void) -{ - CK_RV rv; - - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); - mock_module_add_object (MOCK_SLOT_ONE_ID, extension_eku_server_client); - - p11_extract_info_limit_purpose (&test.ex, "3.3.3.3"); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); - - p11_message_quiet (); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_CANCEL, rv); - - p11_message_loud (); -} - -static void -test_duplicate_extract (void) -{ - CK_ATTRIBUTE certificate = { CKA_CLASS, &certificate_class, sizeof (certificate_class) }; - CK_RV rv; - - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_distrusted); - - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, &certificate, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_OK, rv); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_OK, rv); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_CANCEL, rv); -} - -static void -test_duplicate_distrusted (void) -{ - CK_ATTRIBUTE certificate = { CKA_CLASS, &certificate_class, sizeof (certificate_class) }; - CK_ATTRIBUTE attrs[] = { - { CKA_X_DISTRUSTED, NULL, 0 }, - }; - - CK_BBOOL val; - CK_RV rv; - - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_distrusted); - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); - - test.ex.flags = P11_EXTRACT_COLLAPSE; - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, &certificate, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_OK, rv); - - rv = p11_kit_iter_load_attributes (test.iter, attrs, 1); - assert_num_eq (CKR_OK, rv); - assert (p11_attrs_findn_bool (attrs, 1, CKA_X_DISTRUSTED, &val)); - assert_num_eq (val, CK_TRUE); - free (attrs[0].pValue); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_CANCEL, rv); -} - -static void -test_trusted_match (void) -{ - CK_ATTRIBUTE certificate = { CKA_CLASS, &certificate_class, sizeof (certificate_class) }; - CK_RV rv; - - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_distrusted); - - test.ex.flags = P11_EXTRACT_ANCHORS; - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, &certificate, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_CANCEL, rv); -} - -static void -test_distrust_match (void) -{ - CK_ATTRIBUTE certificate = { CKA_CLASS, &certificate_class, sizeof (certificate_class) }; - CK_BBOOL boolv; - CK_RV rv; - - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_distrusted); - - test.ex.flags = P11_EXTRACT_BLACKLIST; - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, &certificate, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_OK, rv); - - if (!p11_attrs_find_bool (test.ex.attrs, CKA_X_DISTRUSTED, &boolv)) - boolv = CK_FALSE; - assert_num_eq (CK_TRUE, boolv); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_CANCEL, rv); -} - -static void -test_anytrust_match (void) -{ - CK_ATTRIBUTE certificate = { CKA_CLASS, &certificate_class, sizeof (certificate_class) }; - CK_RV rv; - - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_trusted); - mock_module_add_object (MOCK_SLOT_ONE_ID, cacert3_distrusted); - - test.ex.flags = P11_EXTRACT_ANCHORS | P11_EXTRACT_BLACKLIST; - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, &certificate, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_OK, rv); - - rv = p11_kit_iter_next (test.iter); - assert_num_eq (CKR_CANCEL, rv); -} - -int -main (int argc, - char *argv[]) -{ - mock_module_init (); - - p11_test (test_file_name_for_label, "/extract/test_file_name_for_label"); - p11_test (test_file_name_for_class, "/extract/test_file_name_for_class"); - p11_test (test_comment_for_label, "/extract/test_comment_for_label"); - p11_test (test_comment_not_enabled, "/extract/test_comment_not_enabled"); - - p11_fixture (setup, teardown); - p11_test (test_info_simple_certificate, "/extract/test_info_simple_certificate"); - p11_test (test_info_limit_purposes, "/extract/test_info_limit_purposes"); - p11_test (test_info_invalid_purposes, "/extract/test_info_invalid_purposes"); - p11_test (test_info_skip_non_certificate, "/extract/test_info_skip_non_certificate"); - p11_test (test_limit_to_purpose_match, "/extract/test_limit_to_purpose_match"); - p11_test (test_limit_to_purpose_no_match, "/extract/test_limit_to_purpose_no_match"); - p11_test (test_duplicate_extract, "/extract/test_duplicate_extract"); - p11_test (test_duplicate_distrusted, "/extract/test-duplicate-distrusted"); - p11_test (test_trusted_match, "/extract/test_trusted_match"); - p11_test (test_distrust_match, "/extract/test_distrust_match"); - p11_test (test_anytrust_match, "/extract/test_anytrust_match"); - - return p11_test_run (argc, argv); -} diff --git a/trust/tests/test-openssl.c b/trust/tests/test-openssl.c index f31a41a..583ce24 100644 --- a/trust/tests/test-openssl.c +++ b/trust/tests/test-openssl.c @@ -62,8 +62,7 @@ struct { CK_FUNCTION_LIST module; - P11KitIter *iter; - p11_extract_info ex; + p11_enumerate ex; char *directory; } test; @@ -77,9 +76,7 @@ setup (void *unused) rv = test.module.C_Initialize (NULL); assert_num_eq (CKR_OK, rv); - test.iter = p11_kit_iter_new (NULL, 0); - - p11_extract_info_init (&test.ex); + p11_enumerate_init (&test.ex); test.directory = p11_test_directory ("test-extract"); } @@ -93,8 +90,8 @@ teardown (void *unused) assert_not_reached (); free (test.directory); - p11_extract_info_cleanup (&test.ex); - p11_kit_iter_free (test.iter); + p11_enumerate_cleanup (&test.ex); + p11_kit_iter_free (test.ex.iter); rv = test.module.C_Finalize (NULL); assert_num_eq (CKR_OK, rv); @@ -177,6 +174,7 @@ setup_objects (const CK_ATTRIBUTE *attrs, static void test_file (void) { + char *destination; bool ret; setup_objects (cacert3_authority_attrs, @@ -184,48 +182,48 @@ test_file (void) extension_reject_email, NULL); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); - if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.pem") < 0) + if (asprintf (&destination, "%s/%s", test.directory, "extract.pem") < 0) assert_not_reached (); - ret = p11_extract_openssl_bundle (test.iter, &test.ex); + ret = p11_extract_openssl_bundle (&test.ex, destination); assert_num_eq (true, ret); test_check_file (test.directory, "extract.pem", SRCDIR "/files/cacert3-trusted-server-alias.pem"); - free (test.ex.destination); + free (destination); } static void test_plain (void) { + char *destination; bool ret; setup_objects (cacert3_authority_attrs, NULL); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); - if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.pem") < 0) + if (asprintf (&destination, "%s/%s", test.directory, "extract.pem") < 0) assert_not_reached (); - ret = p11_extract_openssl_bundle (test.iter, &test.ex); + ret = p11_extract_openssl_bundle (&test.ex, destination); assert_num_eq (true, ret); test_check_file (test.directory, "extract.pem", SRCDIR "/files/cacert3-trusted-alias.pem"); - free (test.ex.destination); + free (destination); } static void test_keyid (void) { + char *destination; bool ret; static CK_ATTRIBUTE cacert3_plain[] = { @@ -248,25 +246,25 @@ test_keyid (void) setup_objects (cacert3_plain, extension_subject_key_identifier, NULL); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); - if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.pem") < 0) + if (asprintf (&destination, "%s/%s", test.directory, "extract.pem") < 0) assert_not_reached (); - ret = p11_extract_openssl_bundle (test.iter, &test.ex); + ret = p11_extract_openssl_bundle (&test.ex, destination); assert_num_eq (true, ret); test_check_file (test.directory, "extract.pem", SRCDIR "/files/cacert3-trusted-keyid.pem"); - free (test.ex.destination); + free (destination); } static void test_not_authority (void) { + char *destination; bool ret; static CK_ATTRIBUTE cacert3_not_trusted[] = { @@ -279,25 +277,25 @@ test_not_authority (void) setup_objects (cacert3_not_trusted, NULL); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); - if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.pem") < 0) + if (asprintf (&destination, "%s/%s", test.directory, "extract.pem") < 0) assert_not_reached (); - ret = p11_extract_openssl_bundle (test.iter, &test.ex); + ret = p11_extract_openssl_bundle (&test.ex, destination); assert_num_eq (true, ret); test_check_file (test.directory, "extract.pem", SRCDIR "/files/cacert3-not-trusted.pem"); - free (test.ex.destination); + free (destination); } static void test_distrust_all (void) { + char *destination; bool ret; static CK_ATTRIBUTE cacert3_blacklist[] = { @@ -311,25 +309,25 @@ test_distrust_all (void) setup_objects (cacert3_blacklist, NULL); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); - if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.pem") < 0) + if (asprintf (&destination, "%s/%s", test.directory, "extract.pem") < 0) assert_not_reached (); - ret = p11_extract_openssl_bundle (test.iter, &test.ex); + ret = p11_extract_openssl_bundle (&test.ex, destination); assert_num_eq (true, ret); test_check_file (test.directory, "extract.pem", SRCDIR "/files/cacert3-distrust-all.pem"); - free (test.ex.destination); + free (destination); } static void test_file_multiple (void) { + char *destination; bool ret; setup_objects (cacert3_authority_attrs, @@ -340,38 +338,37 @@ test_file_multiple (void) setup_objects (verisign_v1_attrs, NULL); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); - if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.pem") < 0) + if (asprintf (&destination, "%s/%s", test.directory, "extract.pem") < 0) assert_not_reached (); - ret = p11_extract_openssl_bundle (test.iter, &test.ex); + ret = p11_extract_openssl_bundle (&test.ex, destination); assert_num_eq (true, ret); test_check_file (test.directory, "extract.pem", SRCDIR "/files/multiple.pem"); - free (test.ex.destination); + free (destination); } static void test_file_without (void) { + char *destination; bool ret; - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); - if (asprintf (&test.ex.destination, "%s/%s", test.directory, "extract.pem") < 0) + if (asprintf (&destination, "%s/%s", test.directory, "extract.pem") < 0) assert_not_reached (); - ret = p11_extract_openssl_bundle (test.iter, &test.ex); + ret = p11_extract_openssl_bundle (&test.ex, destination); assert_num_eq (true, ret); test_check_data (test.directory, "extract.pem", "", 0); - free (test.ex.destination); + free (destination); } /* From extract-openssl.c */ @@ -587,16 +584,14 @@ test_directory (void) setup_objects (cacert3_authority_attrs, NULL); - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); /* Yes, this is a race, and why you shouldn't build software as root */ if (rmdir (test.directory) < 0) assert_not_reached (); - test.ex.destination = test.directory; - ret = p11_extract_openssl_directory (test.iter, &test.ex); + ret = p11_extract_openssl_directory (&test.ex, test.directory); assert_num_eq (true, ret); test_check_directory (test.directory, ("Custom_Label.pem", "Custom_Label.1.pem", @@ -621,16 +616,14 @@ test_directory_empty (void) { bool ret; - p11_kit_iter_add_callback (test.iter, p11_extract_info_load_filter, &test.ex, NULL); - p11_kit_iter_add_filter (test.iter, certificate_filter, 1); - p11_kit_iter_begin_with (test.iter, &test.module, 0, 0); + p11_kit_iter_add_filter (test.ex.iter, certificate_filter, 1); + p11_kit_iter_begin_with (test.ex.iter, &test.module, 0, 0); /* Yes, this is a race, and why you shouldn't build software as root */ if (rmdir (test.directory) < 0) assert_not_reached (); - test.ex.destination = test.directory; - ret = p11_extract_openssl_directory (test.iter, &test.ex); + ret = p11_extract_openssl_directory (&test.ex, test.directory); assert_num_eq (true, ret); test_check_directory (test.directory, (NULL, NULL)); -- cgit v1.1