summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/oid.h9
-rw-r--r--trust/mozilla.c74
-rw-r--r--trust/parser.c351
-rw-r--r--trust/parser.h11
-rw-r--r--trust/tests/test-data.c18
-rw-r--r--trust/tests/test-data.h9
-rw-r--r--trust/tests/test-parser.c246
-rw-r--r--trust/tests/test-token.c2
8 files changed, 552 insertions, 168 deletions
diff --git a/common/oid.h b/common/oid.h
index b0c8538..181539a 100644
--- a/common/oid.h
+++ b/common/oid.h
@@ -105,8 +105,7 @@ static const unsigned char P11_OID_EXTENDED_KEY_USAGE[] =
* The normal X.509 model is to only *include* the extended key
* usages that are to be allowed (ie: a whitelist). It's not clear
* exactly how valid and useful the reject per extended key usage
- * model is. In fact, it appears that openssl does not use this
- * information.
+ * model is.
*
* However in order to parse openssl trust policy information and
* be able to write it back out in the same way, we define a custom
@@ -196,10 +195,10 @@ static const unsigned char P11_OID_TIME_STAMPING[] =
* be a place holder when no other purposes are defined.
*
* In theory such a certificate should be blacklisted. But in reality
- * OpenSSL supports such empty sets of purposes. RFC 5280 requires at
- * least one purpose in an ExtendedKeyUsage.
+ * many implementations use such empty sets of purposes. RFC 5280 requires
+ * at least one purpose in an ExtendedKeyUsage.
*
- * This purpose should never be used or checked.
+ * Obviously this purpose should never be checked against.
*/
static const unsigned char P11_OID_RESERVED_PURPOSE[] =
{ 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x99, 0x77, 0x06, 0x0a, 0x10 };
diff --git a/trust/mozilla.c b/trust/mozilla.c
index cd8ff25..fd5e287 100644
--- a/trust/mozilla.c
+++ b/trust/mozilla.c
@@ -53,12 +53,12 @@
static CK_ATTRIBUTE *
update_ku (p11_parser *parser,
p11_array *parsing,
- CK_ATTRIBUTE *object)
+ CK_ATTRIBUTE *object,
+ CK_TRUST present)
{
- unsigned char *data;
+ unsigned char *data = NULL;
unsigned int ku = 0;
size_t length;
- CK_TRUST present;
CK_TRUST defawlt;
CK_ULONG i;
@@ -78,22 +78,20 @@ update_ku (p11_parser *parser,
CK_ATTRIBUTE attrs[sizeof (ku_attribute_map)];
- if (p11_parsing_get_flags (parser) & P11_PARSE_FLAG_ANCHOR)
- present = CKT_NETSCAPE_TRUSTED_DELEGATOR;
- else
- present = CKT_NETSCAPE_TRUSTED;
defawlt = present;
- data = p11_parsing_get_extension (parser, parsing, P11_OID_KEY_USAGE, &length);
-
- /*
- * 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.
- */
+ /* 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;
+
if (p11_parse_key_usage (parser, data, length, &ku) != P11_PARSE_SUCCESS)
p11_message ("invalid key usage certificate extension");
free (data);
@@ -116,12 +114,12 @@ update_ku (p11_parser *parser,
static CK_ATTRIBUTE *
update_eku (p11_parser *parser,
p11_array *parsing,
- CK_ATTRIBUTE *object)
+ CK_ATTRIBUTE *object,
+ CK_TRUST trust)
{
- CK_TRUST trust;
CK_TRUST defawlt;
CK_TRUST distrust;
- unsigned char *data;
+ unsigned char *data = NULL;
p11_dict *ekus = NULL;
p11_dict *reject = NULL;
size_t length;
@@ -145,28 +143,24 @@ update_eku (p11_parser *parser,
CK_ATTRIBUTE attrs[sizeof (eku_attribute_map)];
- /* The value set if an eku is present */
- if (p11_parsing_get_flags (parser) & P11_PARSE_FLAG_ANCHOR)
- trust = CKT_NETSCAPE_TRUSTED_DELEGATOR;
- else
- trust= CKT_NETSCAPE_TRUSTED;
-
/* The value set if an eku is not present, adjusted below */
defawlt = trust;
/* The value set if an eku is explictly rejected */
distrust = CKT_NETSCAPE_UNTRUSTED;
- /*
- * If the certificate extension was missing, then *all* extended key
- * usages are to be set. If the extension was invalid, then
- * fail safe to none of the extended key usages.
- */
-
- data = p11_parsing_get_extension (parser, parsing, P11_OID_EXTENDED_KEY_USAGE, &length);
+ /* If blacklisted, don't even bother looking at extensions */
+ if (trust != CKT_NETSCAPE_UNTRUSTED)
+ data = p11_parsing_get_extension (parser, parsing, P11_OID_EXTENDED_KEY_USAGE, &length);
if (data) {
+ /*
+ * If the certificate extension was missing, then *all* extended key
+ * usages are to be set. If the extension was invalid, then
+ * fail safe to none of the extended key usages.
+ */
defawlt = CKT_NETSCAPE_TRUST_UNKNOWN;
+
ekus = p11_parse_extended_key_usage (parser, data, length);
if (ekus == NULL)
p11_message ("invalid extended key usage certificate extension");
@@ -208,6 +202,9 @@ build_nss_trust_object (p11_parser *parser,
CK_ATTRIBUTE *cert)
{
CK_ATTRIBUTE *object = NULL;
+ CK_TRUST trust;
+ CK_ULONG category;
+ CK_BBOOL bval;
CK_OBJECT_CLASS vclass = CKO_NETSCAPE_TRUST;
CK_BYTE vsha1_hash[P11_CHECKSUM_SHA1_LENGTH];
@@ -259,10 +256,23 @@ build_nss_trust_object (p11_parser *parser,
&step_up_approved, NULL);
return_val_if_fail (object != NULL, NULL);
- object = update_ku (parser, parsing, object);
+ /* Calculate the default trust */
+ trust = CKT_NETSCAPE_TRUST_UNKNOWN;
+
+ if (p11_attrs_find_bool (cert, CKA_TRUSTED, &bval) && bval) {
+ if (p11_attrs_find_ulong (cert, CKA_CERTIFICATE_CATEGORY, &category) && category == 2)
+ trust = CKT_NETSCAPE_TRUSTED_DELEGATOR;
+ else
+ trust = CKT_NETSCAPE_TRUSTED;
+ }
+
+ if (p11_attrs_find_bool (cert, CKA_X_DISTRUSTED, &bval) && bval)
+ trust = CKT_NETSCAPE_UNTRUSTED;
+
+ object = update_ku (parser, parsing, object, trust);
return_val_if_fail (object != NULL, NULL);
- object = update_eku (parser, parsing, object);
+ object = update_eku (parser, parsing, object, trust);
return_val_if_fail (object != NULL, NULL);
if (!p11_array_push (parsing, object))
diff --git a/trust/parser.c b/trust/parser.c
index 3a81dcd..28464fd 100644
--- a/trust/parser.c
+++ b/trust/parser.c
@@ -163,6 +163,9 @@ finish_parsing (p11_parser *parser,
/* This is a double check */
return_if_fail (parser->cert_asn == cert_asn);
+ /* Update the certificate state */
+ p11_parsing_update_certificate (parser, parser->parsing);
+
/* Call all the hooks for generating further objects */
p11_mozilla_build_trust_object (parser, parser->parsing);
@@ -579,29 +582,6 @@ calc_date (node_asn *cert,
}
static bool
-calc_trusted (p11_parser *parser,
- node_asn *cert,
- CK_BBOOL *vtrusted)
-{
- assert (parser != NULL);
- assert (vtrusted != NULL);
-
- /*
- * This calculates CKA_TRUSTED, which is a silly attribute, don't
- * read too much into this. The real trust mechinisms are elsewhere.
- */
-
- *vtrusted = CK_FALSE;
- if (parser->flags & P11_PARSE_FLAG_ANCHOR) {
- *vtrusted = CK_TRUE;
- return true;
- }
-
- /* Don't add this attribute unless anchor */
- return false;
-}
-
-static bool
calc_element (node_asn *el,
const unsigned char *data,
size_t length,
@@ -631,18 +611,21 @@ build_x509_certificate (p11_parser *parser,
CK_CERTIFICATE_TYPE vx509 = CKC_X_509;
CK_BYTE vchecksum[3];
- /* TODO: Implement */
- CK_ULONG vcategory = 0;
- CK_BBOOL vtrusted = CK_FALSE;
CK_DATE vstart;
CK_DATE vend;
+ /* Filled in later */
+ CK_ULONG vcategory = 0;
+ CK_BBOOL vtrusted = CK_FALSE;
+ CK_BBOOL vdistrusted = CK_FALSE;
+
CK_ATTRIBUTE certificate_type = { CKA_CERTIFICATE_TYPE, &vx509, sizeof (vx509) };
CK_ATTRIBUTE certificate_category = { CKA_CERTIFICATE_CATEGORY, &vcategory, sizeof (vcategory) };
CK_ATTRIBUTE value = { CKA_VALUE, (void *)data, length };
CK_ATTRIBUTE check_value = { CKA_CHECK_VALUE, &vchecksum, sizeof (vchecksum) };
CK_ATTRIBUTE trusted = { CKA_TRUSTED, &vtrusted, sizeof (vtrusted) };
+ CK_ATTRIBUTE distrusted = { CKA_X_DISTRUSTED, &vdistrusted, sizeof (vdistrusted) };
CK_ATTRIBUTE start_date = { CKA_START_DATE, &vstart, sizeof (vstart) };
CK_ATTRIBUTE end_date = { CKA_END_DATE, &vend, sizeof (vend) };
CK_ATTRIBUTE subject = { CKA_SUBJECT, };
@@ -659,10 +642,6 @@ build_x509_certificate (p11_parser *parser,
calc_check_value (data, length, vchecksum);
- /* This is a silly trust flag, we set it if the cert is an anchor */
- if (!calc_trusted (parser, cert, &vtrusted))
- trusted.type = CKA_INVALID;
-
if (!calc_date (cert, "tbsCertificate.validity.notBefore", &vstart))
start_date.type = CKA_INVALID;
if (!calc_date (cert, "tbsCertificate.validity.notAfter", &vend))
@@ -679,7 +658,7 @@ build_x509_certificate (p11_parser *parser,
return_val_if_fail (attrs != NULL, NULL);
attrs = p11_attrs_build (attrs, &certificate_type, &certificate_category,
- &check_value, &trusted, &start_date, &end_date,
+ &check_value, &trusted, &distrusted, &start_date, &end_date,
&subject, &issuer, &serial_number, &value,
NULL);
return_val_if_fail (attrs != NULL, NULL);
@@ -802,13 +781,6 @@ p11_parsing_get_extension (p11_parser *parser,
return NULL;
}
-int
-p11_parsing_get_flags (p11_parser *parser)
-{
- return_val_if_fail (parser != NULL, 0);
- return parser->flags;
-}
-
CK_ATTRIBUTE *
p11_parsing_get_certificate (p11_parser *parser,
p11_array *parsing)
@@ -827,6 +799,32 @@ p11_parsing_get_certificate (p11_parser *parser,
}
int
+p11_parse_basic_constraints (p11_parser *parser,
+ const unsigned char *data,
+ size_t length,
+ int *is_ca)
+{
+ char buffer[8];
+ node_asn *ext;
+ int ret;
+ int len;
+
+ return_val_if_fail (is_ca != NULL, P11_PARSE_FAILURE);
+
+ ext = decode_asn1 (parser, "PKIX1.BasicConstraints", data, length, NULL);
+ return_val_if_fail (ext != NULL, P11_PARSE_UNRECOGNIZED);
+
+ len = sizeof (buffer);
+ ret = asn1_read_value (ext, "cA", buffer, &len);
+ return_val_if_fail (ret == ASN1_SUCCESS, P11_PARSE_FAILURE);
+
+ *is_ca = (strcmp (buffer, "TRUE") == 0);
+ asn1_delete_structure (&ext);
+
+ return P11_PARSE_SUCCESS;
+}
+
+int
p11_parse_key_usage (p11_parser *parser,
const unsigned char *data,
size_t length,
@@ -888,6 +886,10 @@ p11_parse_extended_key_usage (p11_parser *parser,
if (!p11_oid_simple (eku_der + start, (end - start) + 1))
continue;
+ /* If it's our reserved OID, then skip */
+ if (p11_oid_equal (eku_der + start, P11_OID_RESERVED_PURPOSE))
+ continue;
+
eku = memdup (eku_der + start, (end - start) + 1);
return_val_if_fail (eku != NULL, NULL);
@@ -950,12 +952,12 @@ calc_der_length (const unsigned char *data,
}
static int
-build_stapled_extension (p11_parser *parser,
- CK_ATTRIBUTE *cert,
- const unsigned char *oid_der,
- CK_BBOOL vcritical,
- const unsigned char *ext_der,
- size_t ext_len)
+build_der_extension (p11_parser *parser,
+ CK_ATTRIBUTE *cert,
+ const unsigned char *oid_der,
+ CK_BBOOL vcritical,
+ const unsigned char *ext_der,
+ int ext_len)
{
CK_ATTRIBUTE critical = { CKA_X_CRITICAL, &vcritical, sizeof (vcritical) };
CK_ATTRIBUTE oid = { CKA_OBJECT_ID, (void *)oid_der, p11_oid_length (oid_der) };
@@ -985,6 +987,34 @@ build_stapled_extension (p11_parser *parser,
return P11_PARSE_SUCCESS;
}
+static int
+build_stapled_extension (p11_parser *parser,
+ CK_ATTRIBUTE *cert,
+ const unsigned char *oid,
+ CK_BBOOL critical,
+ node_asn *ext)
+{
+ char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
+ char *der;
+ int len;
+ int ret;
+
+ len = 0;
+ ret = asn1_der_coding (ext, "", NULL, &len, message);
+ return_val_if_fail (ret == ASN1_MEM_ERROR, P11_PARSE_FAILURE);
+
+ der = malloc (len);
+ return_val_if_fail (der != NULL, P11_PARSE_FAILURE);
+
+ ret = asn1_der_coding (ext, "", der, &len, message);
+ return_val_if_fail (ret == ASN1_SUCCESS, P11_PARSE_FAILURE);
+
+ ret = build_der_extension (parser, cert, oid, critical, (unsigned char *)der, len);
+ free (der);
+
+ return ret;
+}
+
static p11_dict *
load_seq_of_oid_str (node_asn *node,
const char *seqof)
@@ -1033,8 +1063,6 @@ build_eku_extension (p11_parser *parser,
node_asn *dest;
int count = 0;
void *value;
- char *der;
- int len;
int ret;
ret = asn1_create_element (parser->pkix_definitions, "PKIX1.ExtKeyUsageSyntax", &dest);
@@ -1052,11 +1080,16 @@ build_eku_extension (p11_parser *parser,
}
/*
- * If no oids have been written, then we have to put some sort of
+ * If no oids have been written, then we have to put in a reserved
* value, due to the way that ExtendedKeyUsage is defined in RFC 5280.
* There must be at least one purpose. This is important since *not*
* having an ExtendedKeyUsage is very different than having one without
* certain usages.
+ *
+ * We account for this in p11_parse_extended_key_usage(). However for
+ * most callers this should not matter, as they only check whether a
+ * given purpose is present, and don't make assumptions about ones
+ * that they don't know about.
*/
if (count == 0) {
@@ -1067,31 +1100,198 @@ build_eku_extension (p11_parser *parser,
return_val_if_fail (ret == ASN1_SUCCESS, P11_PARSE_FAILURE);
}
- len = 0;
- ret = asn1_der_coding (dest, "", NULL, &len, NULL);
- return_val_if_fail (ret == ASN1_MEM_ERROR, P11_PARSE_FAILURE);
- der = malloc (len);
- return_val_if_fail (der != NULL, P11_PARSE_FAILURE);
+ ret = build_stapled_extension (parser, cert, oid, critical, dest);
+ asn1_delete_structure (&dest);
- ret = asn1_der_coding (dest, "", der, &len, NULL);
+ return ret;
+}
+
+static int
+build_bc_extension (p11_parser *parser,
+ CK_ATTRIBUTE *cert,
+ CK_BBOOL critical,
+ int is_ca)
+{
+ node_asn *ext;
+ int ret;
+
+ ret = asn1_create_element (parser->pkix_definitions, "PKIX1.BasicConstraints", &ext);
return_val_if_fail (ret == ASN1_SUCCESS, P11_PARSE_FAILURE);
- ret = build_stapled_extension (parser, cert, oid, critical,
- (unsigned char *)der, len);
+ /* FALSE is the default, so clear if not CA */
+ ret = asn1_write_value (ext, "cA", is_ca ? "TRUE" : NULL, is_ca ? -1 : 0);
+ return_val_if_fail (ret == ASN1_SUCCESS, P11_PARSE_FAILURE);
- free (der);
- asn1_delete_structure (&dest);
+ /* Clear this optional value */
+ ret = asn1_write_value (ext, "pathLenConstraint", NULL, 0);
+ return_val_if_fail (ret == ASN1_SUCCESS, P11_PARSE_FAILURE);
+
+ ret = build_stapled_extension (parser, cert, P11_OID_BASIC_CONSTRAINTS, critical, ext);
+ asn1_delete_structure (&ext);
return ret;
}
static int
-build_cert_aux_extensions (p11_parser *parser,
- CK_ATTRIBUTE *cert,
- node_asn *aux,
- const unsigned char *aux_der,
- size_t aux_len)
+is_v1_x509_authority (CK_ATTRIBUTE *cert,
+ node_asn *node)
+{
+ CK_ATTRIBUTE *subject;
+ CK_ATTRIBUTE *issuer;
+ char buffer[16];
+ int len;
+ int ret;
+
+ len = sizeof (buffer);
+ ret = asn1_read_value (node, "tbsCertificate.version", buffer, &len);
+
+ /* The default value */
+ if (ret == ASN1_ELEMENT_NOT_FOUND) {
+ ret = ASN1_SUCCESS;
+ buffer[0] = 0;
+ len = 1;
+ }
+
+ return_val_if_fail (ret == ASN1_SUCCESS, 0);
+
+ /*
+ * In X.509 version v1 is the integer zero. Two's complement
+ * integer, but zero is easy to read.
+ */
+ if (len != 1 || buffer[0] != 0)
+ return 0;
+
+ /* Must be self-signed, ie: same subject and issuer */
+ subject = p11_attrs_find (cert, CKA_SUBJECT);
+ issuer = p11_attrs_find (cert, CKA_ISSUER);
+ return (subject != NULL && issuer != NULL &&
+ p11_attr_match_value (subject, issuer->pValue, issuer->ulValueLen));
+}
+
+static void
+update_category (p11_parser *parser,
+ CK_ATTRIBUTE *cert)
+{
+ CK_ATTRIBUTE *category;
+ int is_ca = 0;
+ unsigned char *data;
+ size_t length;
+ int ret;
+
+ /* See if we have a basic constraints extension */
+ data = p11_parsing_get_extension (parser, parser->parsing, P11_OID_BASIC_CONSTRAINTS, &length);
+ if (data) {
+ if (!p11_parse_basic_constraints (parser, data, length, &is_ca))
+ p11_message ("invalid basic constraints certificate extension");
+ free (data);
+
+ } else if (is_v1_x509_authority (cert, parser->cert_asn)) {
+ /*
+ * If there is no basic constraints extension, and the CA version is
+ * v1, and is self-signed, then we assume this is a certificate authority.
+ * So we add a BasicConstraints stapled certificate extension
+ */
+ is_ca = 1;
+ ret = build_bc_extension (parser, cert, CK_FALSE, is_ca);
+ return_if_fail (ret == P11_PARSE_SUCCESS);
+ }
+
+ category = p11_attrs_find (cert, CKA_CERTIFICATE_CATEGORY);
+ assert (category != NULL);
+ assert (category->pValue != NULL);
+ assert (category->ulValueLen == sizeof (CK_ULONG));
+
+ /*
+ * In the PKCS#11 spec:
+ * 0 = unspecified (default value)
+ * 1 = token user
+ * 2 = authority
+ * 3 = other entity
+ */
+ *((CK_ULONG *)category->pValue) = is_ca ? 2 : 3;
+}
+
+static void
+update_trust_and_distrust (p11_parser *parser,
+ CK_ATTRIBUTE *cert)
+{
+ CK_ATTRIBUTE *attr;
+ CK_BBOOL trusted;
+ CK_BBOOL distrusted;
+ unsigned char *data;
+ size_t length;
+ p11_dict *ekus;
+
+ /*
+ * This function is called to update the CKA_TRUSTED and CKA_X_DISTRUSTED
+ * fields (anchor and blacklist). Some other code may have updated the
+ * related extensions, so this may be called more than once.
+ *
+ * Since some input like OpenSSL model blacklists as anchors with all
+ * purposes being removed/rejected, we account for that here. If there
+ * is an ExtendedKeyUsage without any useful purposes, then treat
+ * like a blacklist.
+ *
+ * The certificate is an anchor if the parser is in anchor mode.
+ */
+
+ 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_parse_extended_key_usage (parser, data, length);
+ if (ekus == NULL)
+ p11_message ("invalid extendend key usage certificate extension");
+ else if (p11_dict_size (ekus) == 0) {
+ distrusted = CK_TRUE;
+ trusted = CK_FALSE;
+ }
+
+ p11_dict_free (ekus);
+ free (data);
+ }
+
+ attr = p11_attrs_find (cert, CKA_TRUSTED);
+ assert (attr != NULL);
+ assert (attr->pValue != NULL);
+ assert (attr->ulValueLen == sizeof (CK_BBOOL));
+ *((CK_BBOOL *)attr->pValue) = trusted;
+
+ attr = p11_attrs_find (cert, CKA_X_DISTRUSTED);
+ assert (attr != NULL);
+ assert (attr->pValue != NULL);
+ assert (attr->ulValueLen == sizeof (CK_BBOOL));
+ *((CK_BBOOL *)attr->pValue) = distrusted;
+}
+
+void
+p11_parsing_update_certificate (p11_parser *parser,
+ p11_array *parsing)
+{
+ CK_ATTRIBUTE *cert;
+
+ /* Find the certificate to update */
+ cert = p11_parsing_get_certificate (parser, parsing);
+ if (cert == NULL)
+ return;
+
+ /* This should match the above cert */
+ assert (parser->cert_asn != NULL);
+
+ update_category (parser, cert);
+ update_trust_and_distrust (parser, cert);
+}
+
+
+static int
+build_openssl_extensions (p11_parser *parser,
+ CK_ATTRIBUTE *cert,
+ node_asn *aux,
+ const unsigned char *aux_der,
+ size_t aux_len)
{
p11_dict *trust = NULL;
p11_dict *reject = NULL;
@@ -1102,10 +1302,15 @@ build_cert_aux_extensions (p11_parser *parser,
int ret;
int num;
- ret = asn1_number_of_elements (aux, "trust", &num);
- return_val_if_fail (ret == ASN1_SUCCESS || ret == ASN1_ELEMENT_NOT_FOUND, P11_PARSE_FAILURE);
- if (ret == ASN1_SUCCESS)
- trust = load_seq_of_oid_str (aux, "trust");
+ /*
+ * This will load an empty list if there is no OPTIONAL trust field.
+ * OpenSSL assumes that for a TRUSTED CERTIFICATE a missing trust field
+ * is identical to untrusted for all purposes.
+ *
+ * This is different from ExtendedKeyUsage, where a missing certificate
+ * extension means that it is trusted for all purposes.
+ */
+ trust = load_seq_of_oid_str (aux, "trust");
ret = asn1_number_of_elements (aux, "reject", &num);
return_val_if_fail (ret == ASN1_SUCCESS || ret == ASN1_ELEMENT_NOT_FOUND, P11_PARSE_FAILURE);
@@ -1120,7 +1325,7 @@ build_cert_aux_extensions (p11_parser *parser,
}
/*
- * The trust field becomes a standard ExtKeyUsageSyntax.
+ * The trust field (or lack of it) becomes a standard ExtKeyUsageSyntax.
*
* critical: require that this is enforced
*/
@@ -1131,8 +1336,9 @@ build_cert_aux_extensions (p11_parser *parser,
}
/*
- * For the reject field we use a custom defined extension. See oid.h for
- * more details. It uses ExtKeyUsageSyntax structure.
+ * For the reject field we use a custom defined extension. We track this
+ * for completeness, although the above ExtendedKeyUsage extension handles
+ * this data fine. See oid.h for more details. It uses ExtKeyUsageSyntax structure.
*
* non-critical: non-standard, and also covered by trusts
*/
@@ -1156,11 +1362,12 @@ build_cert_aux_extensions (p11_parser *parser,
return_val_if_fail (ret == ASN1_SUCCESS || ret == ASN1_ELEMENT_NOT_FOUND, P11_PARSE_FAILURE);
if (ret == ASN1_SUCCESS) {
- ret = build_stapled_extension (parser, cert, P11_OID_SUBJECT_KEY_IDENTIFIER, CK_FALSE,
- aux_der + start, (end - start) + 1);
+ ret = build_der_extension (parser, cert, P11_OID_SUBJECT_KEY_IDENTIFIER, CK_FALSE,
+ aux_der + start, (end - start) + 1);
return_val_if_fail (ret == P11_PARSE_SUCCESS, ret);
}
+
return P11_PARSE_SUCCESS;
}
@@ -1222,7 +1429,7 @@ parse_openssl_trusted_certificate (p11_parser *parser,
attrs = build_x509_certificate (parser, vid, cert, data, cert_len);
return_val_if_fail (attrs != NULL, P11_PARSE_FAILURE);
- ret = build_cert_aux_extensions (parser, attrs, aux, data + cert_len, length - cert_len);
+ ret = build_openssl_extensions (parser, attrs, aux, data + cert_len, length - cert_len);
return_val_if_fail (ret == P11_PARSE_SUCCESS, ret);
finish_parsing (parser, cert);
diff --git a/trust/parser.h b/trust/parser.h
index 31f307c..da19bce 100644
--- a/trust/parser.h
+++ b/trust/parser.h
@@ -48,6 +48,7 @@ enum {
enum {
P11_PARSE_FLAG_NONE = 0,
P11_PARSE_FLAG_ANCHOR = 1 << 0,
+ P11_PARSE_FLAG_BLACKLIST = 1 << 1
};
#define P11_PARSER_FIRST_HANDLE 0xA0000000UL
@@ -75,6 +76,11 @@ int p11_parse_file (p11_parser *parser,
p11_parser_sink sink,
void *sink_data);
+int p11_parse_basic_constraints (p11_parser *parser,
+ const unsigned char *data,
+ size_t length,
+ int *is_ca);
+
int p11_parse_key_usage (p11_parser *parser,
const unsigned char *data,
size_t length,
@@ -86,8 +92,6 @@ p11_dict * p11_parse_extended_key_usage (p11_parser *parser,
/* Functions used for retrieving parsing information */
-int p11_parsing_get_flags (p11_parser *parser);
-
CK_ATTRIBUTE * p11_parsing_get_certificate (p11_parser *parser,
p11_array *parsing);
@@ -96,4 +100,7 @@ unsigned char * p11_parsing_get_extension (p11_parser *parser,
const unsigned char *oid,
size_t *length);
+void p11_parsing_update_certificate (p11_parser *parser,
+ p11_array *parsing);
+
#endif
diff --git a/trust/tests/test-data.c b/trust/tests/test-data.c
index a3d5373..f159926 100644
--- a/trust/tests/test-data.c
+++ b/trust/tests/test-data.c
@@ -74,7 +74,7 @@ test_check_cacert3_ca_msg (CuTest *cu,
const char *label)
{
CK_CERTIFICATE_TYPE x509 = CKC_X_509;
- CK_ULONG category = 0; /* TODO: Implement */
+ CK_ULONG category = 2; /* authority */
CK_ATTRIBUTE expected[] = {
{ CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) },
@@ -94,6 +94,22 @@ test_check_cacert3_ca_msg (CuTest *cu,
}
void
+test_check_id_msg (CuTest *cu,
+ const char *file,
+ int line,
+ CK_ATTRIBUTE *expected,
+ CK_ATTRIBUTE *attr)
+{
+ CK_ATTRIBUTE *one;
+ CK_ATTRIBUTE *two;
+
+ one = p11_attrs_find (expected, CKA_ID);
+ two = p11_attrs_find (attr, CKA_ID);
+
+ test_check_attr_msg (cu, file, line, one, two);
+}
+
+void
test_check_attrs_msg (CuTest *cu,
const char *file,
int line,
diff --git a/trust/tests/test-data.h b/trust/tests/test-data.h
index e4ff938..300e342 100644
--- a/trust/tests/test-data.h
+++ b/trust/tests/test-data.h
@@ -74,6 +74,15 @@ void test_check_attr_msg (CuTest *cu,
CK_ATTRIBUTE *expected,
CK_ATTRIBUTE *attr);
+#define test_check_id(cu, expected, attrs) \
+ test_check_id_msg (cu, __FILE__, __LINE__, expected, attrs)
+
+void test_check_id_msg (CuTest *cu,
+ const char *file,
+ int line,
+ CK_ATTRIBUTE *expected,
+ CK_ATTRIBUTE *attr);
+
static const unsigned char test_cacert3_ca_der[] = {
0x30, 0x82, 0x07, 0x59, 0x30, 0x82, 0x05, 0x41, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x0a,
0x41, 0x8a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
diff --git a/trust/tests/test-parser.c b/trust/tests/test-parser.c
index 493dcb3..5bb690a 100644
--- a/trust/tests/test-parser.c
+++ b/trust/tests/test-parser.c
@@ -86,8 +86,9 @@ on_parse_object (CK_ATTRIBUTE *attrs,
static void
test_parse_der_certificate (CuTest *cu)
{
- CK_ATTRIBUTE *attrs;
- CK_ATTRIBUTE *attr;
+ CK_ATTRIBUTE *cert;
+ CK_ATTRIBUTE *object;
+ CK_BBOOL bval;
int ret;
setup (cu);
@@ -99,11 +100,19 @@ test_parse_der_certificate (CuTest *cu)
/* Should have gotten certificate and a trust object */
CuAssertIntEquals (cu, 2, test.objects->num);
- attrs = test.objects->elem[0];
- test_check_cacert3_ca (cu, attrs, NULL);
+ cert = test.objects->elem[0];
+ test_check_cacert3_ca (cu, cert, NULL);
+
+ if (!p11_attrs_find_bool (cert, CKA_TRUSTED, &bval))
+ CuFail (cu, "missing CKA_TRUSTED");
+ CuAssertIntEquals (cu, CK_FALSE, bval);
+
+ if (!p11_attrs_find_bool (cert, CKA_X_DISTRUSTED, &bval))
+ CuFail (cu, "missing CKA_X_DISTRUSTED");
+ CuAssertIntEquals (cu, CK_FALSE, bval);
- attr = p11_attrs_find (attrs, CKA_TRUSTED);
- CuAssertPtrEquals (cu, NULL, attr);
+ object = test.objects->elem[1];
+ test_check_id (cu, cert, object);
teardown (cu);
}
@@ -111,8 +120,9 @@ test_parse_der_certificate (CuTest *cu)
static void
test_parse_pem_certificate (CuTest *cu)
{
- CK_ATTRIBUTE *attrs;
- CK_ATTRIBUTE *attr;
+ CK_ATTRIBUTE *cert;
+ CK_ATTRIBUTE *object;
+ CK_BBOOL bval;
int ret;
setup (cu);
@@ -124,11 +134,19 @@ test_parse_pem_certificate (CuTest *cu)
/* Should have gotten certificate and a trust object */
CuAssertIntEquals (cu, 2, test.objects->num);
- attrs = test.objects->elem[0];
- test_check_cacert3_ca (cu, attrs, NULL);
+ cert = test.objects->elem[0];
+ test_check_cacert3_ca (cu, cert, NULL);
+
+ if (!p11_attrs_find_bool (cert, CKA_TRUSTED, &bval))
+ CuFail (cu, "missing CKA_TRUSTED");
+ CuAssertIntEquals (cu, CK_FALSE, bval);
+
+ if (!p11_attrs_find_bool (cert, CKA_X_DISTRUSTED, &bval))
+ CuFail (cu, "missing CKA_X_DISTRUSTED");
+ CuAssertIntEquals (cu, CK_FALSE, bval);
- attr = p11_attrs_find (attrs, CKA_TRUSTED);
- CuAssertPtrEquals (cu, NULL, attr);
+ object = test.objects->elem[1];
+ test_check_id (cu, cert, object);
teardown (cu);
}
@@ -136,7 +154,7 @@ test_parse_pem_certificate (CuTest *cu)
static void
test_parse_openssl_trusted (CuTest *cu)
{
- CK_TRUST trusted = CKT_NETSCAPE_TRUSTED;
+ CK_TRUST trusted = CKT_NETSCAPE_TRUSTED_DELEGATOR;
CK_TRUST distrusted = CKT_NETSCAPE_UNTRUSTED;
CK_TRUST unknown = CKT_NETSCAPE_TRUST_UNKNOWN;
CK_OBJECT_CLASS certificate_extension = CKO_X_CERTIFICATE_EXTENSION;
@@ -149,6 +167,8 @@ test_parse_openssl_trusted (CuTest *cu)
{ CKA_CLASS, &certificate_extension, sizeof (certificate_extension), },
{ CKA_OBJECT_ID, (void *)P11_OID_EXTENDED_KEY_USAGE, sizeof (P11_OID_EXTENDED_KEY_USAGE) },
{ CKA_X_CRITICAL, &vtrue, sizeof (vtrue) },
+ { CKA_VALUE, "\x30\x14\x06\x08\x2b\x06\x01\x05\x05\x07\x03\x01\x06\x08\x2b\x06"
+ "\x01\x05\x05\x07\x03\x02", 22 },
{ CKA_INVALID },
};
@@ -157,6 +177,7 @@ test_parse_openssl_trusted (CuTest *cu)
{ CKA_CLASS, &certificate_extension, sizeof (certificate_extension), },
{ CKA_OBJECT_ID, (void *)P11_OID_OPENSSL_REJECT, sizeof (P11_OID_OPENSSL_REJECT) },
{ CKA_X_CRITICAL, &vfalse, sizeof (vfalse) },
+ { CKA_VALUE, "\x30\x0a\x06\x08\x2b\x06\x01\x05\x05\x07\x03\x04", 12 },
{ CKA_INVALID },
};
@@ -186,33 +207,149 @@ test_parse_openssl_trusted (CuTest *cu)
{ CKA_INVALID, }
};
- CK_ATTRIBUTE *attrs;
- CK_ATTRIBUTE *attr;
+ CK_ATTRIBUTE *cert;
+ CK_ATTRIBUTE *object;
+ CK_BBOOL bval;
int ret;
setup (cu);
ret = p11_parse_file (test.parser, SRCDIR "/files/cacert3-trusted.pem",
- 0, on_parse_object, 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);
- attrs = test.objects->elem[0];
- test_check_cacert3_ca (cu, attrs, NULL);
+ cert = test.objects->elem[0];
+ test_check_cacert3_ca (cu, cert, NULL);
+
+ if (!p11_attrs_find_bool (cert, CKA_TRUSTED, &bval))
+ CuFail (cu, "missing CKA_TRUSTED");
+ CuAssertIntEquals (cu, CK_TRUE, bval);
+
+ if (!p11_attrs_find_bool (cert, CKA_X_DISTRUSTED, &bval))
+ 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);
+
+ teardown (cu);
+}
+
+static void
+test_parse_openssl_distrusted (CuTest *cu)
+{
+ CK_TRUST distrusted = CKT_NETSCAPE_UNTRUSTED;
+ CK_OBJECT_CLASS certificate_extension = CKO_X_CERTIFICATE_EXTENSION;
+ CK_OBJECT_CLASS trust_object = CKO_NETSCAPE_TRUST;
+ CK_OBJECT_CLASS klass = CKO_CERTIFICATE;
+ CK_CERTIFICATE_TYPE x509 = CKC_X_509;
+ CK_ULONG category = 2; /* authority */
+ CK_BBOOL vtrue = CK_TRUE;
+ CK_BBOOL vfalse = CK_FALSE;
+
+ CK_ATTRIBUTE certificate[] = {
+ { CKA_CLASS, &klass, sizeof (klass), },
+ { CKA_TOKEN, &vtrue, sizeof (vtrue) },
+ { CKA_PRIVATE, &vfalse, sizeof (vfalse) },
+ { CKA_MODIFIABLE, &vfalse, sizeof (vfalse) },
+ { CKA_CLASS, &klass, sizeof (klass) },
+ { CKA_LABEL, "Red Hat Is the CA", 17 },
+ { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) },
+ { CKA_CERTIFICATE_CATEGORY, &category, sizeof (category) },
+ { CKA_CHECK_VALUE, "\xe9z}", 3 },
+ { CKA_START_DATE, "20090916", 8 },
+ { CKA_END_DATE, "20190914", 8, },
+ { CKA_SERIAL_NUMBER, "\x02\x01\x01", 3 },
+ { CKA_TRUSTED, &vfalse, sizeof (vfalse) },
+ { CKA_X_DISTRUSTED, &vtrue, sizeof (vtrue) },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE eku_extension[] = {
+ { CKA_LABEL, "Red Hat Is the CA", 17 },
+ { CKA_CLASS, &certificate_extension, sizeof (certificate_extension), },
+ { CKA_OBJECT_ID, (void *)P11_OID_EXTENDED_KEY_USAGE, sizeof (P11_OID_EXTENDED_KEY_USAGE) },
+ { CKA_X_CRITICAL, &vtrue, sizeof (vtrue) },
+ { CKA_VALUE, "\x30\x0c\x06\x0a\x2b\x06\x01\x04\x01\x99\x77\x06\x0a\x10", 14 },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE reject_extension[] = {
+ { CKA_LABEL, "Red Hat Is the CA", 17 },
+ { CKA_CLASS, &certificate_extension, sizeof (certificate_extension), },
+ { CKA_OBJECT_ID, (void *)P11_OID_OPENSSL_REJECT, sizeof (P11_OID_OPENSSL_REJECT) },
+ { CKA_X_CRITICAL, &vfalse, sizeof (vfalse) },
+ { CKA_VALUE, "\x30\x0a\x06\x08\x2b\x06\x01\x05\x05\x07\x03\x02", 12 },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE nss_trust[] = {
+ { CKA_LABEL, "Red Hat Is the CA", 17 },
+ { CKA_CLASS, &trust_object, sizeof (trust_object), },
+ { CKA_CERT_SHA1_HASH, "\xe9z}\xe3\x82""7\xa0U\xb1k\xfe\xffo.\x03\x15*\xba\xb9\x90", 20 },
+ { CKA_CERT_MD5_HASH, "\xda\xb4<\xe7;QK\x1a\xe5\xeau\xa1\xc9 \xdf""B", 16 },
+ { CKA_SERIAL_NUMBER, "\x02\x01\x01", 3 },
+ { CKA_TRUST_SERVER_AUTH, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_CLIENT_AUTH, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_EMAIL_PROTECTION, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_CODE_SIGNING, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_IPSEC_END_SYSTEM, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_IPSEC_TUNNEL, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_IPSEC_USER, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_TIME_STAMPING, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_DIGITAL_SIGNATURE, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_NON_REPUDIATION, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_KEY_ENCIPHERMENT, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_DATA_ENCIPHERMENT, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_KEY_AGREEMENT, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_KEY_CERT_SIGN, &distrusted, sizeof (distrusted) },
+ { CKA_TRUST_CRL_SIGN, &distrusted, sizeof (distrusted) },
+ { CKA_INVALID, }
+ };
- attr = p11_attrs_find (attrs, CKA_TRUSTED);
- CuAssertPtrEquals (cu, NULL, attr);
+ CK_ATTRIBUTE *cert;
+ CK_ATTRIBUTE *object;
+ int ret;
- attrs = test.objects->elem[1];
- test_check_attrs (cu, eku_extension, attrs);
+ setup (cu);
- attrs = test.objects->elem[2];
- test_check_attrs (cu, reject_extension, attrs);
+ /*
+ * OpenSSL style is to litter the blacklist in with the anchors,
+ * so we parse this as an anchor, but expect it to be blacklisted
+ */
+ ret = p11_parse_file (test.parser, SRCDIR "/files/distrusted.pem",
+ P11_PARSE_FLAG_ANCHOR, on_parse_object, cu);
+ CuAssertIntEquals (cu, P11_PARSE_SUCCESS, ret);
- attrs = test.objects->elem[3];
- test_check_attrs (cu, nss_trust, attrs);
+ /* Should have gotten certificate, one stapled extensions, and a trust object */
+ CuAssertIntEquals (cu, 4, 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);
teardown (cu);
}
@@ -227,7 +364,7 @@ test_parse_with_key_usage (CuTest *cu)
CK_BBOOL vtrue = CK_TRUE;
CK_BBOOL vfalse = CK_FALSE;
CK_CERTIFICATE_TYPE x509 = CKC_X_509;
- CK_ULONG category = 0; /* TODO: Implement */
+ CK_ULONG category = 3; /* other entity */
CK_ATTRIBUTE certificate[] = {
{ CKA_CLASS, &klass, sizeof (klass), },
@@ -244,6 +381,8 @@ test_parse_with_key_usage (CuTest *cu)
{ CKA_ISSUER, "0*1(0&\x06\x03U\x04\x03\x13\x1f""self-signed-with-ku.example.com", 44 },
{ CKA_SUBJECT, "0*1(0&\x06\x03U\x04\x03\x13\x1f""self-signed-with-ku.example.com", 44 },
{ CKA_SERIAL_NUMBER, "\x02\x02\x03x", 4 },
+ { CKA_TRUSTED, &vtrue, sizeof (vtrue) },
+ { CKA_X_DISTRUSTED, &vfalse, sizeof (vfalse) },
{ CKA_INVALID },
};
@@ -273,41 +412,34 @@ test_parse_with_key_usage (CuTest *cu)
{ CKA_INVALID, }
};
- CK_ATTRIBUTE *attrs;
- CK_ATTRIBUTE *attr;
+ CK_ATTRIBUTE *cert;
+ CK_ATTRIBUTE *object;
+ CK_BBOOL bval;
int ret;
setup (cu);
ret = p11_parse_file (test.parser, SRCDIR "/files/self-signed-with-ku.der",
- 0, on_parse_object, 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 */
+ /* Should have gotten certificate, and a trust object */
CuAssertIntEquals (cu, 2, test.objects->num);
- attrs = test.objects->elem[0];
- test_check_attrs (cu, certificate, attrs);
+ cert = test.objects->elem[0];
+ test_check_attrs (cu, certificate, cert);
- attr = p11_attrs_find (attrs, CKA_TRUSTED);
- CuAssertPtrEquals (cu, NULL, attr);
+ if (!p11_attrs_find_bool (cert, CKA_TRUSTED, &bval))
+ CuFail (cu, "missing CKA_TRUSTED");
+ CuAssertIntEquals (cu, CK_TRUE, bval);
- attrs = test.objects->elem[1];
- test_check_attrs (cu, nss_trust, attrs);
+ if (!p11_attrs_find_bool (cert, CKA_X_DISTRUSTED, &bval))
+ CuFail (cu, "missing CKA_X_DISTRUSTED");
+ CuAssertIntEquals (cu, CK_FALSE, bval);
- teardown (cu);
-}
-
-static void
-test_parse_distrusted (CuTest *cu)
-{
- int ret;
-
- setup (cu);
-
- ret = p11_parse_file (test.parser, SRCDIR "/files/distrusted.pem",
- 0, on_parse_object, cu);
- CuAssertIntEquals (cu, P11_PARSE_SUCCESS, ret);
+ object = test.objects->elem[1];
+ test_check_attrs (cu, nss_trust, object);
+ test_check_id (cu, cert, object);
teardown (cu);
}
@@ -315,7 +447,8 @@ test_parse_distrusted (CuTest *cu)
static void
test_parse_anchor (CuTest *cu)
{
- CK_ATTRIBUTE *attrs;
+ CK_ATTRIBUTE *cert;
+ CK_ATTRIBUTE *object;
CK_ATTRIBUTE *attr;
CK_BBOOL vtrue = CK_TRUE;
CK_ATTRIBUTE trusted = { CKA_TRUSTED, &vtrue, sizeof (vtrue) };
@@ -330,12 +463,15 @@ test_parse_anchor (CuTest *cu)
/* Should have gotten a certificate and a trust object */
CuAssertIntEquals (cu, 2, test.objects->num);
- attrs = test.objects->elem[0];
- test_check_cacert3_ca (cu, attrs, NULL);
+ cert = test.objects->elem[0];
+ test_check_cacert3_ca (cu, cert, NULL);
- attr = p11_attrs_find (attrs, CKA_TRUSTED);
+ attr = p11_attrs_find (cert, CKA_TRUSTED);
test_check_attr (cu, &trusted, attr);
+ object = test.objects->elem[1];
+ test_check_id (cu, cert, object);
+
teardown (cu);
}
@@ -499,8 +635,8 @@ main (void)
SUITE_ADD_TEST (suite, test_parse_der_certificate);
SUITE_ADD_TEST (suite, test_parse_pem_certificate);
SUITE_ADD_TEST (suite, test_parse_openssl_trusted);
+ SUITE_ADD_TEST (suite, test_parse_openssl_distrusted);
SUITE_ADD_TEST (suite, test_parse_with_key_usage);
- SUITE_ADD_TEST (suite, test_parse_distrusted);
SUITE_ADD_TEST (suite, test_parse_anchor);
SUITE_ADD_TEST (suite, test_parse_no_sink);
SUITE_ADD_TEST (suite, test_parse_invalid_file);
diff --git a/trust/tests/test-token.c b/trust/tests/test-token.c
index 8a5b34d..2ed1134 100644
--- a/trust/tests/test-token.c
+++ b/trust/tests/test-token.c
@@ -76,7 +76,7 @@ test_token_load (CuTest *cu)
/* A certificate and trust object for each parsed object + builtin */
objects = p11_token_objects (test.token);
- CuAssertIntEquals (cu, ((count - 1) * 2) + 1, p11_dict_size (objects));
+ CuAssertTrue (cu, ((count - 1) * 2) + 1 <= p11_dict_size (objects));
teardown (cu);
}