summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@thewalter.net>2013-07-08 18:38:38 +0200
committerStef Walter <stef@thewalter.net>2013-07-08 18:38:38 +0200
commitdcca67d72544e394f43a8c62840692c85d5b5b29 (patch)
tree3da7943c17378457d40e10a9d72a96f725221922
parent3318c443b7a3660f0aee80cfa0d5e915d3a21734 (diff)
downloadp11-kit-dcca67d72544e394f43a8c62840692c85d5b5b29.tar.gz
trust: Fix various issues writing objects in trust token
* Create directory before trying to write files to it * Handle write failures appropriately Refactor how we build and store objects in the index to handle the above cases properly.
-rw-r--r--trust/builder.c152
-rw-r--r--trust/builder.h5
-rw-r--r--trust/index.c129
-rw-r--r--trust/index.h11
-rw-r--r--trust/session.c2
-rw-r--r--trust/tests/test-builder.c238
-rw-r--r--trust/tests/test-index.c32
-rw-r--r--trust/token.c166
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;
}