summaryrefslogtreecommitdiff
path: root/trust
diff options
context:
space:
mode:
Diffstat (limited to 'trust')
-rw-r--r--trust/Makefile.am2
-rw-r--r--trust/adapter.c456
-rw-r--r--trust/adapter.h (renamed from trust/mozilla.h)8
-rw-r--r--trust/p11-kit-trust.module3
-rw-r--r--trust/parser.c5
-rw-r--r--trust/tests/files/redhat-ca.derbin0 -> 948 bytes
-rw-r--r--trust/tests/test-parser.c352
7 files changed, 783 insertions, 43 deletions
diff --git a/trust/Makefile.am b/trust/Makefile.am
index 9f3f119..92c122d 100644
--- a/trust/Makefile.am
+++ b/trust/Makefile.am
@@ -10,9 +10,9 @@ INCLUDES = \
$(NULL)
MODULE_SRCS = \
+ adapter.c adapter.h \
parser.c parser.h \
module.c module.h \
- mozilla.c mozilla.h \
session.c session.h \
token.c token.h \
$(NULL)
diff --git a/trust/adapter.c b/trust/adapter.c
new file mode 100644
index 0000000..c698382
--- /dev/null
+++ b/trust/adapter.c
@@ -0,0 +1,456 @@
+/*
+ * Copyright (C) 2012 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 <stefw@redhat.com>
+ */
+
+#include "config.h"
+
+#include "adapter.h"
+#include "attrs.h"
+#include "checksum.h"
+#include "dict.h"
+#define P11_DEBUG_FLAG P11_DEBUG_TRUST
+#include "debug.h"
+#include "library.h"
+#include "oid.h"
+#include "parser.h"
+#include "pkcs11.h"
+#include "pkcs11x.h"
+#include "x509.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+static CK_ATTRIBUTE *
+build_trust_object_ku (p11_parser *parser,
+ p11_array *parsing,
+ CK_ATTRIBUTE *object,
+ CK_TRUST present)
+{
+ unsigned char *data = NULL;
+ unsigned int ku = 0;
+ p11_dict *defs;
+ size_t length;
+ CK_TRUST defawlt;
+ CK_ULONG i;
+
+ struct {
+ CK_ATTRIBUTE_TYPE type;
+ unsigned int ku;
+ } ku_attribute_map[] = {
+ { CKA_TRUST_DIGITAL_SIGNATURE, P11_KU_DIGITAL_SIGNATURE },
+ { CKA_TRUST_NON_REPUDIATION, P11_KU_NON_REPUDIATION },
+ { CKA_TRUST_KEY_ENCIPHERMENT, P11_KU_KEY_ENCIPHERMENT },
+ { CKA_TRUST_DATA_ENCIPHERMENT, P11_KU_DATA_ENCIPHERMENT },
+ { CKA_TRUST_KEY_AGREEMENT, P11_KU_KEY_AGREEMENT },
+ { CKA_TRUST_KEY_CERT_SIGN, P11_KU_KEY_CERT_SIGN },
+ { CKA_TRUST_CRL_SIGN, P11_KU_CRL_SIGN },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE attrs[sizeof (ku_attribute_map)];
+
+ defawlt = present;
+
+ /* If blacklisted, don't even bother looking at extensions */
+ if (present != CKT_NETSCAPE_UNTRUSTED)
+ data = p11_parsing_get_extension (parser, parsing, P11_OID_KEY_USAGE, &length);
+
+ if (data) {
+ /*
+ * If the certificate extension was missing, then *all* key
+ * usages are to be set. If the extension was invalid, then
+ * fail safe to none of the key usages.
+ */
+ defawlt = CKT_NETSCAPE_TRUST_UNKNOWN;
+
+ defs = p11_parser_get_asn1_defs (parser);
+ if (!p11_x509_parse_key_usage (defs, data, length, &ku))
+ p11_message ("invalid key usage certificate extension");
+ free (data);
+ }
+
+ for (i = 0; ku_attribute_map[i].type != CKA_INVALID; i++) {
+ attrs[i].type = ku_attribute_map[i].type;
+ if (data && (ku & ku_attribute_map[i].ku) == ku_attribute_map[i].ku) {
+ attrs[i].pValue = &present;
+ attrs[i].ulValueLen = sizeof (present);
+ } else {
+ attrs[i].pValue = &defawlt;
+ attrs[i].ulValueLen = sizeof (defawlt);
+ }
+ }
+
+ return p11_attrs_buildn (object, attrs, i);
+}
+
+static CK_ATTRIBUTE *
+build_trust_object_eku (p11_parser *parser,
+ p11_array *parsing,
+ CK_ATTRIBUTE *object,
+ CK_TRUST allow,
+ p11_dict *purposes,
+ p11_dict *rejects)
+{
+ CK_TRUST neutral;
+ CK_TRUST disallow;
+ CK_ULONG i;
+
+ struct {
+ CK_ATTRIBUTE_TYPE type;
+ const char *oid;
+ } eku_attribute_map[] = {
+ { CKA_TRUST_SERVER_AUTH, P11_OID_SERVER_AUTH_STR },
+ { CKA_TRUST_CLIENT_AUTH, P11_OID_CLIENT_AUTH_STR },
+ { CKA_TRUST_CODE_SIGNING, P11_OID_CODE_SIGNING_STR },
+ { CKA_TRUST_EMAIL_PROTECTION, P11_OID_EMAIL_PROTECTION_STR },
+ { CKA_TRUST_IPSEC_END_SYSTEM, P11_OID_IPSEC_END_SYSTEM_STR },
+ { CKA_TRUST_IPSEC_TUNNEL, P11_OID_IPSEC_TUNNEL_STR },
+ { CKA_TRUST_IPSEC_USER, P11_OID_IPSEC_USER_STR },
+ { CKA_TRUST_TIME_STAMPING, P11_OID_TIME_STAMPING_STR },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE attrs[sizeof (eku_attribute_map)];
+
+ /* The neutral value is set if an purpose is not present */
+ if (allow == CKT_NETSCAPE_UNTRUSTED)
+ neutral = CKT_NETSCAPE_UNTRUSTED;
+
+ /* If anything explicitly set, then neutral is unknown */
+ else if (purposes || rejects)
+ neutral = CKT_NETSCAPE_TRUST_UNKNOWN;
+
+ /* Otherwise neutral will allow any purpose */
+ else
+ neutral = allow;
+
+ /* The value set if a purpose is explictly rejected */
+ disallow = CKT_NETSCAPE_UNTRUSTED;
+
+ for (i = 0; eku_attribute_map[i].type != CKA_INVALID; i++) {
+ attrs[i].type = eku_attribute_map[i].type;
+ if (rejects && p11_dict_get (rejects, eku_attribute_map[i].oid)) {
+ attrs[i].pValue = &disallow;
+ attrs[i].ulValueLen = sizeof (disallow);
+ } else if (purposes && p11_dict_get (purposes, eku_attribute_map[i].oid)) {
+ attrs[i].pValue = &allow;
+ attrs[i].ulValueLen = sizeof (allow);
+ } else {
+ attrs[i].pValue = &neutral;
+ attrs[i].ulValueLen = sizeof (neutral);
+ }
+ }
+
+ return p11_attrs_buildn (object, attrs, i);
+}
+
+static void
+build_nss_trust_object (p11_parser *parser,
+ p11_array *parsing,
+ CK_ATTRIBUTE *cert,
+ CK_BBOOL trust,
+ CK_BBOOL distrust,
+ CK_BBOOL authority,
+ p11_dict *purposes,
+ p11_dict *rejects)
+{
+ CK_ATTRIBUTE *object = NULL;
+ CK_TRUST allow;
+
+ CK_OBJECT_CLASS vclass = CKO_NETSCAPE_TRUST;
+ CK_BYTE vsha1_hash[P11_CHECKSUM_SHA1_LENGTH];
+ CK_BYTE vmd5_hash[P11_CHECKSUM_MD5_LENGTH];
+ CK_BBOOL vfalse = CK_FALSE;
+ CK_BBOOL vtrue = CK_TRUE;
+
+ CK_ATTRIBUTE klass = { CKA_CLASS, &vclass, sizeof (vclass) };
+ CK_ATTRIBUTE token = { CKA_TOKEN, &vtrue, sizeof (vtrue) };
+ CK_ATTRIBUTE private = { CKA_PRIVATE, &vfalse, sizeof (vfalse) };
+ CK_ATTRIBUTE modifiable = { CKA_MODIFIABLE, &vfalse, sizeof (vfalse) };
+ CK_ATTRIBUTE invalid = { CKA_INVALID, };
+
+ CK_ATTRIBUTE md5_hash = { CKA_CERT_MD5_HASH, vmd5_hash, sizeof (vmd5_hash) };
+ CK_ATTRIBUTE sha1_hash = { CKA_CERT_SHA1_HASH, vsha1_hash, sizeof (vsha1_hash) };
+
+ CK_ATTRIBUTE step_up_approved = { CKA_TRUST_STEP_UP_APPROVED, &vfalse, sizeof (vfalse) };
+
+ CK_ATTRIBUTE_PTR label;
+ CK_ATTRIBUTE_PTR id;
+ CK_ATTRIBUTE_PTR der;
+ CK_ATTRIBUTE_PTR subject;
+ CK_ATTRIBUTE_PTR issuer;
+ CK_ATTRIBUTE_PTR serial_number;
+
+ /* Setup the hashes of the DER certificate value */
+ der = p11_attrs_find (cert, CKA_VALUE);
+ return_if_fail (der != NULL);
+ p11_checksum_md5 (vmd5_hash, der->pValue, der->ulValueLen, NULL);
+ p11_checksum_sha1 (vsha1_hash, der->pValue, der->ulValueLen, NULL);
+
+ /* Copy all of the following attributes from certificate */
+ id = p11_attrs_find (cert, CKA_ID);
+ return_if_fail (id != NULL);
+ subject = p11_attrs_find (cert, CKA_SUBJECT);
+ return_if_fail (subject != NULL);
+ issuer = p11_attrs_find (cert, CKA_ISSUER);
+ return_if_fail (issuer != NULL);
+ serial_number = p11_attrs_find (cert, CKA_SERIAL_NUMBER);
+ return_if_fail (serial_number != NULL);
+
+ /* Try to use the same label */
+ label = p11_attrs_find (cert, CKA_LABEL);
+ if (label == NULL)
+ label = &invalid;
+
+ object = p11_attrs_build (NULL, &klass, &token, &private, &modifiable, id, label,
+ subject, issuer, serial_number, &md5_hash, &sha1_hash,
+ &step_up_approved, NULL);
+ return_if_fail (object != NULL);
+
+ /* Calculate the default allow trust */
+ if (distrust)
+ allow = CKT_NETSCAPE_UNTRUSTED;
+ else if (trust && authority)
+ allow = CKT_NETSCAPE_TRUSTED_DELEGATOR;
+ else if (trust)
+ allow = CKT_NETSCAPE_TRUSTED;
+ else
+ allow = CKT_NETSCAPE_TRUST_UNKNOWN;
+
+ object = build_trust_object_ku (parser, parsing, object, allow);
+ return_if_fail (object != NULL);
+
+ object = build_trust_object_eku (parser, parsing, object, allow, purposes, rejects);
+ return_if_fail (object != NULL);
+
+ if (!p11_array_push (parsing, object))
+ return_if_reached ();
+}
+
+static const char *
+yield_oid_from_vec (void **state)
+{
+ const char **oids = *state;
+ const char *ret = NULL;
+ if (*oids != NULL)
+ ret = *(oids++);
+ *state = oids;
+ return ret;
+}
+
+static const char *
+yield_oid_from_dict (void **state)
+{
+ p11_dictiter *iter = *state;
+ const char *ret = NULL;
+ if (iter && !p11_dict_next (iter, (void**)&ret, NULL))
+ *state = NULL;
+ return ret;
+}
+
+static void
+build_assertions (p11_parser *parser,
+ p11_array *parsing,
+ CK_ATTRIBUTE *cert,
+ CK_X_ASSERTION_TYPE type,
+ const char * (oid_iter) (void **),
+ void *oid_state)
+{
+ CK_OBJECT_CLASS assertion = CKO_X_TRUST_ASSERTION;
+ CK_BBOOL vtrue = CK_TRUE;
+ CK_BBOOL vfalse = CK_FALSE;
+
+ CK_ATTRIBUTE klass = { CKA_CLASS, &assertion, sizeof (assertion) };
+ CK_ATTRIBUTE token = { CKA_TOKEN, &vtrue, sizeof (vtrue) };
+ CK_ATTRIBUTE private = { CKA_PRIVATE, &vfalse, sizeof (vfalse) };
+ CK_ATTRIBUTE modifiable = { CKA_MODIFIABLE, &vfalse, sizeof (vfalse) };
+ CK_ATTRIBUTE assertion_type = { CKA_X_ASSERTION_TYPE, &type, sizeof (type) };
+ CK_ATTRIBUTE purpose = { CKA_X_PURPOSE, };
+ CK_ATTRIBUTE invalid = { CKA_INVALID, };
+
+ CK_ATTRIBUTE *issuer;
+ CK_ATTRIBUTE *serial;
+ CK_ATTRIBUTE *value;
+ CK_ATTRIBUTE *label;
+ CK_ATTRIBUTE *id;
+ CK_ATTRIBUTE *object;
+ const char *oid_str;
+
+ label = p11_attrs_find (cert, CKA_LABEL);
+ if (label == NULL)
+ label = &invalid;
+
+ id = p11_attrs_find (cert, CKA_ID);
+ issuer = p11_attrs_find (cert, CKA_ISSUER);
+ serial = p11_attrs_find (cert, CKA_SERIAL_NUMBER);
+ value = p11_attrs_find (cert, CKA_VALUE);
+
+ return_if_fail (id != NULL && issuer != NULL && serial != NULL && value != NULL);
+
+ for (;;) {
+ oid_str = (oid_iter) (&oid_state);
+ if (!oid_str)
+ break;
+
+ purpose.pValue = (void *)oid_str;
+ purpose.ulValueLen = strlen (oid_str);
+
+ object = p11_attrs_build (NULL, &klass, &token, &private, &modifiable,
+ id, label, &assertion_type, &purpose,
+ issuer, serial, value, NULL);
+ return_if_fail (object != NULL);
+
+ if (!p11_array_push (parsing, object))
+ return_if_reached ();
+ }
+}
+
+static void
+build_trust_assertions (p11_parser *parser,
+ p11_array *parsing,
+ CK_ATTRIBUTE *cert,
+ CK_BBOOL trust,
+ CK_BBOOL distrust,
+ CK_BBOOL authority,
+ p11_dict *purposes,
+ p11_dict *rejects)
+{
+ p11_dictiter iter;
+
+ const char *all_purposes[] = {
+ P11_OID_SERVER_AUTH_STR,
+ P11_OID_CLIENT_AUTH_STR,
+ P11_OID_CODE_SIGNING_STR,
+ P11_OID_EMAIL_PROTECTION_STR,
+ P11_OID_IPSEC_END_SYSTEM_STR,
+ P11_OID_IPSEC_TUNNEL_STR,
+ P11_OID_IPSEC_USER_STR,
+ P11_OID_TIME_STAMPING_STR,
+ NULL,
+ };
+
+ /* Build assertions for anything that's explicitly rejected */
+ if (rejects) {
+ p11_dict_iterate (rejects, &iter);
+ build_assertions (parser, parsing, cert, CKT_X_DISTRUSTED_CERTIFICATE,
+ yield_oid_from_dict, &iter);
+ }
+
+ if (distrust) {
+ /*
+ * Trust assertions are defficient in that they don't blacklist a certificate
+ * for any purposes. So we just have to go wild and write out a bunch of
+ * assertions for all our known purposes.
+ */
+ build_assertions (parser, parsing, cert, CKT_X_DISTRUSTED_CERTIFICATE,
+ yield_oid_from_vec, all_purposes);
+ }
+
+ /*
+ * TODO: Build pinned certificate assertions. That is, trusted
+ * certificates where not an authority.
+ */
+
+ if (trust && authority) {
+ if (purposes) {
+ /* If purposes explicitly set, then anchor for those purposes */
+ p11_dict_iterate (purposes, &iter);
+ build_assertions (parser, parsing, cert, CKT_X_ANCHORED_CERTIFICATE,
+ yield_oid_from_dict, &iter);
+ } else {
+ /* If purposes not-explicitly set, then anchor for all known */
+ build_assertions (parser, parsing, cert, CKT_X_ANCHORED_CERTIFICATE,
+ yield_oid_from_vec, all_purposes);
+ }
+ }
+}
+
+void
+p11_adapter_build_objects (p11_parser *parser,
+ p11_array *parsing)
+{
+ CK_ATTRIBUTE *cert;
+ CK_ULONG category;
+ CK_BBOOL trust = CK_FALSE;
+ CK_BBOOL distrust = CK_FALSE;
+ CK_BBOOL authority = CK_FALSE;
+ p11_dict *purposes = NULL;
+ p11_dict *rejects = NULL;
+ unsigned char *data;
+ p11_dict *defs;
+ size_t length;
+
+ cert = p11_parsing_get_certificate (parser, parsing);
+ return_if_fail (cert != NULL);
+
+ /*
+ * We look up all this information in advance, since it's used
+ * by the various adapter objects, and we don't have to parse
+ * it multiple times.
+ */
+
+ if (!p11_attrs_find_bool (cert, CKA_TRUSTED, &trust))
+ trust = CK_FALSE;
+ if (!p11_attrs_find_bool (cert, CKA_X_DISTRUSTED, &distrust))
+ distrust = CK_FALSE;
+ if (p11_attrs_find_ulong (cert, CKA_CERTIFICATE_CATEGORY, &category) && category == 2)
+ authority = CK_TRUE;
+
+ if (!distrust) {
+ data = p11_parsing_get_extension (parser, parsing, P11_OID_EXTENDED_KEY_USAGE, &length);
+ if (data) {
+ defs = p11_parser_get_asn1_defs (parser);
+ purposes = p11_x509_parse_extended_key_usage (defs, data, length);
+ if (purposes == NULL)
+ p11_message ("invalid extended key usage certificate extension");
+ free (data);
+ }
+
+ data = p11_parsing_get_extension (parser, parsing, P11_OID_OPENSSL_REJECT, &length);
+ if (data) {
+ defs = p11_parser_get_asn1_defs (parser);
+ rejects = p11_x509_parse_extended_key_usage (defs, data, length);
+ if (rejects == NULL)
+ p11_message ("invalid reject key usage certificate extension");
+ free (data);
+ }
+ }
+
+ build_nss_trust_object (parser, parsing, cert, trust, distrust,
+ authority, purposes, rejects);
+ build_trust_assertions (parser, parsing, cert, trust, distrust,
+ authority, purposes, rejects);
+
+ p11_dict_free (purposes);
+ p11_dict_free (rejects);
+}
diff --git a/trust/mozilla.h b/trust/adapter.h
index 8d5b20a..fb4ad4e 100644
--- a/trust/mozilla.h
+++ b/trust/adapter.h
@@ -35,10 +35,10 @@
#include "array.h"
#include "parser.h"
-#ifndef P11_MOZILLA_H_
-#define P11_MOZILLA_H_
+#ifndef P11_ADAPTER_H_
+#define P11_ADAPTER_H_
-void p11_mozilla_build_trust_object (p11_parser *parser,
+void p11_adapter_build_objects (p11_parser *parser,
p11_array *parsing);
-#endif
+#endif /* P11_ADAPTER_H_ */
diff --git a/trust/p11-kit-trust.module b/trust/p11-kit-trust.module
index ad0f254..1a6e94b 100644
--- a/trust/p11-kit-trust.module
+++ b/trust/p11-kit-trust.module
@@ -4,3 +4,6 @@ module: p11-kit-trust.so
# The order in which this is loaded in the trust policy
trust-policy: 1
+
+# This is for drop-in compatibilty with glib-networking and gcr
+x-trust-lookup: pkcs11:library-description=PKCS%2311%20Kit%20Trust%20Module
diff --git a/trust/parser.c b/trust/parser.c
index d33babb..4f8c407 100644
--- a/trust/parser.c
+++ b/trust/parser.c
@@ -34,6 +34,7 @@
#include "config.h"
+#include "adapter.h"
#include "array.h"
#include "asn1.h"
#include "attrs.h"
@@ -43,7 +44,6 @@
#include "dict.h"
#include "library.h"
#include "module.h"
-#include "mozilla.h"
#include "oid.h"
#include "parser.h"
#include "pem.h"
@@ -120,7 +120,7 @@ finish_parsing (p11_parser *parser,
p11_parsing_update_certificate (parser, parser->parsing);
/* Call all the hooks for generating further objects */
- p11_mozilla_build_trust_object (parser, parser->parsing);
+ p11_adapter_build_objects (parser, parser->parsing);
for (i = 0; i < parser->parsing->num; i++) {
attrs = parser->parsing->elem[i];
@@ -771,7 +771,6 @@ update_trust_and_distrust (p11_parser *parser,
trusted = (parser->flags & P11_PARSE_FLAG_ANCHOR) ? CK_TRUE : CK_FALSE;
distrusted = (parser->flags & P11_PARSE_FLAG_BLACKLIST) ? CK_TRUE : CK_FALSE;
- /* See if we have a basic constraints extension */
data = p11_parsing_get_extension (parser, parser->parsing, P11_OID_EXTENDED_KEY_USAGE, &length);
if (data) {
ekus = p11_x509_parse_extended_key_usage (parser->asn1_defs, data, length);
diff --git a/trust/tests/files/redhat-ca.der b/trust/tests/files/redhat-ca.der
new file mode 100644
index 0000000..affae24
--- /dev/null
+++ b/trust/tests/files/redhat-ca.der
Binary files differ
diff --git a/trust/tests/test-parser.c b/trust/tests/test-parser.c
index 80f0f07..a504cab 100644
--- a/trust/tests/test-parser.c
+++ b/trust/tests/test-parser.c
@@ -159,6 +159,9 @@ test_parse_openssl_trusted (CuTest *cu)
CK_TRUST unknown = CKT_NETSCAPE_TRUST_UNKNOWN;
CK_OBJECT_CLASS certificate_extension = CKO_X_CERTIFICATE_EXTENSION;
CK_OBJECT_CLASS trust_object = CKO_NETSCAPE_TRUST;
+ CK_OBJECT_CLASS trust_assertion = CKO_X_TRUST_ASSERTION;
+ CK_X_ASSERTION_TYPE anchored_certificate = CKT_X_ANCHORED_CERTIFICATE;
+ CK_X_ASSERTION_TYPE distrusted_certificate = CKT_X_DISTRUSTED_CERTIFICATE;
CK_BBOOL vtrue = CK_TRUE;
CK_BBOOL vfalse = CK_FALSE;
@@ -207,10 +210,49 @@ test_parse_openssl_trusted (CuTest *cu)
{ CKA_INVALID, }
};
+ CK_ATTRIBUTE server_anchor[] = {
+ { CKA_LABEL, "Custom Label", 12 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) },
+ { CKA_X_ASSERTION_TYPE, &anchored_certificate, sizeof (anchored_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_SERVER_AUTH_STR, strlen (P11_OID_SERVER_AUTH_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE client_anchor[] = {
+ { CKA_LABEL, "Custom Label", 12 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) },
+ { CKA_X_ASSERTION_TYPE, &anchored_certificate, sizeof (anchored_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_CLIENT_AUTH_STR, strlen (P11_OID_CLIENT_AUTH_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE email_distrust[] = {
+ { CKA_LABEL, "Custom Label", 12 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_ISSUER, (void *)test_cacert3_ca_issuer, sizeof (test_cacert3_ca_issuer) },
+ { CKA_SERIAL_NUMBER, (void *)test_cacert3_ca_serial, sizeof (test_cacert3_ca_serial) },
+ { CKA_X_ASSERTION_TYPE, &distrusted_certificate, sizeof (distrusted_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_EMAIL_PROTECTION_STR, strlen (P11_OID_EMAIL_PROTECTION_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE *expected[] = {
+ NULL,
+ eku_extension,
+ reject_extension,
+ nss_trust,
+ email_distrust,
+ server_anchor,
+ client_anchor
+ };
+
CK_ATTRIBUTE *cert;
CK_ATTRIBUTE *object;
CK_BBOOL bval;
int ret;
+ int i;
setup (cu);
@@ -218,9 +260,16 @@ test_parse_openssl_trusted (CuTest *cu)
P11_PARSE_FLAG_ANCHOR, on_parse_object, cu);
CuAssertIntEquals (cu, P11_PARSE_SUCCESS, ret);
- /* Should have gotten certificate, two stapled extensions, and a trust object */
- CuAssertIntEquals (cu, 4, test.objects->num);
+ /*
+ * Should have gotten:
+ * - 1 certificate
+ * - 2 stapled extensions
+ * - 1 trust object
+ * - 3 trust assertions
+ */
+ CuAssertIntEquals (cu, 7, test.objects->num);
+ /* The certificate */
cert = test.objects->elem[0];
test_check_cacert3_ca (cu, cert, NULL);
@@ -232,17 +281,12 @@ test_parse_openssl_trusted (CuTest *cu)
CuFail (cu, "missing CKA_X_DISTRUSTED");
CuAssertIntEquals (cu, CK_FALSE, bval);
- object = test.objects->elem[1];
- test_check_attrs (cu, eku_extension, object);
- test_check_id (cu, cert, object);
-
- object = test.objects->elem[2];
- test_check_attrs (cu, reject_extension, object);
- test_check_id (cu, cert, object);
-
- object = test.objects->elem[3];
- test_check_attrs (cu, nss_trust, object);
- test_check_id (cu, cert, object);
+ /* The other objects */
+ for (i = 1; i < 7; i++) {
+ object = test.objects->elem[i];
+ test_check_attrs (cu, expected[i], object);
+ test_check_id (cu, cert, object);
+ }
teardown (cu);
}
@@ -254,6 +298,8 @@ test_parse_openssl_distrusted (CuTest *cu)
CK_OBJECT_CLASS certificate_extension = CKO_X_CERTIFICATE_EXTENSION;
CK_OBJECT_CLASS trust_object = CKO_NETSCAPE_TRUST;
CK_OBJECT_CLASS klass = CKO_CERTIFICATE;
+ CK_OBJECT_CLASS trust_assertion = CKO_X_TRUST_ASSERTION;
+ CK_X_ASSERTION_TYPE distrusted_certificate = CKT_X_DISTRUSTED_CERTIFICATE;
CK_CERTIFICATE_TYPE x509 = CKC_X_509;
CK_ULONG category = 2; /* authority */
CK_BBOOL vtrue = CK_TRUE;
@@ -319,9 +365,122 @@ test_parse_openssl_distrusted (CuTest *cu)
{ CKA_INVALID, }
};
+ unsigned char red_hat_issuer[] = {
+ 0x30, 0x81, 0x9d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+ 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0e, 0x4e, 0x6f, 0x72, 0x74, 0x68,
+ 0x20, 0x43, 0x61, 0x72, 0x6f, 0x6c, 0x69, 0x6e, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x13, 0x07, 0x52, 0x61, 0x6c, 0x65, 0x69, 0x67, 0x68, 0x31, 0x16, 0x30, 0x14, 0x06,
+ 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x52, 0x65, 0x64, 0x20, 0x48, 0x61, 0x74, 0x2c, 0x20, 0x49,
+ 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x02, 0x49, 0x53,
+ 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x52, 0x65, 0x64, 0x20, 0x48,
+ 0x61, 0x74, 0x20, 0x49, 0x53, 0x20, 0x43, 0x41, 0x31, 0x26, 0x30, 0x24, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x17, 0x73, 0x79, 0x73, 0x61, 0x64, 0x6d, 0x69,
+ 0x6e, 0x2d, 0x72, 0x64, 0x75, 0x40, 0x72, 0x65, 0x64, 0x68, 0x61, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+ };
+
+ unsigned char red_hat_serial[] = {
+ 0x02, 0x01, 0x01,
+ };
+
+ CK_ATTRIBUTE server_distrust[] = {
+ { CKA_LABEL, "Red Hat Is the CA", 17 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_ISSUER, (void *)red_hat_issuer, sizeof (red_hat_issuer) },
+ { CKA_SERIAL_NUMBER, (void *)red_hat_serial, sizeof (red_hat_serial) },
+ { CKA_X_ASSERTION_TYPE, &distrusted_certificate, sizeof (distrusted_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_SERVER_AUTH_STR, strlen (P11_OID_SERVER_AUTH_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE client_distrust[] = {
+ { CKA_LABEL, "Red Hat Is the CA", 17 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_ISSUER, (void *)red_hat_issuer, sizeof (red_hat_issuer) },
+ { CKA_SERIAL_NUMBER, (void *)red_hat_serial, sizeof (red_hat_serial) },
+ { CKA_X_ASSERTION_TYPE, &distrusted_certificate, sizeof (distrusted_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_CLIENT_AUTH_STR, strlen (P11_OID_CLIENT_AUTH_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE code_distrust[] = {
+ { CKA_LABEL, "Red Hat Is the CA", 17 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_ISSUER, (void *)red_hat_issuer, sizeof (red_hat_issuer) },
+ { CKA_SERIAL_NUMBER, (void *)red_hat_serial, sizeof (red_hat_serial) },
+ { CKA_X_ASSERTION_TYPE, &distrusted_certificate, sizeof (distrusted_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_CODE_SIGNING_STR, strlen (P11_OID_CODE_SIGNING_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE email_distrust[] = {
+ { CKA_LABEL, "Red Hat Is the CA", 17 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_ISSUER, (void *)red_hat_issuer, sizeof (red_hat_issuer) },
+ { CKA_SERIAL_NUMBER, (void *)red_hat_serial, sizeof (red_hat_serial) },
+ { CKA_X_ASSERTION_TYPE, &distrusted_certificate, sizeof (distrusted_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_EMAIL_PROTECTION_STR, strlen (P11_OID_EMAIL_PROTECTION_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE ipsec_system_distrust[] = {
+ { CKA_LABEL, "Red Hat Is the CA", 17 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_ISSUER, (void *)red_hat_issuer, sizeof (red_hat_issuer) },
+ { CKA_SERIAL_NUMBER, (void *)red_hat_serial, sizeof (red_hat_serial) },
+ { CKA_X_ASSERTION_TYPE, &distrusted_certificate, sizeof (distrusted_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_IPSEC_END_SYSTEM_STR, strlen (P11_OID_IPSEC_END_SYSTEM_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE ipsec_tunnel_distrust[] = {
+ { CKA_LABEL, "Red Hat Is the CA", 17 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_ISSUER, (void *)red_hat_issuer, sizeof (red_hat_issuer) },
+ { CKA_SERIAL_NUMBER, (void *)red_hat_serial, sizeof (red_hat_serial) },
+ { CKA_X_ASSERTION_TYPE, &distrusted_certificate, sizeof (distrusted_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_IPSEC_TUNNEL_STR, strlen (P11_OID_IPSEC_TUNNEL_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE ipsec_user_distrust[] = {
+ { CKA_LABEL, "Red Hat Is the CA", 17 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_ISSUER, (void *)red_hat_issuer, sizeof (red_hat_issuer) },
+ { CKA_SERIAL_NUMBER, (void *)red_hat_serial, sizeof (red_hat_serial) },
+ { CKA_X_ASSERTION_TYPE, &distrusted_certificate, sizeof (distrusted_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_IPSEC_USER_STR, strlen (P11_OID_IPSEC_USER_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE stamping_distrust[] = {
+ { CKA_LABEL, "Red Hat Is the CA", 17 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_ISSUER, (void *)red_hat_issuer, sizeof (red_hat_issuer) },
+ { CKA_SERIAL_NUMBER, (void *)red_hat_serial, sizeof (red_hat_serial) },
+ { CKA_X_ASSERTION_TYPE, &distrusted_certificate, sizeof (distrusted_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_TIME_STAMPING_STR, strlen (P11_OID_TIME_STAMPING_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE *expected[] = {
+ certificate,
+ eku_extension,
+ reject_extension,
+ nss_trust,
+ server_distrust,
+ client_distrust,
+ code_distrust,
+ email_distrust,
+ ipsec_system_distrust,
+ ipsec_tunnel_distrust,
+ ipsec_user_distrust,
+ stamping_distrust,
+ };
+
CK_ATTRIBUTE *cert;
CK_ATTRIBUTE *object;
int ret;
+ int i;
setup (cu);
@@ -333,23 +492,22 @@ test_parse_openssl_distrusted (CuTest *cu)
P11_PARSE_FLAG_ANCHOR, on_parse_object, cu);
CuAssertIntEquals (cu, P11_PARSE_SUCCESS, ret);
- /* Should have gotten certificate, one stapled extensions, and a trust object */
- CuAssertIntEquals (cu, 4, test.objects->num);
-
+ /*
+ * Should have gotten:
+ * - 1 certificate
+ * - 2 stapled extensions
+ * - 1 trust object
+ * - 8 trust assertions
+ */
+ CuAssertIntEquals (cu, 12, test.objects->num);
cert = test.objects->elem[0];
- test_check_attrs (cu, certificate, cert);
-
- object = test.objects->elem[1];
- test_check_attrs (cu, eku_extension, object);
- test_check_id (cu, cert, object);
-
- object = test.objects->elem[2];
- test_check_attrs (cu, reject_extension, object);
- test_check_id (cu, cert, object);
- object = test.objects->elem[3];
- test_check_attrs (cu, nss_trust, object);
- test_check_id (cu, cert, object);
+ /* The other objects */
+ for (i = 0; i < 12; i++) {
+ object = test.objects->elem[i];
+ test_check_attrs (cu, expected[i], object);
+ test_check_id (cu, cert, object);
+ }
teardown (cu);
}
@@ -447,12 +605,129 @@ test_parse_with_key_usage (CuTest *cu)
static void
test_parse_anchor (CuTest *cu)
{
+ CK_BBOOL vtrue = CK_TRUE;
+ CK_OBJECT_CLASS trust_object = CKO_NETSCAPE_TRUST;
+ CK_ATTRIBUTE trusted = { CKA_TRUSTED, &vtrue, sizeof (vtrue) };
+ CK_TRUST delegator = CKT_NETSCAPE_TRUSTED_DELEGATOR;
+ CK_OBJECT_CLASS trust_assertion = CKO_X_TRUST_ASSERTION;
+ CK_X_ASSERTION_TYPE anchored_certificate = CKT_X_ANCHORED_CERTIFICATE;
+
+ CK_ATTRIBUTE nss_trust[] = {
+ { CKA_LABEL, "cacert3.der", 11 },
+ { CKA_CLASS, &trust_object, sizeof (trust_object), },
+ { CKA_CERT_SHA1_HASH, "\xad\x7c\x3f\x64\xfc\x44\x39\xfe\xf4\xe9\x0b\xe8\xf4\x7c\x6c\xfa\x8a\xad\xfd\xce", 20 },
+ { CKA_CERT_MD5_HASH, "\xf7\x25\x12\x82\x4e\x67\xb5\xd0\x8d\x92\xb7\x7c\x0b\x86\x7a\x42", 16 },
+ { CKA_ISSUER, (void *)test_cacert3_ca_issuer, sizeof (test_cacert3_ca_issuer) },
+ { CKA_SUBJECT, (void *)test_cacert3_ca_subject, sizeof (test_cacert3_ca_subject) },
+ { CKA_SERIAL_NUMBER, (void *)test_cacert3_ca_serial, sizeof (test_cacert3_ca_serial) },
+ { CKA_TRUST_SERVER_AUTH, &delegator, sizeof (delegator) },
+ { CKA_TRUST_CLIENT_AUTH, &delegator, sizeof (delegator) },
+ { CKA_TRUST_EMAIL_PROTECTION, &delegator, sizeof (delegator) },
+ { CKA_TRUST_CODE_SIGNING, &delegator, sizeof (delegator) },
+ { CKA_TRUST_IPSEC_END_SYSTEM, &delegator, sizeof (delegator) },
+ { CKA_TRUST_IPSEC_TUNNEL, &delegator, sizeof (delegator) },
+ { CKA_TRUST_IPSEC_USER, &delegator, sizeof (delegator) },
+ { CKA_TRUST_TIME_STAMPING, &delegator, sizeof (delegator) },
+ { CKA_TRUST_DIGITAL_SIGNATURE, &delegator, sizeof (delegator) },
+ { CKA_TRUST_NON_REPUDIATION, &delegator, sizeof (delegator) },
+ { CKA_TRUST_KEY_ENCIPHERMENT, &delegator, sizeof (delegator) },
+ { CKA_TRUST_DATA_ENCIPHERMENT, &delegator, sizeof (delegator) },
+ { CKA_TRUST_KEY_AGREEMENT, &delegator, sizeof (delegator) },
+ { CKA_TRUST_KEY_CERT_SIGN, &delegator, sizeof (delegator) },
+ { CKA_TRUST_CRL_SIGN, &delegator, sizeof (delegator) },
+ { CKA_INVALID, }
+ };
+
+ CK_ATTRIBUTE server_anchor[] = {
+ { CKA_LABEL, "cacert3.der", 11 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) },
+ { CKA_X_ASSERTION_TYPE, &anchored_certificate, sizeof (anchored_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_SERVER_AUTH_STR, strlen (P11_OID_SERVER_AUTH_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE client_anchor[] = {
+ { CKA_LABEL, "cacert3.der", 11 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) },
+ { CKA_X_ASSERTION_TYPE, &anchored_certificate, sizeof (anchored_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_CLIENT_AUTH_STR, strlen (P11_OID_CLIENT_AUTH_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE code_anchor[] = {
+ { CKA_LABEL, "cacert3.der", 11 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) },
+ { CKA_X_ASSERTION_TYPE, &anchored_certificate, sizeof (anchored_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_CODE_SIGNING_STR, strlen (P11_OID_CODE_SIGNING_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE email_anchor[] = {
+ { CKA_LABEL, "cacert3.der", 11 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) },
+ { CKA_X_ASSERTION_TYPE, &anchored_certificate, sizeof (anchored_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_EMAIL_PROTECTION_STR, strlen (P11_OID_EMAIL_PROTECTION_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE ipsec_system_anchor[] = {
+ { CKA_LABEL, "cacert3.der", 11 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) },
+ { CKA_X_ASSERTION_TYPE, &anchored_certificate, sizeof (anchored_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_IPSEC_END_SYSTEM_STR, strlen (P11_OID_IPSEC_END_SYSTEM_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE ipsec_tunnel_anchor[] = {
+ { CKA_LABEL, "cacert3.der", 11 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) },
+ { CKA_X_ASSERTION_TYPE, &anchored_certificate, sizeof (anchored_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_IPSEC_TUNNEL_STR, strlen (P11_OID_IPSEC_TUNNEL_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE ipsec_user_anchor[] = {
+ { CKA_LABEL, "cacert3.der", 11 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) },
+ { CKA_X_ASSERTION_TYPE, &anchored_certificate, sizeof (anchored_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_IPSEC_USER_STR, strlen (P11_OID_IPSEC_USER_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE stamping_anchor[] = {
+ { CKA_LABEL, "cacert3.der", 11 },
+ { CKA_CLASS, &trust_assertion, sizeof (trust_assertion) },
+ { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) },
+ { CKA_X_ASSERTION_TYPE, &anchored_certificate, sizeof (anchored_certificate) },
+ { CKA_X_PURPOSE, (void *)P11_OID_TIME_STAMPING_STR, strlen (P11_OID_TIME_STAMPING_STR) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE *expected[] = {
+ NULL,
+ nss_trust,
+ server_anchor,
+ client_anchor,
+ code_anchor,
+ email_anchor,
+ ipsec_system_anchor,
+ ipsec_tunnel_anchor,
+ ipsec_user_anchor,
+ stamping_anchor,
+ };
+
CK_ATTRIBUTE *cert;
CK_ATTRIBUTE *object;
CK_ATTRIBUTE *attr;
- CK_BBOOL vtrue = CK_TRUE;
- CK_ATTRIBUTE trusted = { CKA_TRUSTED, &vtrue, sizeof (vtrue) };
int ret;
+ int i;
setup (cu);
@@ -460,17 +735,24 @@ test_parse_anchor (CuTest *cu)
P11_PARSE_FLAG_ANCHOR, on_parse_object, cu);
CuAssertIntEquals (cu, P11_PARSE_SUCCESS, ret);
- /* Should have gotten a certificate and a trust object */
- CuAssertIntEquals (cu, 2, test.objects->num);
+ /*
+ * Should have gotten:
+ * - 1 certificate
+ * - 1 trust object
+ * - 8 trust assertions
+ */
+ CuAssertIntEquals (cu, 10, test.objects->num);
cert = test.objects->elem[0];
test_check_cacert3_ca (cu, cert, NULL);
-
attr = p11_attrs_find (cert, CKA_TRUSTED);
test_check_attr (cu, &trusted, attr);
- object = test.objects->elem[1];
- test_check_id (cu, cert, object);
+ for (i = 1; i < 10; i++) {
+ object = test.objects->elem[i];
+ test_check_attrs (cu, expected[i], object);
+ test_check_id (cu, cert, object);
+ }
teardown (cu);
}