diff options
Diffstat (limited to 'trust')
-rw-r--r-- | trust/builder.c | 152 | ||||
-rw-r--r-- | trust/builder.h | 5 | ||||
-rw-r--r-- | trust/index.c | 129 | ||||
-rw-r--r-- | trust/index.h | 11 | ||||
-rw-r--r-- | trust/session.c | 2 | ||||
-rw-r--r-- | trust/tests/test-builder.c | 238 | ||||
-rw-r--r-- | trust/tests/test-index.c | 32 | ||||
-rw-r--r-- | trust/token.c | 166 |
8 files changed, 483 insertions, 252 deletions
diff --git a/trust/builder.c b/trust/builder.c index 106968c..d39890d 100644 --- a/trust/builder.c +++ b/trust/builder.c @@ -81,7 +81,7 @@ typedef struct { bool (*validate) (p11_builder *, CK_ATTRIBUTE *); } attrs[32]; CK_ATTRIBUTE * (*populate) (p11_builder *, p11_index *, CK_ATTRIBUTE *); - CK_RV (*validate) (p11_builder *, CK_ATTRIBUTE *); + CK_RV (*validate) (p11_builder *, CK_ATTRIBUTE *, CK_ATTRIBUTE *); } builder_schema; static node_asn * @@ -711,12 +711,24 @@ certificate_populate (p11_builder *builder, return p11_attrs_build (attrs, &category, &empty_value, NULL); } -static CK_RV -certificate_validate (p11_builder *builder, - CK_ATTRIBUTE *attrs) +static bool +have_attribute (CK_ATTRIBUTE *attrs1, + CK_ATTRIBUTE *attrs2, + CK_ATTRIBUTE_TYPE type) { CK_ATTRIBUTE *attr; + attr = p11_attrs_find (attrs1, type); + if (attr == NULL) + attr = p11_attrs_find (attrs2, type); + return attr != NULL && attr->ulValueLen > 0; +} + +static CK_RV +certificate_validate (p11_builder *builder, + CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *merge) +{ /* * In theory we should be validating that in the absence of CKA_VALUE * various other fields must be set. However we do not enforce this @@ -724,16 +736,13 @@ certificate_validate (p11_builder *builder, * but issuer and serial number, for blacklisting purposes. */ - attr = p11_attrs_find (attrs, CKA_URL); - if (attr != NULL && attr->ulValueLen > 0) { - attr = p11_attrs_find (attrs, CKA_HASH_OF_SUBJECT_PUBLIC_KEY); - if (attr == NULL || attr->ulValueLen == 0) { + if (have_attribute (attrs, merge, CKA_URL)) { + if (!have_attribute (attrs, merge, CKA_HASH_OF_SUBJECT_PUBLIC_KEY)) { p11_message ("missing the CKA_HASH_OF_SUBJECT_PUBLIC_KEY attribute"); return CKR_TEMPLATE_INCONSISTENT; } - attr = p11_attrs_find (attrs, CKA_HASH_OF_ISSUER_PUBLIC_KEY); - if (attr == NULL || attr->ulValueLen == 0) { + if (!have_attribute (attrs, merge, CKA_HASH_OF_SUBJECT_PUBLIC_KEY)) { p11_message ("missing the CKA_HASH_OF_ISSUER_PUBLIC_KEY attribute"); return CKR_TEMPLATE_INCONSISTENT; } @@ -746,8 +755,8 @@ const static builder_schema certificate_schema = { NORMAL_BUILD, { COMMON_ATTRS, { CKA_CERTIFICATE_TYPE, REQUIRE | CREATE, type_ulong }, - { CKA_TRUSTED, NONE, type_bool }, - { CKA_X_DISTRUSTED, NONE, type_bool }, + { CKA_TRUSTED, CREATE | WANT, type_bool }, + { CKA_X_DISTRUSTED, CREATE | WANT, type_bool }, { CKA_CERTIFICATE_CATEGORY, CREATE | WANT, type_ulong }, { CKA_CHECK_VALUE, CREATE | WANT, }, { CKA_START_DATE, CREATE | MODIFY | WANT, type_date }, @@ -761,7 +770,7 @@ const static builder_schema certificate_schema = { { CKA_HASH_OF_SUBJECT_PUBLIC_KEY, CREATE }, { CKA_HASH_OF_ISSUER_PUBLIC_KEY, CREATE }, { CKA_JAVA_MIDP_SECURITY_DOMAIN, CREATE, type_ulong }, - { CKA_X_PUBLIC_KEY_INFO, CREATE | WANT, type_der_key }, + { CKA_X_PUBLIC_KEY_INFO, WANT, type_der_key }, { CKA_INVALID }, }, certificate_populate, certificate_validate, }; @@ -884,33 +893,6 @@ const static builder_schema builtin_schema = { }, common_populate }; -static void -attrs_filter_if_unchanged (CK_ATTRIBUTE *attrs, - CK_ATTRIBUTE *merge) -{ - CK_ATTRIBUTE *attr; - int in, out; - - assert (attrs != NULL); - assert (merge != NULL); - - for (in = 0, out = 0; !p11_attrs_terminator (merge + in); in++) { - attr = p11_attrs_find (attrs, merge[in].type); - if (attr && p11_attr_equal (attr, merge + in)) { - free (merge[in].pValue); - merge[in].pValue = NULL; - merge[in].ulValueLen = 0; - } else { - if (in != out) - memcpy (merge + out, merge + in, sizeof (CK_ATTRIBUTE)); - out++; - } - } - - merge[out].type = CKA_INVALID; - assert (p11_attrs_terminator (merge + out)); -} - static const char * value_name (const p11_constant *info, CK_ATTRIBUTE_TYPE type) @@ -926,49 +908,15 @@ type_name (CK_ATTRIBUTE_TYPE type) } static CK_RV -validate_for_schema (p11_builder *builder, - const builder_schema *schema, - CK_ATTRIBUTE *attrs, - CK_ATTRIBUTE *merge) -{ - CK_ATTRIBUTE *shallow; - CK_ULONG nattrs; - CK_ULONG nmerge; - CK_RV rv; - - if (!schema->validate) - return CKR_OK; - - nattrs = p11_attrs_count (attrs); - nmerge = p11_attrs_count (merge); - - /* Make a shallow copy of the combined attributes for validation */ - shallow = calloc (nmerge + nattrs + 1, sizeof (CK_ATTRIBUTE)); - return_val_if_fail (shallow != NULL, CKR_GENERAL_ERROR); - - memcpy (shallow, merge, sizeof (CK_ATTRIBUTE) * nmerge); - memcpy (shallow + nmerge, attrs, sizeof (CK_ATTRIBUTE) * nattrs); - - /* The terminator attribute */ - shallow[nmerge + nattrs].type = CKA_INVALID; - assert(p11_attrs_terminator (shallow + nmerge + nattrs)); - - rv = (schema->validate) (builder, shallow); - free (shallow); - - return rv; -} - -static CK_RV build_for_schema (p11_builder *builder, p11_index *index, const builder_schema *schema, - CK_ATTRIBUTE **object, - CK_ATTRIBUTE *merge) + CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *merge, + CK_ATTRIBUTE **extra) { - CK_ATTRIBUTE *extra; - CK_ATTRIBUTE *attrs; CK_BBOOL modifiable; + CK_ATTRIBUTE *attr; bool modifying; bool creating; bool populate; @@ -978,7 +926,6 @@ build_for_schema (p11_builder *builder, int i, j; CK_RV rv; - attrs = *object; populate = false; /* Signifies that data is being loaded */ @@ -998,9 +945,6 @@ build_for_schema (p11_builder *builder, } } - if (attrs != NULL) - attrs_filter_if_unchanged (attrs, merge); - if (creating && (builder->flags & P11_BUILDER_FLAG_TOKEN)) { if (schema->build_flags & GENERATED_CLASS) { p11_message ("objects of this type cannot be created"); @@ -1009,6 +953,12 @@ build_for_schema (p11_builder *builder, } for (i = 0; merge[i].type != CKA_INVALID; i++) { + + /* Don't validate attribute if not changed */ + attr = p11_attrs_find (attrs, merge[i].type); + if (attr && p11_attr_equal (attr, merge + i)) + continue; + found = false; for (j = 0; schema->attrs[j].type != CKA_INVALID; j++) { if (schema->attrs[j].type != merge[i].type) @@ -1068,35 +1018,27 @@ build_for_schema (p11_builder *builder, } } - if (populate && schema->populate) { - extra = schema->populate (builder, index, merge); - if (extra != NULL) - merge = p11_attrs_merge (merge, extra, false); - } + if (populate && schema->populate) + *extra = schema->populate (builder, index, merge); /* Validate the result, before committing to the change. */ - if (!loading) { - rv = validate_for_schema (builder, schema, attrs, merge); - if (rv != CKR_OK) { - p11_attrs_free (merge); + if (!loading && schema->validate) { + rv = (schema->validate) (builder, attrs, merge); + if (rv != CKR_OK) return rv; - } } - *object = p11_attrs_merge (attrs, merge, true); - return_val_if_fail (*object != NULL, CKR_HOST_MEMORY); - return CKR_OK; } CK_RV p11_builder_build (void *bilder, p11_index *index, - CK_ATTRIBUTE **object, - CK_ATTRIBUTE *merge) + CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *merge, + CK_ATTRIBUTE **populate) { p11_builder *builder = bilder; - CK_ATTRIBUTE *attrs; CK_OBJECT_CLASS klass; CK_CERTIFICATE_TYPE type; CK_BBOOL token; @@ -1105,8 +1047,6 @@ p11_builder_build (void *bilder, return_val_if_fail (index != NULL, CKR_GENERAL_ERROR); return_val_if_fail (merge != NULL, CKR_GENERAL_ERROR); - attrs = *object; - if (!p11_attrs_find_ulong (attrs ? attrs : merge, CKA_CLASS, &klass)) { p11_message ("no CKA_CLASS attribute found"); return CKR_TEMPLATE_INCOMPLETE; @@ -1125,7 +1065,7 @@ p11_builder_build (void *bilder, p11_message ("missing %s on object", type_name (CKA_CERTIFICATE_TYPE)); return CKR_TEMPLATE_INCOMPLETE; } else if (type == CKC_X_509) { - return build_for_schema (builder, index, &certificate_schema, object, merge); + return build_for_schema (builder, index, &certificate_schema, attrs, merge, populate); } else { p11_message ("%s unsupported %s", value_name (p11_constant_certs, type), type_name (CKA_CERTIFICATE_TYPE)); @@ -1133,19 +1073,19 @@ p11_builder_build (void *bilder, } case CKO_X_CERTIFICATE_EXTENSION: - return build_for_schema (builder, index, &extension_schema, object, merge); + return build_for_schema (builder, index, &extension_schema, attrs, merge, populate); case CKO_DATA: - return build_for_schema (builder, index, &data_schema, object, merge); + return build_for_schema (builder, index, &data_schema, attrs, merge, populate); case CKO_NSS_TRUST: - return build_for_schema (builder, index, &trust_schema, object, merge); + return build_for_schema (builder, index, &trust_schema, attrs, merge, populate); case CKO_NSS_BUILTIN_ROOT_LIST: - return build_for_schema (builder, index, &builtin_schema, object, merge); + return build_for_schema (builder, index, &builtin_schema, attrs, merge, populate); case CKO_X_TRUST_ASSERTION: - return build_for_schema (builder, index, &assertion_schema, object, merge); + return build_for_schema (builder, index, &assertion_schema, attrs, merge, populate); default: p11_message ("%s unsupported object class", diff --git a/trust/builder.h b/trust/builder.h index c837514..ba130e1 100644 --- a/trust/builder.h +++ b/trust/builder.h @@ -53,8 +53,9 @@ void p11_builder_free (p11_builder *builder); CK_RV p11_builder_build (void *builder, p11_index *index, - CK_ATTRIBUTE **attrs, - CK_ATTRIBUTE *merge); + CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *merge, + CK_ATTRIBUTE **populate); void p11_builder_changed (void *builder, p11_index *index, diff --git a/trust/index.c b/trust/index.c index 4743397..b84142f 100644 --- a/trust/index.c +++ b/trust/index.c @@ -77,6 +77,9 @@ struct _p11_index { /* Called to build an new/modified object */ p11_index_build_cb build; + /* Called after each object ready to be stored */ + p11_index_store_cb store; + /* Called after objects change */ p11_index_notify_cb notify; @@ -98,8 +101,37 @@ free_object (void *data) free (obj); } +static CK_RV +default_build (void *data, + p11_index *index, + CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *merge, + CK_ATTRIBUTE **populate) +{ + return CKR_OK; +} + +static CK_RV +default_store (void *data, + p11_index *index, + CK_OBJECT_HANDLE handle, + CK_ATTRIBUTE **attrs) +{ + return CKR_OK; +} + +static void +default_notify (void *data, + p11_index *index, + CK_OBJECT_HANDLE handle, + CK_ATTRIBUTE *attrs) +{ + +} + p11_index * p11_index_new (p11_index_build_cb build, + p11_index_store_cb store, p11_index_notify_cb notify, void *data) { @@ -108,7 +140,15 @@ p11_index_new (p11_index_build_cb build, index = calloc (1, sizeof (p11_index)); return_val_if_fail (index != NULL, NULL); + if (build == NULL) + build = default_build; + if (store == NULL) + store = default_store; + if (notify == NULL) + notify = default_notify; + index->build = build; + index->store = store; index->notify = notify; index->data = data; @@ -251,17 +291,89 @@ index_hash (p11_index *index, } } +static void +merge_attrs (CK_ATTRIBUTE *output, + CK_ULONG *noutput, + CK_ATTRIBUTE *merge, + CK_ULONG nmerge, + p11_array *to_free) +{ + CK_ULONG i; + + for (i = 0; i < nmerge; i++) { + /* Already have this attribute? */ + if (p11_attrs_findn (output, *noutput, merge[i].type)) { + p11_array_push (to_free, merge[i].pValue); + + } else { + memcpy (output + *noutput, merge + i, sizeof (CK_ATTRIBUTE)); + (*noutput)++; + } + } + + /* Freeing the array itself */ + p11_array_push (to_free, merge); +} + static CK_RV index_build (p11_index *index, + CK_OBJECT_HANDLE handle, CK_ATTRIBUTE **attrs, CK_ATTRIBUTE *merge) { - if (index->build) { - return index->build (index->data, index, attrs, merge); + CK_ATTRIBUTE *extra = NULL; + CK_ATTRIBUTE *built; + p11_array *stack = NULL; + CK_ULONG count; + CK_ULONG nattrs; + CK_ULONG nmerge; + CK_ULONG nextra; + CK_RV rv; + int i; + + rv = index->build (index->data, index, *attrs, merge, &extra); + if (rv != CKR_OK) + return rv; + + /* Short circuit when nothing to merge */ + if (*attrs == NULL && extra == NULL) { + built = merge; + stack = NULL; + } else { - *attrs = p11_attrs_merge (*attrs, merge, true); - return CKR_OK; + stack = p11_array_new (NULL); + nattrs = p11_attrs_count (*attrs); + nmerge = p11_attrs_count (merge); + nextra = p11_attrs_count (extra); + + /* Make a shallow copy of the combined attributes for validation */ + built = calloc (nmerge + nattrs + nextra + 1, sizeof (CK_ATTRIBUTE)); + return_val_if_fail (built != NULL, CKR_GENERAL_ERROR); + + count = nmerge; + memcpy (built, merge, sizeof (CK_ATTRIBUTE) * nmerge); + merge_attrs (built, &count, *attrs, nattrs, stack); + merge_attrs (built, &count, extra, nextra, stack); + + /* The terminator attribute */ + built[count].type = CKA_INVALID; + assert (p11_attrs_terminator (built + count)); } + + rv = index->store (index->data, index, handle, &built); + + if (rv == CKR_OK) { + for (i = 0; stack && i < stack->num; i++) + free (stack->elem[i]); + *attrs = built; + } else { + p11_attrs_free (merge); + p11_attrs_free (extra); + free (built); + } + + p11_array_free (stack); + return rv; } static void @@ -371,7 +483,9 @@ p11_index_take (p11_index *index, obj = calloc (1, sizeof (index_object)); return_val_if_fail (obj != NULL, CKR_HOST_MEMORY); - rv = index_build (index, &obj->attrs, attrs); + obj->handle = p11_module_next_id (); + + rv = index_build (index, obj->handle, &obj->attrs, attrs); if (rv != CKR_OK) { p11_attrs_free (attrs); free (obj); @@ -379,7 +493,6 @@ p11_index_take (p11_index *index, } return_val_if_fail (obj->attrs != NULL, CKR_GENERAL_ERROR); - obj->handle = p11_module_next_id (); if (!p11_dict_set (index->objects, &obj->handle, obj)) return_val_if_reached (CKR_HOST_MEMORY); @@ -427,7 +540,7 @@ p11_index_update (p11_index *index, return CKR_OBJECT_HANDLE_INVALID; } - rv = index_build (index, &obj->attrs, update); + rv = index_build (index, obj->handle, &obj->attrs, update); if (rv != CKR_OK) { p11_attrs_free (update); return rv; @@ -508,7 +621,7 @@ index_replacev (p11_index *index, continue; if (p11_attrs_matchn (replace[j], attr, 1)) { attrs = NULL; - rv = index_build (index, &attrs, replace[j]); + rv = index_build (index, obj->handle, &attrs, replace[j]); if (rv != CKR_OK) return rv; p11_attrs_free (obj->attrs); diff --git a/trust/index.h b/trust/index.h index 6603092..192bfcd 100644 --- a/trust/index.h +++ b/trust/index.h @@ -44,8 +44,14 @@ typedef struct _p11_index p11_index; typedef CK_RV (* p11_index_build_cb) (void *data, p11_index *index, - CK_ATTRIBUTE **attrs, - CK_ATTRIBUTE *merge); + CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *merge, + CK_ATTRIBUTE **populate); + +typedef CK_RV (* p11_index_store_cb) (void *data, + p11_index *index, + CK_OBJECT_HANDLE handle, + CK_ATTRIBUTE **attrs); typedef void (* p11_index_notify_cb) (void *data, p11_index *index, @@ -53,6 +59,7 @@ typedef void (* p11_index_notify_cb) (void *data, CK_ATTRIBUTE *attrs); p11_index * p11_index_new (p11_index_build_cb build, + p11_index_store_cb store, p11_index_notify_cb notify, void *data); diff --git a/trust/session.c b/trust/session.c index b04b8bf..76a9acf 100644 --- a/trust/session.c +++ b/trust/session.c @@ -61,7 +61,7 @@ p11_session_new (p11_token *token) session->builder = p11_builder_new (P11_BUILDER_FLAG_NONE); return_val_if_fail (session->builder, NULL); - session->index = p11_index_new (p11_builder_build, + session->index = p11_index_new (p11_builder_build, NULL, p11_builder_changed, session->builder); return_val_if_fail (session->index != NULL, NULL); diff --git a/trust/tests/test-builder.c b/trust/tests/test-builder.c index 72ee151..3f71b14 100644 --- a/trust/tests/test-builder.c +++ b/trust/tests/test-builder.c @@ -77,7 +77,7 @@ setup (void *unused) test.builder = p11_builder_new (P11_BUILDER_FLAG_TOKEN); assert_ptr_not_null (test.builder); - test.index = p11_index_new (p11_builder_build, p11_builder_changed, test.builder); + test.index = p11_index_new (p11_builder_build, NULL, p11_builder_changed, test.builder); assert_ptr_not_null (test.index); } @@ -121,13 +121,18 @@ test_build_data (void) CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; attrs = NULL; + extra = NULL; merge = p11_attrs_dup (input); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_OK, rv); + attrs = p11_attrs_merge (attrs, merge, true); + attrs = p11_attrs_merge (attrs, extra, false); + test_check_attrs (check, attrs); p11_attrs_free (attrs); } @@ -160,13 +165,18 @@ test_build_certificate (void) CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; attrs = NULL; + extra = NULL; merge = p11_attrs_dup (input); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_OK, rv); + attrs = p11_attrs_merge (attrs, merge, true); + attrs = p11_attrs_merge (attrs, extra, false); + test_check_attrs (expected, attrs); p11_attrs_free (attrs); } @@ -208,15 +218,20 @@ test_build_certificate_empty (void) CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; p11_hash_sha1 (checksum, test_cacert3_ca_der, sizeof (test_cacert3_ca_der), NULL); attrs = NULL; + extra = NULL; merge = p11_attrs_dup (input); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_OK, rv); + attrs = p11_attrs_merge (attrs, merge, true); + attrs = p11_attrs_merge (attrs, extra, false); + test_check_attrs (expected, attrs); p11_attrs_free (attrs); } @@ -332,12 +347,17 @@ test_build_certificate_non_ca (void) }; CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE *extra; CK_RV rv; attrs = NULL; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + extra = NULL; + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); + attrs = p11_attrs_merge (attrs, p11_attrs_dup (input), true); + attrs = p11_attrs_merge (attrs, extra, false); + test_check_attrs (expected, attrs); p11_attrs_free (attrs); } @@ -358,12 +378,17 @@ test_build_certificate_v1_ca (void) }; CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE *extra; CK_RV rv; attrs = NULL; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + extra = NULL; + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); + attrs = p11_attrs_merge (attrs, p11_attrs_dup (input), true); + attrs = p11_attrs_merge (attrs, extra, false); + test_check_attrs (expected, attrs); p11_attrs_free (attrs); } @@ -394,6 +419,7 @@ test_build_certificate_staple_ca (void) }; CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE *extra; CK_RV rv; /* Add a stapled certificate */ @@ -401,9 +427,13 @@ test_build_certificate_staple_ca (void) assert_num_eq (CKR_OK, rv); attrs = NULL; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + extra = NULL; + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); + attrs = p11_attrs_merge (attrs, p11_attrs_dup (input), true); + attrs = p11_attrs_merge (attrs, extra, false); + /* * Even though the certificate is not a valid CA, the presence of the * stapled certificate extension transforms it into a CA. @@ -422,13 +452,15 @@ test_build_certificate_no_type (void) CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; p11_message_quiet (); attrs = NULL; + extra = NULL; merge = p11_attrs_dup (input); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_TEMPLATE_INCOMPLETE, rv); p11_attrs_free (merge); @@ -448,13 +480,14 @@ test_build_certificate_bad_type (void) CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; p11_message_quiet (); attrs = NULL; merge = p11_attrs_dup (input); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_TEMPLATE_INCONSISTENT, rv); p11_attrs_free (merge); @@ -484,12 +517,17 @@ test_build_extension (void) }; CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE *extra; CK_RV rv; attrs = NULL; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + extra = NULL; + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); + attrs = p11_attrs_merge (attrs, p11_attrs_dup (input), true); + attrs = p11_attrs_merge (attrs, extra, false); + test_check_attrs (check, attrs); p11_attrs_free (attrs); } @@ -538,12 +576,17 @@ test_build_distant_end_date (void) }; CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE *extra; CK_RV rv; attrs = NULL; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + extra = NULL; + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); + attrs = p11_attrs_merge (attrs, p11_attrs_dup (input), true); + attrs = p11_attrs_merge (attrs, extra, false); + test_check_attrs (expected, attrs); p11_attrs_free (attrs); } @@ -552,6 +595,7 @@ static void test_valid_bool (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_BBOOL value = CK_TRUE; CK_RV rv; @@ -562,16 +606,17 @@ test_valid_bool (void) { CKA_INVALID }, }; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); - p11_attrs_free (attrs); + p11_attrs_free (extra); } static void test_invalid_bool (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_RV rv; CK_ATTRIBUTE input[] = { @@ -585,13 +630,13 @@ test_invalid_bool (void) input[0].pValue = "123"; input[0].ulValueLen = 3; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); input[0].pValue = NULL; input[0].ulValueLen = sizeof (CK_BBOOL); - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); p11_message_loud (); @@ -601,6 +646,7 @@ static void test_valid_ulong (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_ULONG value = 2; CK_RV rv; @@ -611,16 +657,17 @@ test_valid_ulong (void) { CKA_INVALID }, }; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); - p11_attrs_free (attrs); + p11_attrs_free (extra); } static void test_invalid_ulong (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_RV rv; CK_ATTRIBUTE input[] = { @@ -634,13 +681,13 @@ test_invalid_ulong (void) input[0].pValue = "123"; input[0].ulValueLen = 3; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); input[0].pValue = NULL; input[0].ulValueLen = sizeof (CK_ULONG); - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); p11_message_loud (); @@ -650,6 +697,7 @@ static void test_valid_utf8 (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_RV rv; CK_ATTRIBUTE input[] = { @@ -661,16 +709,17 @@ test_valid_utf8 (void) input[0].pValue = NULL; input[0].ulValueLen = 0; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); - p11_attrs_free (attrs); + p11_attrs_free (extra); } static void test_invalid_utf8 (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_RV rv; CK_ATTRIBUTE input[] = { @@ -684,13 +733,13 @@ test_invalid_utf8 (void) input[0].pValue = "\xfex23"; input[0].ulValueLen = 4; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); input[0].pValue = NULL; input[0].ulValueLen = 4; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); p11_message_loud (); @@ -700,6 +749,7 @@ static void test_valid_dates (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_DATE date; CK_RV rv; @@ -711,14 +761,14 @@ test_valid_dates (void) }; memcpy (&date, "20001010", sizeof (date)); - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); p11_attrs_free (attrs); attrs = NULL; input[0].ulValueLen = 0; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); p11_attrs_free (attrs); @@ -728,6 +778,7 @@ static void test_invalid_dates (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_DATE date; CK_RV rv; @@ -741,15 +792,15 @@ test_invalid_dates (void) p11_message_quiet (); memcpy (&date, "AAAABBCC", sizeof (date)); - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); memcpy (&date, "20001580", sizeof (date)); - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); input[0].pValue = NULL; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); p11_message_loud (); @@ -759,6 +810,7 @@ static void test_valid_name (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_RV rv; CK_ATTRIBUTE input[] = { @@ -770,7 +822,7 @@ test_valid_name (void) input[0].pValue = NULL; input[0].ulValueLen = 0; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); p11_attrs_free (attrs); @@ -778,7 +830,7 @@ test_valid_name (void) input[0].pValue = (void *)test_cacert3_ca_issuer; input[0].ulValueLen = sizeof (test_cacert3_ca_issuer); - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); p11_attrs_free (attrs); @@ -788,6 +840,7 @@ static void test_invalid_name (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_RV rv; CK_ATTRIBUTE input[] = { @@ -801,12 +854,12 @@ test_invalid_name (void) input[0].pValue = "blah"; input[0].ulValueLen = 4; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); input[0].pValue = NULL; input[0].ulValueLen = 4; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); p11_message_loud (); @@ -816,6 +869,7 @@ static void test_valid_serial (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_RV rv; CK_ATTRIBUTE input[] = { @@ -827,24 +881,25 @@ test_valid_serial (void) input[0].pValue = NULL; input[0].ulValueLen = 0; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); - p11_attrs_free (attrs); + p11_attrs_free (extra); attrs = NULL; input[0].pValue = (void *)test_cacert3_ca_serial; input[0].ulValueLen = sizeof (test_cacert3_ca_serial); - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); - p11_attrs_free (attrs); + p11_attrs_free (extra); } static void test_invalid_serial (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_RV rv; CK_ATTRIBUTE input[] = { @@ -858,17 +913,17 @@ test_invalid_serial (void) input[0].pValue = "blah"; input[0].ulValueLen = 4; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); input[0].pValue = (void *)test_cacert3_ca_subject; input[0].ulValueLen = sizeof (test_cacert3_ca_subject); - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); input[0].pValue = NULL; input[0].ulValueLen = 4; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); p11_message_loud (); @@ -878,6 +933,7 @@ static void test_valid_cert (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_RV rv; CK_ATTRIBUTE input[] = { @@ -889,24 +945,25 @@ test_valid_cert (void) input[0].pValue = NULL; input[0].ulValueLen = 0; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); - p11_attrs_free (attrs); + p11_attrs_free (extra); attrs = NULL; input[0].pValue = (void *)test_cacert3_ca_der; input[0].ulValueLen = sizeof (test_cacert3_ca_der); - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); - p11_attrs_free (attrs); + p11_attrs_free (extra); } static void test_invalid_cert (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_RV rv; CK_ATTRIBUTE input[] = { @@ -920,17 +977,17 @@ test_invalid_cert (void) input[0].pValue = "blah"; input[0].ulValueLen = 4; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); input[0].pValue = (void *)test_cacert3_ca_subject; input[0].ulValueLen = sizeof (test_cacert3_ca_subject); - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); input[0].pValue = NULL; input[0].ulValueLen = 4; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); p11_message_loud (); @@ -940,6 +997,7 @@ static void test_invalid_schema (void) { CK_ATTRIBUTE *attrs = NULL; + CK_ATTRIBUTE *extra = NULL; CK_RV rv; CK_ATTRIBUTE input[] = { @@ -952,7 +1010,7 @@ test_invalid_schema (void) p11_message_quiet (); /* Missing CKA_HASH_OF_SUBJECT_PUBLIC_KEY and CKA_HASH_OF_ISSUER_PUBLIC_KEY */ - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_TEMPLATE_INCONSISTENT, rv); p11_message_loud (); @@ -962,26 +1020,27 @@ static void test_create_not_settable (void) { /* - * CKA_TRUSTED cannot be set by the normal user according to spec + * CKA_X_PUBLIC_KEY_INFO cannot be created/modified */ CK_ATTRIBUTE input[] = { { CKA_CLASS, &certificate, sizeof (certificate) }, { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, - { CKA_TRUSTED, &falsev, sizeof (falsev) }, { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) }, + { CKA_X_PUBLIC_KEY_INFO, (void *)verisign_v1_ca_public_key, sizeof (verisign_v1_ca_public_key) }, { CKA_INVALID }, }; CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; p11_message_quiet (); attrs = NULL; merge = p11_attrs_dup (input); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_ATTRIBUTE_READ_ONLY, rv); p11_attrs_free (merge); @@ -994,29 +1053,33 @@ static void test_create_but_loadable (void) { /* - * CKA_TRUSTED cannot be set on creation, but can be set if we're + * CKA_X_PUBLIC_KEY_INFO cannot be set on creation, but can be set if we're * loading from our store. This is signified by batching. */ CK_ATTRIBUTE input[] = { { CKA_CLASS, &certificate, sizeof (certificate) }, { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, - { CKA_TRUSTED, &falsev, sizeof (falsev) }, { CKA_VALUE, (void *)test_cacert3_ca_der, sizeof (test_cacert3_ca_der) }, + { CKA_X_PUBLIC_KEY_INFO, (void *)verisign_v1_ca_public_key, sizeof (verisign_v1_ca_public_key) }, { CKA_INVALID }, }; CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE *extra; CK_RV rv; p11_index_load (test.index); attrs = NULL; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); p11_index_finish (test.index); + attrs = p11_attrs_merge (attrs, p11_attrs_dup (input), true); + attrs = p11_attrs_merge (attrs, extra, false); + test_check_attrs (input, attrs); p11_attrs_free (attrs); } @@ -1033,13 +1096,15 @@ test_create_unsupported (void) CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; p11_message_quiet (); attrs = NULL; + extra = NULL; merge = p11_attrs_dup (input); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_TEMPLATE_INCONSISTENT, rv); p11_attrs_free (merge); @@ -1058,13 +1123,15 @@ test_create_generated (void) CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; p11_message_quiet (); attrs = NULL; + extra = NULL; merge = p11_attrs_dup (input); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_TEMPLATE_INCONSISTENT, rv); p11_attrs_free (merge); @@ -1083,13 +1150,15 @@ test_create_bad_attribute (void) CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; p11_message_quiet (); attrs = NULL; + extra = NULL; merge = p11_attrs_dup (input); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_TEMPLATE_INCONSISTENT, rv); p11_attrs_free (merge); @@ -1106,13 +1175,15 @@ test_create_missing_attribute (void) CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; p11_message_quiet (); attrs = NULL; + extra = NULL; merge = p11_attrs_dup (input); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_TEMPLATE_INCOMPLETE, rv); p11_attrs_free (merge); @@ -1129,13 +1200,15 @@ test_create_no_class (void) CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; p11_message_quiet (); attrs = NULL; + extra = NULL; merge = p11_attrs_dup (input); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_TEMPLATE_INCOMPLETE, rv); p11_attrs_free (merge); @@ -1153,13 +1226,15 @@ test_create_token_mismatch (void) CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; p11_message_quiet (); attrs = NULL; + extra = NULL; merge = p11_attrs_dup (input); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_TEMPLATE_INCONSISTENT, rv); p11_attrs_free (merge); @@ -1191,15 +1266,24 @@ test_modify_success (void) }; CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE *extra; CK_RV rv; attrs = NULL; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + extra = NULL; + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (modify)); + attrs = p11_attrs_merge (attrs, p11_attrs_dup (input), true); + attrs = p11_attrs_merge (attrs, extra, false); + + extra = NULL; + rv = p11_builder_build (test.builder, test.index, attrs, modify, &extra); assert_num_eq (CKR_OK, rv); + attrs = p11_attrs_merge (attrs, p11_attrs_dup (modify), true); + attrs = p11_attrs_merge (attrs, extra, false); + test_check_attrs (expected, attrs); p11_attrs_free (attrs); } @@ -1221,17 +1305,23 @@ test_modify_read_only (void) CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; attrs = NULL; + extra = NULL; merge = p11_attrs_dup (input); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_OK, rv); + attrs = p11_attrs_merge (attrs, merge, true); + attrs = p11_attrs_merge (attrs, extra, false); + p11_message_quiet (); + extra = NULL; merge = p11_attrs_dup (modify); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_ATTRIBUTE_READ_ONLY, rv); p11_attrs_free (merge); @@ -1268,15 +1358,23 @@ test_modify_unchanged (void) }; CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE *extra; CK_RV rv; attrs = NULL; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (modify)); + attrs = p11_attrs_merge (attrs, p11_attrs_dup (input), true); + attrs = p11_attrs_merge (attrs, extra, false); + + extra = NULL; + rv = p11_builder_build (test.builder, test.index, attrs, modify, &extra); assert_num_eq (CKR_OK, rv); + attrs = p11_attrs_merge (attrs, p11_attrs_dup (modify), true); + attrs = p11_attrs_merge (attrs, extra, false); + test_check_attrs (expected, attrs); p11_attrs_free (attrs); } @@ -1298,16 +1396,22 @@ test_modify_not_modifiable (void) CK_ATTRIBUTE *attrs; CK_ATTRIBUTE *merge; + CK_ATTRIBUTE *extra; CK_RV rv; attrs = NULL; - rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + extra = NULL; + rv = p11_builder_build (test.builder, test.index, attrs, input, &extra); assert_num_eq (CKR_OK, rv); + attrs = p11_attrs_merge (attrs, p11_attrs_dup (input), true); + attrs = p11_attrs_merge (attrs, extra, false); + p11_message_quiet (); + extra = NULL; merge = p11_attrs_dup (modify); - rv = p11_builder_build (test.builder, test.index, &attrs, merge); + rv = p11_builder_build (test.builder, test.index, attrs, merge, &extra); assert_num_eq (CKR_ATTRIBUTE_READ_ONLY, rv); p11_attrs_free (merge); diff --git a/trust/tests/test-index.c b/trust/tests/test-index.c index 8932da6..73fc359 100644 --- a/trust/tests/test-index.c +++ b/trust/tests/test-index.c @@ -53,7 +53,7 @@ struct { static void setup (void *unused) { - test.index = p11_index_new (NULL, NULL, NULL); + test.index = p11_index_new (NULL, NULL, NULL, NULL); assert_ptr_not_null (test.index); } @@ -657,22 +657,20 @@ test_replace_all (void) static CK_RV on_build_populate (void *data, p11_index *index, - CK_ATTRIBUTE **attrs, - CK_ATTRIBUTE *merge) + CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *merge, + CK_ATTRIBUTE **populate) { - CK_ATTRIBUTE override[] = { + CK_ATTRIBUTE more[] = { { CKA_APPLICATION, "vigorous", 8 }, { CKA_LABEL, "naay", 4 }, - { CKA_INVALID }, }; assert_str_eq (data, "blah"); assert_ptr_not_null (index); - assert_ptr_not_null (attrs); assert_ptr_not_null (merge); - *attrs = p11_attrs_merge (*attrs, merge, true); - *attrs = p11_attrs_merge (*attrs, p11_attrs_dup (override), true); + *populate = p11_attrs_buildn (*populate, more, 2); return CKR_OK; } @@ -687,7 +685,7 @@ test_build_populate (void) }; CK_ATTRIBUTE after[] = { - { CKA_LABEL, "naay", 4 }, + { CKA_LABEL, "yay", 3 }, { CKA_VALUE, "eight", 5 }, { CKA_APPLICATION, "vigorous", 8 }, { CKA_INVALID } @@ -698,7 +696,7 @@ test_build_populate (void) p11_index *index; CK_RV rv; - index = p11_index_new (on_build_populate, NULL, "blah"); + index = p11_index_new (on_build_populate, NULL, NULL, "blah"); assert_ptr_not_null (index); rv = p11_index_add (index, original, 2, &handle); @@ -723,8 +721,9 @@ test_build_populate (void) static CK_RV on_build_fail (void *data, p11_index *index, - CK_ATTRIBUTE **attrs, - CK_ATTRIBUTE *merge) + CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *merge, + CK_ATTRIBUTE **populate) { CK_ATTRIBUTE check[] = { { CKA_LABEL, "nay", 3 }, @@ -737,7 +736,6 @@ on_build_fail (void *data, if (p11_attrs_match (merge, check)) return CKR_DEVICE_ERROR; - *attrs = p11_attrs_merge (*attrs, merge, true); return CKR_OK; } @@ -761,7 +759,7 @@ test_build_fail (void) p11_index *index; CK_RV rv; - index = p11_index_new (on_build_fail, NULL, "testo"); + index = p11_index_new (on_build_fail, NULL, NULL, "testo"); assert_ptr_not_null (index); rv = p11_index_add (index, okay, 2, &handle); @@ -825,7 +823,7 @@ test_change_called (void) p11_index *index; CK_RV rv; - index = p11_index_new (NULL, on_change_check, "change-check"); + index = p11_index_new (NULL, NULL, on_change_check, "change-check"); assert_ptr_not_null (index); on_change_removing = false; @@ -870,7 +868,7 @@ test_change_batch (void) p11_index *index; CK_RV rv; - index = p11_index_new (NULL, on_change_check, "change-check"); + index = p11_index_new (NULL, NULL, on_change_check, "change-check"); assert_ptr_not_null (index); on_change_batching = true; @@ -961,7 +959,7 @@ test_change_nested (void) p11_index *index; CK_RV rv; - index = p11_index_new (NULL, on_change_nested, "change-nested"); + index = p11_index_new (NULL, NULL, on_change_nested, "change-nested"); assert_ptr_not_null (index); on_change_called = 0; diff --git a/trust/token.c b/trust/token.c index ca24762..0641619 100644 --- a/trust/token.c +++ b/trust/token.c @@ -73,8 +73,9 @@ struct _p11_token { char *label; /* The token label */ CK_SLOT_ID slot; /* The slot id */ - bool checked_writable; + bool checked_path; bool is_writable; + bool make_directory; }; static bool @@ -422,6 +423,60 @@ p11_token_reload (p11_token *token, return loader_load_file (token, origin, &sb) > 0; } +static bool +check_directory (const char *path, + bool *make_directory, + bool *is_writable) +{ + struct stat sb; + char *parent; + bool dummy; + bool ret; + + /* + * This function attempts to determine whether a later write + * to this token will succeed so we can setup the appropriate + * token flags. Yes, it is racy, but that's inherent to the problem. + */ + + if (stat (path, &sb) == 0) { + *make_directory = false; + *is_writable = S_ISDIR (sb.st_mode) && access (path, W_OK) == 0; + return true; + } + + switch (errno) { + case EACCES: + *is_writable = false; + *make_directory = false; + return true; + case ENOENT: + *make_directory = true; + parent = p11_path_parent (path); + if (parent == NULL) + ret = false; + else + ret = check_directory (parent, &dummy, is_writable); + free (parent); + return ret; + default: + p11_message ("couldn't access: %s: %s", path, strerror (errno)); + return false; + } +} + +static bool +check_token_directory (p11_token *token) +{ + if (!token->checked_path) { + token->checked_path = check_directory (token->path, + &token->make_directory, + &token->is_writable); + } + + return token->checked_path; +} + static p11_save_file * writer_overwrite_origin (p11_token *token, CK_ATTRIBUTE *origin) @@ -515,11 +570,50 @@ writer_put_object (p11_save_file *file, return CKR_OK; } +static bool +mkdir_with_parents (const char *path) +{ + int mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + char *parent; + bool ret; + + if (mkdir (path, mode) == 0) + return true; + + switch (errno) { + case ENOENT: + parent = p11_path_parent (path); + if (parent != NULL) { + ret = mkdir_with_parents (parent); + free (parent); + if (ret == true) { + if (mkdir (path, mode) == 0) + return true; + } + } + /* fall through */ + default: + p11_message ("couldn't create directory: %s: %s", path, strerror (errno)); + return false; + } +} + static CK_RV on_index_build (void *data, p11_index *index, - CK_ATTRIBUTE **attrs, - CK_ATTRIBUTE *merge) + CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *merge, + CK_ATTRIBUTE **extra) +{ + p11_token *token = data; + return p11_builder_build (token->builder, index, attrs, merge, extra); +} + +static CK_RV +on_index_store (void *data, + p11_index *index, + CK_OBJECT_HANDLE handle, + CK_ATTRIBUTE **attrs) { p11_token *token = data; CK_OBJECT_HANDLE *other; @@ -533,14 +627,19 @@ on_index_build (void *data, CK_RV rv; int i; - rv = p11_builder_build (token->builder, index, attrs, merge); - if (rv != CKR_OK) - return rv; - /* Signifies that data is being loaded, don't write out */ if (p11_index_loading (index)) return CKR_OK; + if (!check_token_directory (token)) + return CKR_FUNCTION_FAILED; + + if (token->make_directory) { + if (!mkdir_with_parents (token->path)) + return CKR_FUNCTION_FAILED; + token->make_directory = false; + } + /* Do we already have a filename? */ origin = p11_attrs_find (*attrs, CKA_X_ORIGIN); if (origin == NULL) { @@ -567,9 +666,11 @@ on_index_build (void *data, rv = writer_put_object (file, persist, &buffer, *attrs); for (i = 0; rv == CKR_OK && other && other[i] != 0; i++) { - object = p11_index_lookup (index, other[i]); - if (object != NULL && object != *attrs) - rv = writer_put_object (file, persist, &buffer, object); + if (other[i] != handle) { + object = p11_index_lookup (index, handle); + if (object != NULL) + rv = writer_put_object (file, persist, &buffer, object); + } } p11_buffer_uninit (&buffer); @@ -632,7 +733,10 @@ p11_token_new (CK_SLOT_ID slot, token->builder = p11_builder_new (P11_BUILDER_FLAG_TOKEN); return_val_if_fail (token->builder != NULL, NULL); - token->index = p11_index_new (on_index_build, on_index_notify, token); + token->index = p11_index_new (on_index_build, + on_index_store, + on_index_notify, + token); return_val_if_fail (token->index != NULL, NULL); token->parser = p11_parser_new (p11_builder_get_cache (token->builder)); @@ -698,46 +802,10 @@ p11_token_parser (p11_token *token) return token->parser; } -static bool -check_writable_directory (const char *path) -{ - struct stat sb; - char *parent; - bool ret; - - if (access (path, W_OK) == 0) - return stat (path, &sb) == 0 && S_ISDIR (sb.st_mode); - - switch (errno) { - case EACCES: - return false; - case ENOENT: - parent = p11_path_parent (path); - if (parent == NULL) - ret = false; - else - ret = check_writable_directory (parent); - free (parent); - return ret; - default: - p11_message ("couldn't access: %s: %s", path, strerror (errno)); - return false; - } -} - bool p11_token_is_writable (p11_token *token) { - /* - * This function attempts to determine whether a later write - * to this token will succeed so we can setup the appropriate - * token flags. Yes, it is racy, but that's inherent to the problem. - */ - - if (!token->checked_writable) { - token->is_writable = check_writable_directory (token->path); - token->checked_writable = true; - } - + if (!check_token_directory (token)) + return false; return token->is_writable; } |