summaryrefslogtreecommitdiff
path: root/trust/parser.c
diff options
context:
space:
mode:
authorStef Walter <stef@thewalter.net>2013-07-04 15:48:38 +0200
committerStef Walter <stef@thewalter.net>2013-07-04 15:48:38 +0200
commit7d4941715b5afc2ef8ea18716990d28965737c70 (patch)
tree65b860118fbcf084b855e3e8d78c818b6b8fe765 /trust/parser.c
parent2be55821c1ffab99b91c76c43c91dd95db1c21c7 (diff)
downloadp11-kit-7d4941715b5afc2ef8ea18716990d28965737c70.tar.gz
trust: Port to use CKA_PUBLIC_KEY_INFO and updated trust store spec
* Use the concepts and PKCS#11 objects described in the recently updated (still work in progress) storing trust spec. * Define our own CKA_X_PUBLIC_KEY_INFO define for now, since the the CKA_PUBLIC_KEY_INFO isn't defined yet. * Most notably, the association between certificates and stapled extensions is by public key. * Rework some of the tests to take into account the above.
Diffstat (limited to 'trust/parser.c')
-rw-r--r--trust/parser.c109
1 files changed, 79 insertions, 30 deletions
diff --git a/trust/parser.c b/trust/parser.c
index 77e41bc..26d911b 100644
--- a/trust/parser.c
+++ b/trust/parser.c
@@ -200,44 +200,75 @@ parse_der_x509_certificate (p11_parser *parser,
static CK_ATTRIBUTE *
extension_attrs (p11_parser *parser,
CK_ATTRIBUTE *id,
+ CK_ATTRIBUTE *public_key_info,
+ const char *oid_str,
const unsigned char *oid_der,
- CK_BBOOL vcritical,
- const unsigned char *ext_der,
- int ext_len)
+ bool critical,
+ const unsigned char *value,
+ int length)
{
CK_OBJECT_CLASS klassv = CKO_X_CERTIFICATE_EXTENSION;
CK_BBOOL modifiablev = CK_FALSE;
CK_ATTRIBUTE klass = { CKA_CLASS, &klassv, sizeof (klassv) };
CK_ATTRIBUTE modifiable = { CKA_MODIFIABLE, &modifiablev, sizeof (modifiablev) };
- CK_ATTRIBUTE critical = { CKA_X_CRITICAL, &vcritical, sizeof (vcritical) };
CK_ATTRIBUTE oid = { CKA_OBJECT_ID, (void *)oid_der, p11_oid_length (oid_der) };
- CK_ATTRIBUTE value = { CKA_VALUE, (void *)ext_der, ext_len };
- if (ext_der == NULL)
- value.type = CKA_INVALID;
+ CK_ATTRIBUTE *attrs;
+ node_asn *dest;
+ unsigned char *der;
+ size_t len;
+ int ret;
+
+ attrs = p11_attrs_build (NULL, id, public_key_info, &klass, &modifiable, &oid, NULL);
+ return_val_if_fail (attrs != NULL, NULL);
+
+ dest = p11_asn1_create (parser->asn1_defs, "PKIX1.Extension");
+ return_val_if_fail (dest != NULL, NULL);
+
+ ret = asn1_write_value (dest, "extnID", oid_str, 1);
+ return_val_if_fail (ret == ASN1_SUCCESS, NULL);
+
+ if (critical)
+ ret = asn1_write_value (dest, "critical", "TRUE", 1);
+ return_val_if_fail (ret == ASN1_SUCCESS, NULL);
+
+ ret = asn1_write_value (dest, "extnValue", value, length);
+ return_val_if_fail (ret == ASN1_SUCCESS, NULL);
+
+ der = p11_asn1_encode (dest, &len);
+ return_val_if_fail (der != NULL, NULL);
- return p11_attrs_build (NULL, id, &klass, &modifiable, &oid, &critical, &value, NULL);
+ attrs = p11_attrs_take (attrs, CKA_VALUE, der, len);
+ return_val_if_fail (attrs != NULL, NULL);
+
+ /* An opmitization so that the builder can get at this without parsing */
+ p11_asn1_cache_take (parser->asn1_cache, dest, "PKIX1.Extension", der, len);
+ return attrs;
}
static CK_ATTRIBUTE *
stapled_attrs (p11_parser *parser,
CK_ATTRIBUTE *id,
- const unsigned char *oid,
- CK_BBOOL critical,
+ CK_ATTRIBUTE *public_key_info,
+ const char *oid_str,
+ const unsigned char *oid_der,
+ bool critical,
node_asn *ext)
{
CK_ATTRIBUTE *attrs;
unsigned char *der;
size_t len;
- attrs = extension_attrs (parser, id, oid, critical, NULL, 0);
- return_val_if_fail (attrs != NULL, NULL);
-
der = p11_asn1_encode (ext, &len);
return_val_if_fail (der != NULL, NULL);
- return p11_attrs_take (attrs, CKA_VALUE, der, len);
+ attrs = extension_attrs (parser, id, public_key_info, oid_str, oid_der,
+ critical, der, len);
+ return_val_if_fail (attrs != NULL, NULL);
+
+ free (der);
+ return attrs;
}
static p11_dict *
@@ -270,8 +301,10 @@ load_seq_of_oid_str (node_asn *node,
static CK_ATTRIBUTE *
stapled_eku_attrs (p11_parser *parser,
CK_ATTRIBUTE *id,
- const unsigned char *oid,
- CK_BBOOL critical,
+ CK_ATTRIBUTE *public_key_info,
+ const char *oid_str,
+ const unsigned char *oid_der,
+ bool critical,
p11_dict *oid_strs)
{
CK_ATTRIBUTE *attrs;
@@ -317,7 +350,7 @@ stapled_eku_attrs (p11_parser *parser,
}
- attrs = stapled_attrs (parser, id, oid, critical, dest);
+ attrs = stapled_attrs (parser, id, public_key_info, oid_str, oid_der, critical, dest);
asn1_delete_structure (&dest);
return attrs;
@@ -327,6 +360,7 @@ static CK_ATTRIBUTE *
build_openssl_extensions (p11_parser *parser,
CK_ATTRIBUTE *cert,
CK_ATTRIBUTE *id,
+ CK_ATTRIBUTE *public_key_info,
node_asn *aux,
const unsigned char *aux_der,
size_t aux_len)
@@ -379,7 +413,10 @@ build_openssl_extensions (p11_parser *parser,
*/
if (trust) {
- attrs = stapled_eku_attrs (parser, id, P11_OID_EXTENDED_KEY_USAGE, CK_TRUE, trust);
+ attrs = stapled_eku_attrs (parser, id, public_key_info,
+ P11_OID_EXTENDED_KEY_USAGE_STR,
+ P11_OID_EXTENDED_KEY_USAGE,
+ true, trust);
return_val_if_fail (attrs != NULL, NULL);
sink_object (parser, attrs);
}
@@ -393,7 +430,10 @@ build_openssl_extensions (p11_parser *parser,
*/
if (reject && p11_dict_size (reject) > 0) {
- attrs = stapled_eku_attrs (parser, id, P11_OID_OPENSSL_REJECT, CK_FALSE, reject);
+ attrs = stapled_eku_attrs (parser, id, public_key_info,
+ P11_OID_OPENSSL_REJECT_STR,
+ P11_OID_OPENSSL_REJECT,
+ false, reject);
return_val_if_fail (attrs != NULL, NULL);
sink_object (parser, attrs);
}
@@ -439,8 +479,10 @@ build_openssl_extensions (p11_parser *parser,
return_val_if_fail (ret == ASN1_SUCCESS || ret == ASN1_ELEMENT_NOT_FOUND, NULL);
if (ret == ASN1_SUCCESS) {
- attrs = extension_attrs (parser, id, P11_OID_SUBJECT_KEY_IDENTIFIER, CK_FALSE,
- aux_der + start, (end - start) + 1);
+ attrs = extension_attrs (parser, id, public_key_info,
+ P11_OID_SUBJECT_KEY_IDENTIFIER_STR,
+ P11_OID_SUBJECT_KEY_IDENTIFIER,
+ false, aux_der + start, (end - start) + 1);
return_val_if_fail (attrs != NULL, NULL);
sink_object (parser, attrs);
}
@@ -458,12 +500,15 @@ parse_openssl_trusted_certificate (p11_parser *parser,
CK_ATTRIBUTE *attrs;
CK_BYTE idv[ID_LENGTH];
CK_ATTRIBUTE id = { CKA_ID, idv, sizeof (idv) };
+ CK_ATTRIBUTE public_key_info = { CKA_X_PUBLIC_KEY_INFO };
CK_ATTRIBUTE *value;
char *label = NULL;
node_asn *cert;
node_asn *aux;
ssize_t cert_len;
- int len;
+ size_t len;
+ int start;
+ int end;
int ret;
/*
@@ -497,23 +542,27 @@ parse_openssl_trusted_certificate (p11_parser *parser,
/* Cache the parsed certificate ASN.1 for later use by the builder */
value = p11_attrs_find_valid (attrs, CKA_VALUE);
return_val_if_fail (value != NULL, P11_PARSE_FAILURE);
+
+ /* Pull out the subject public key info */
+ ret = asn1_der_decoding_startEnd (cert, data, cert_len,
+ "tbsCertificate.subjectPublicKeyInfo", &start, &end);
+ return_val_if_fail (ret == ASN1_SUCCESS, P11_PARSE_FAILURE);
+
+ public_key_info.pValue = (char *)data + start;
+ public_key_info.ulValueLen = (end - start) + 1;
+
p11_asn1_cache_take (parser->asn1_cache, cert, "PKIX1.Certificate",
value->pValue, value->ulValueLen);
/* Pull the label out of the CertAux */
len = 0;
- ret = asn1_read_value (aux, "alias", NULL, &len);
- if (ret != ASN1_ELEMENT_NOT_FOUND) {
- return_val_if_fail (ret == ASN1_MEM_ERROR, P11_PARSE_FAILURE);
- label = calloc (len + 1, 1);
- return_val_if_fail (label != NULL, P11_PARSE_FAILURE);
- ret = asn1_read_value (aux, "alias", label, &len);
- return_val_if_fail (ret == ASN1_SUCCESS, P11_PARSE_FAILURE);
+ label = p11_asn1_read (aux, "alias", &len);
+ if (label != NULL) {
attrs = p11_attrs_take (attrs, CKA_LABEL, label, strlen (label));
return_val_if_fail (attrs != NULL, P11_PARSE_FAILURE);
}
- attrs = build_openssl_extensions (parser, attrs, &id, aux,
+ attrs = build_openssl_extensions (parser, attrs, &id, &public_key_info, aux,
data + cert_len, length - cert_len);
return_val_if_fail (attrs != NULL, P11_PARSE_FAILURE);