summaryrefslogtreecommitdiff
path: root/trust
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2013-05-21 21:46:27 +0200
committerStef Walter <stefw@gnome.org>2013-05-27 10:46:11 +0200
commit96771f49dc945800ae28c77ff407753cbb995c7f (patch)
tree595d2bc1779c55b12912c32bd05920bff8d41e36 /trust
parentdaf63f2cf66669b3555f2f15498a0aa2db234b2f (diff)
persist: Support for writing out p11-kit persist files
Diffstat (limited to 'trust')
-rw-r--r--trust/parser.c10
-rw-r--r--trust/persist.c458
-rw-r--r--trust/persist.h4
-rw-r--r--trust/tests/test-persist.c203
-rw-r--r--trust/tests/test-trust.c2
5 files changed, 587 insertions, 90 deletions
diff --git a/trust/parser.c b/trust/parser.c
index 7690d6a..21b693b 100644
--- a/trust/parser.c
+++ b/trust/parser.c
@@ -675,10 +675,14 @@ parse_p11_kit_persist (p11_parser *parser,
const unsigned char *data,
size_t length)
{
+ CK_BBOOL modifiablev = CK_FALSE;
+ CK_ATTRIBUTE *attrs;
p11_array *objects;
bool ret;
int i;
+ CK_ATTRIBUTE modifiable = { CKA_MODIFIABLE, &modifiablev, sizeof (modifiablev) };
+
if (!p11_persist_magic (data, length))
return P11_PARSE_UNRECOGNIZED;
@@ -692,8 +696,10 @@ parse_p11_kit_persist (p11_parser *parser,
ret = p11_persist_read (parser->persist, parser->basename, data, length, objects);
if (ret) {
- for (i = 0; i < objects->num; i++)
- sink_object (parser, objects->elem[i]);
+ for (i = 0; i < objects->num; i++) {
+ attrs = p11_attrs_build (objects->elem[i], &modifiable, NULL);
+ sink_object (parser, attrs);
+ }
}
p11_array_free (objects);
diff --git a/trust/persist.c b/trust/persist.c
index 69af697..ad80683 100644
--- a/trust/persist.c
+++ b/trust/persist.c
@@ -41,12 +41,15 @@
#include "lexer.h"
#include "pem.h"
#include "persist.h"
+#include "pkcs11.h"
+#include "pkcs11x.h"
#include "url.h"
#include "basic.asn.h"
#include <libtasn1.h>
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
@@ -55,12 +58,6 @@
struct _p11_persist {
p11_dict *constants;
node_asn *asn1_defs;
-
- /* Used during parsing */
- p11_lexer lexer;
- CK_ATTRIBUTE *attrs;
- bool result;
- bool skip;
};
bool
@@ -127,6 +124,20 @@ parse_string (p11_lexer *lexer,
return true;
}
+static void
+format_string (CK_ATTRIBUTE *attr,
+ p11_buffer *buf)
+{
+ const unsigned char *value;
+
+ assert (attr->ulValueLen != CK_UNAVAILABLE_INFORMATION);
+
+ p11_buffer_add (buf, "\"", 1);
+ value = attr->pValue;
+ p11_url_encode (value, value + attr->ulValueLen, P11_URL_VERBATIM, buf);
+ p11_buffer_add (buf, "\"", 1);
+}
+
static bool
parse_bool (p11_lexer *lexer,
CK_ATTRIBUTE *attr)
@@ -152,6 +163,56 @@ parse_bool (p11_lexer *lexer,
}
static bool
+format_bool (CK_ATTRIBUTE *attr,
+ p11_buffer *buf)
+{
+ const CK_BBOOL *value;
+
+ if (attr->ulValueLen != sizeof (CK_BBOOL))
+ return false;
+
+ switch (attr->type) {
+ case CKA_TOKEN:
+ case CKA_PRIVATE:
+ case CKA_TRUSTED:
+ case CKA_SENSITIVE:
+ case CKA_ENCRYPT:
+ case CKA_DECRYPT:
+ case CKA_WRAP:
+ case CKA_UNWRAP:
+ case CKA_SIGN:
+ case CKA_SIGN_RECOVER:
+ case CKA_VERIFY:
+ case CKA_VERIFY_RECOVER:
+ case CKA_DERIVE:
+ case CKA_EXTRACTABLE:
+ case CKA_LOCAL:
+ case CKA_NEVER_EXTRACTABLE:
+ case CKA_ALWAYS_SENSITIVE:
+ case CKA_MODIFIABLE:
+ case CKA_SECONDARY_AUTH:
+ case CKA_ALWAYS_AUTHENTICATE:
+ case CKA_WRAP_WITH_TRUSTED:
+ case CKA_RESET_ON_INIT:
+ case CKA_HAS_RESET:
+ case CKA_COLOR:
+ break;
+ default:
+ return false;
+ }
+
+ value = attr->pValue;
+ if (*value == CK_TRUE)
+ p11_buffer_add (buf, "true", -1);
+ else if (*value == CK_FALSE)
+ p11_buffer_add (buf, "false", -1);
+ else
+ return false;
+
+ return true;
+}
+
+static bool
parse_ulong (p11_lexer *lexer,
CK_ATTRIBUTE *attr)
{
@@ -172,6 +233,66 @@ parse_ulong (p11_lexer *lexer,
}
static bool
+format_ulong (CK_ATTRIBUTE *attr,
+ p11_buffer *buf)
+{
+ char string[sizeof (CK_ULONG) * 4];
+ const CK_ULONG *value;
+
+ if (attr->ulValueLen != sizeof (CK_ULONG))
+ return false;
+
+ switch (attr->type) {
+ case CKA_CERTIFICATE_CATEGORY:
+ case CKA_CERTIFICATE_TYPE:
+ case CKA_CLASS:
+ case CKA_JAVA_MIDP_SECURITY_DOMAIN:
+ case CKA_KEY_GEN_MECHANISM:
+ case CKA_KEY_TYPE:
+ case CKA_MECHANISM_TYPE:
+ case CKA_MODULUS_BITS:
+ case CKA_PRIME_BITS:
+ case CKA_SUB_PRIME_BITS:
+ case CKA_VALUE_BITS:
+ case CKA_VALUE_LEN:
+ case CKA_TRUST_DIGITAL_SIGNATURE:
+ case CKA_TRUST_NON_REPUDIATION:
+ case CKA_TRUST_KEY_ENCIPHERMENT:
+ case CKA_TRUST_DATA_ENCIPHERMENT:
+ case CKA_TRUST_KEY_AGREEMENT:
+ case CKA_TRUST_KEY_CERT_SIGN:
+ case CKA_TRUST_CRL_SIGN:
+ case CKA_TRUST_SERVER_AUTH:
+ case CKA_TRUST_CLIENT_AUTH:
+ case CKA_TRUST_CODE_SIGNING:
+ case CKA_TRUST_EMAIL_PROTECTION:
+ case CKA_TRUST_IPSEC_END_SYSTEM:
+ case CKA_TRUST_IPSEC_TUNNEL:
+ case CKA_TRUST_IPSEC_USER:
+ case CKA_TRUST_TIME_STAMPING:
+ case CKA_TRUST_STEP_UP_APPROVED:
+ case CKA_X_ASSERTION_TYPE:
+ case CKA_AUTH_PIN_FLAGS:
+ case CKA_HW_FEATURE_TYPE:
+ case CKA_PIXEL_X:
+ case CKA_PIXEL_Y:
+ case CKA_RESOLUTION:
+ case CKA_CHAR_ROWS:
+ case CKA_CHAR_COLUMNS:
+ case CKA_BITS_PER_PIXEL:
+ break;
+ default:
+ return false;
+ }
+
+ value = attr->pValue;
+ snprintf (string, sizeof (string), "%lu", *value);
+
+ p11_buffer_add (buf, string, -1);
+ return true;
+}
+
+static bool
parse_constant (p11_persist *persist,
p11_lexer *lexer,
CK_ATTRIBUTE *attr)
@@ -190,6 +311,70 @@ parse_constant (p11_persist *persist,
return true;
}
+static bool
+format_constant (CK_ATTRIBUTE *attr,
+ p11_buffer *buf)
+{
+ const p11_constant *table;
+ const CK_ULONG *value;
+ const char *nick;
+
+ if (attr->ulValueLen != sizeof (CK_ULONG))
+ return false;
+
+ switch (attr->type) {
+ case CKA_TRUST_DIGITAL_SIGNATURE:
+ case CKA_TRUST_NON_REPUDIATION:
+ case CKA_TRUST_KEY_ENCIPHERMENT:
+ case CKA_TRUST_DATA_ENCIPHERMENT:
+ case CKA_TRUST_KEY_AGREEMENT:
+ case CKA_TRUST_KEY_CERT_SIGN:
+ case CKA_TRUST_CRL_SIGN:
+ case CKA_TRUST_SERVER_AUTH:
+ case CKA_TRUST_CLIENT_AUTH:
+ case CKA_TRUST_CODE_SIGNING:
+ case CKA_TRUST_EMAIL_PROTECTION:
+ case CKA_TRUST_IPSEC_END_SYSTEM:
+ case CKA_TRUST_IPSEC_TUNNEL:
+ case CKA_TRUST_IPSEC_USER:
+ case CKA_TRUST_TIME_STAMPING:
+ table = p11_constant_trusts;
+ break;
+ case CKA_CLASS:
+ table = p11_constant_classes;
+ break;
+ case CKA_CERTIFICATE_TYPE:
+ table = p11_constant_certs;
+ break;
+ case CKA_KEY_TYPE:
+ table = p11_constant_keys;
+ break;
+ case CKA_X_ASSERTION_TYPE:
+ table = p11_constant_asserts;
+ break;
+ case CKA_CERTIFICATE_CATEGORY:
+ table = p11_constant_categories;
+ break;
+ case CKA_KEY_GEN_MECHANISM:
+ case CKA_MECHANISM_TYPE:
+ table = p11_constant_mechanisms;
+ break;
+ default:
+ table = NULL;
+ };
+
+ if (!table)
+ return false;
+
+ value = attr->pValue;
+ nick = p11_constant_nick (table, *value);
+
+ if (!nick)
+ return false;
+
+ p11_buffer_add (buf, nick, -1);
+ return true;
+}
static bool
parse_oid (p11_persist *persist,
@@ -249,6 +434,60 @@ parse_oid (p11_persist *persist,
}
static bool
+format_oid (p11_persist *persist,
+ CK_ATTRIBUTE *attr,
+ p11_buffer *buf)
+{
+ char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = { 0, };
+ node_asn *asn;
+ char *data;
+ int len;
+ int ret;
+
+ if (attr->type != CKA_OBJECT_ID)
+ return false;
+
+ if (!persist->asn1_defs) {
+ ret = asn1_array2tree (basic_asn1_tab, &persist->asn1_defs, message);
+ if (ret != ASN1_SUCCESS) {
+ p11_debug_precond ("failed to load BASIC definitions: %s: %s\n",
+ asn1_strerror (ret), message);
+ return false;
+ }
+ }
+
+ ret = asn1_create_element (persist->asn1_defs, "BASIC.ObjectIdentifier", &asn);
+ if (ret != ASN1_SUCCESS) {
+ p11_debug_precond ("failed to create ObjectIdentifier element: %s\n",
+ asn1_strerror (ret));
+ return false;
+ }
+
+ ret = asn1_der_decoding (&asn, attr->pValue, attr->ulValueLen, message);
+ if (ret != ASN1_SUCCESS) {
+ p11_debug_precond ("invalid oid value: %s", message);
+ return false;
+ }
+
+ len = 0;
+ ret = asn1_read_value (asn, "", NULL, &len);
+ return_val_if_fail (ret == ASN1_MEM_ERROR, false);
+
+ data = calloc (len + 1, 1);
+ return_val_if_fail (data != NULL, false);
+
+ ret = asn1_read_value (asn, "", data, &len);
+ return_val_if_fail (ret == ASN1_SUCCESS, false);
+
+ asn1_delete_structure (&asn);
+
+ p11_buffer_add (buf, data, len - 1);
+ free (data);
+
+ return true;
+}
+
+static bool
parse_value (p11_persist *persist,
p11_lexer *lexer,
CK_ATTRIBUTE *attr)
@@ -260,16 +499,41 @@ parse_value (p11_persist *persist,
parse_oid (persist, lexer, attr);
}
+static void
+format_value (p11_persist *persist,
+ CK_ATTRIBUTE *attr,
+ p11_buffer *buf)
+{
+ assert (attr->ulValueLen != CK_UNAVAILABLE_INFORMATION);
+
+ if (format_bool (attr, buf) ||
+ format_constant (attr, buf) ||
+ format_ulong (attr, buf) ||
+ format_oid (persist, attr, buf))
+ return;
+
+ /* Everything else as string */
+ format_string (attr, buf);
+}
+
static bool
field_to_attribute (p11_persist *persist,
- p11_lexer *lexer)
+ p11_lexer *lexer,
+ CK_ATTRIBUTE **attrs)
{
CK_ATTRIBUTE attr = { 0, };
+ char *end;
- attr.type = p11_constant_resolve (persist->constants, lexer->tok.field.name);
- if (attr.type == CKA_INVALID || !p11_constant_name (p11_constant_types, attr.type)) {
- p11_lexer_msg (lexer, "invalid or unsupported attribute");
- return false;
+ end = NULL;
+ attr.type = strtoul (lexer->tok.field.name, &end, 10);
+
+ /* Not a valid number value, probably a constant */
+ if (!end || *end != '\0') {
+ attr.type = p11_constant_resolve (persist->constants, lexer->tok.field.name);
+ if (attr.type == CKA_INVALID || !p11_constant_name (p11_constant_types, attr.type)) {
+ p11_lexer_msg (lexer, "invalid or unsupported attribute");
+ return false;
+ }
}
if (!parse_value (persist, lexer, &attr)) {
@@ -277,51 +541,61 @@ field_to_attribute (p11_persist *persist,
return false;
}
- persist->attrs = p11_attrs_take (persist->attrs, attr.type,
- attr.pValue, attr.ulValueLen);
+ *attrs = p11_attrs_take (*attrs, attr.type,
+ attr.pValue, attr.ulValueLen);
return true;
}
-static void
-on_pem_block (const char *type,
- const unsigned char *contents,
- size_t length,
- void *user_data)
+static CK_ATTRIBUTE *
+certificate_to_attributes (const unsigned char *der,
+ size_t length)
{
CK_OBJECT_CLASS klassv = CKO_CERTIFICATE;
CK_CERTIFICATE_TYPE x509 = CKC_X_509;
- CK_BBOOL modifiablev = CK_FALSE;
- CK_ATTRIBUTE modifiable = { CKA_MODIFIABLE, &modifiablev, sizeof (modifiablev) };
CK_ATTRIBUTE klass = { CKA_CLASS, &klassv, sizeof (klassv) };
CK_ATTRIBUTE certificate_type = { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) };
- CK_ATTRIBUTE value = { CKA_VALUE, };
+ CK_ATTRIBUTE value = { CKA_VALUE, (void *)der, length };
+
+ return p11_attrs_build (NULL, &klass, &certificate_type, &value, NULL);
+}
- p11_persist *store = user_data;
+typedef struct {
+ p11_lexer *lexer;
+ CK_ATTRIBUTE *attrs;
+ bool result;
+} parse_block;
+
+static void
+on_pem_block (const char *type,
+ const unsigned char *contents,
+ size_t length,
+ void *user_data)
+{
+ parse_block *pb = user_data;
CK_ATTRIBUTE *attrs;
if (strcmp (type, "CERTIFICATE") == 0) {
- value.pValue = (void *)contents;
- value.ulValueLen = length;
- attrs = p11_attrs_build (NULL, &klass, &modifiable, &certificate_type, &value, NULL);
- store->attrs = p11_attrs_merge (store->attrs, attrs, false);
- store->result = true;
+ attrs = certificate_to_attributes (contents, length);
+ pb->attrs = p11_attrs_merge (pb->attrs, attrs, false);
+ pb->result = true;
} else {
- p11_lexer_msg (&store->lexer, "unsupported pem block in store");
- store->result = false;
+ p11_lexer_msg (pb->lexer, "unsupported pem block in store");
+ pb->result = false;
}
}
static bool
-pem_to_attributes (p11_persist *store,
- p11_lexer *lexer)
+pem_to_attributes (p11_lexer *lexer,
+ CK_ATTRIBUTE **attrs)
{
+ parse_block pb = { lexer, *attrs, false };
unsigned int count;
count = p11_pem_parse (lexer->tok.pem.begin,
lexer->tok.pem.length,
- on_pem_block, store);
+ on_pem_block, &pb);
if (count == 0) {
p11_lexer_msg (lexer, "invalid pem block");
@@ -330,7 +604,8 @@ pem_to_attributes (p11_persist *store,
/* The lexer should have only matched one block */
return_val_if_fail (count == 1, false);
- return store->result;
+ *attrs = pb.attrs;
+ return pb.result;
}
bool
@@ -340,50 +615,53 @@ p11_persist_read (p11_persist *persist,
size_t length,
p11_array *objects)
{
- bool failed = false;
+ p11_lexer lexer;
+ CK_ATTRIBUTE *attrs;
+ bool failed;
+ bool skip;
return_val_if_fail (persist != NULL, false);
return_val_if_fail (objects != NULL, false);
- persist->skip = false;
- persist->result = false;
- persist->attrs = NULL;
+ skip = false;
+ attrs = NULL;
+ failed = false;
- p11_lexer_init (&persist->lexer, filename, (const char *)data, length);
- while (p11_lexer_next (&persist->lexer, &failed)) {
- switch (persist->lexer.tok_type) {
+ p11_lexer_init (&lexer, filename, (const char *)data, length);
+ while (p11_lexer_next (&lexer, &failed)) {
+ switch (lexer.tok_type) {
case TOK_SECTION:
- if (persist->attrs && !p11_array_push (objects, persist->attrs))
+ if (attrs && !p11_array_push (objects, attrs))
return_val_if_reached (false);
- persist->attrs = NULL;
- if (strcmp (persist->lexer.tok.section.name, PERSIST_HEADER) != 0) {
- p11_lexer_msg (&persist->lexer, "unrecognized or invalid section header");
- persist->skip = true;
+ attrs = NULL;
+ if (strcmp (lexer.tok.section.name, PERSIST_HEADER) != 0) {
+ p11_lexer_msg (&lexer, "unrecognized or invalid section header");
+ skip = true;
} else {
- persist->attrs = p11_attrs_build (NULL, NULL);
- return_val_if_fail (persist->attrs != NULL, false);
- persist->skip = false;
+ attrs = p11_attrs_build (NULL, NULL);
+ return_val_if_fail (attrs != NULL, false);
+ skip = false;
}
failed = false;
break;
case TOK_FIELD:
- if (persist->skip) {
+ if (skip) {
failed = false;
- } else if (!persist->attrs) {
- p11_lexer_msg (&persist->lexer, "attribute before p11-kit section header");
+ } else if (!attrs) {
+ p11_lexer_msg (&lexer, "attribute before p11-kit section header");
failed = true;
} else {
- failed = !field_to_attribute (persist, &persist->lexer);
+ failed = !field_to_attribute (persist, &lexer, &attrs);
}
break;
case TOK_PEM:
- if (persist->skip) {
+ if (skip) {
failed = false;
- } else if (!persist->attrs) {
- p11_lexer_msg (&persist->lexer, "pem block before p11-kit section header");
+ } else if (!attrs) {
+ p11_lexer_msg (&lexer, "pem block before p11-kit section header");
failed = true;
} else {
- failed = !pem_to_attributes (persist, &persist->lexer);
+ failed = !pem_to_attributes (&lexer, &attrs);
}
break;
}
@@ -392,10 +670,72 @@ p11_persist_read (p11_persist *persist,
break;
}
- if (persist->attrs && !p11_array_push (objects, persist->attrs))
+ if (attrs && !p11_array_push (objects, attrs))
return_val_if_reached (false);
- persist->attrs = NULL;
+ attrs = NULL;
- p11_lexer_done (&persist->lexer);
+ p11_lexer_done (&lexer);
return !failed;
}
+
+static CK_ATTRIBUTE *
+find_certificate_value (CK_ATTRIBUTE *attrs)
+{
+ CK_OBJECT_CLASS klass;
+ CK_CERTIFICATE_TYPE type;
+
+ if (!p11_attrs_find_ulong (attrs, CKA_CLASS, &klass) ||
+ klass != CKO_CERTIFICATE)
+ return NULL;
+ if (!p11_attrs_find_ulong (attrs, CKA_CERTIFICATE_TYPE, &type) ||
+ type != CKC_X_509)
+ return NULL;
+ return p11_attrs_find_valid (attrs, CKA_VALUE);
+}
+
+bool
+p11_persist_write (p11_persist *persist,
+ CK_ATTRIBUTE *attrs,
+ p11_buffer *buf)
+{
+ char string[sizeof (CK_ULONG) * 4];
+ CK_ATTRIBUTE *cert_value;
+ const char *nick;
+ int i;
+
+ cert_value = find_certificate_value (attrs);
+
+ p11_buffer_add (buf, "[" PERSIST_HEADER "]\n", -1);
+
+ for (i = 0; !p11_attrs_terminator (attrs + i); i++) {
+
+ /* These are written later? */
+ if (cert_value != NULL &&
+ (attrs[i].type == CKA_CLASS ||
+ attrs[i].type == CKA_CERTIFICATE_TYPE ||
+ attrs[i].type == CKA_VALUE))
+ continue;
+
+ if (attrs[i].ulValueLen == CK_UNAVAILABLE_INFORMATION)
+ continue;
+
+ nick = p11_constant_nick (p11_constant_types, attrs[i].type);
+ if (nick == NULL) {
+ snprintf (string, sizeof (string), "%lu", attrs[i].type);
+ nick = string;
+ }
+
+ p11_buffer_add (buf, nick, -1);
+ p11_buffer_add (buf, ": ", 2);
+ format_value (persist, attrs + i, buf);
+ p11_buffer_add (buf, "\n", 1);
+ }
+
+ if (cert_value != NULL) {
+ if (!p11_pem_write (cert_value->pValue, cert_value->ulValueLen, "CERTIFICATE", buf))
+ return_val_if_reached (false);
+ }
+
+ p11_buffer_add (buf, "\n", 1);
+ return p11_buffer_ok (buf);
+}
diff --git a/trust/persist.h b/trust/persist.h
index 04762f4..0ef142c 100644
--- a/trust/persist.h
+++ b/trust/persist.h
@@ -54,6 +54,10 @@ bool p11_persist_read (p11_persist *persist,
size_t length,
p11_array *objects);
+bool p11_persist_write (p11_persist *persist,
+ CK_ATTRIBUTE *object,
+ p11_buffer *buf);
+
void p11_persist_free (p11_persist *persist);
#endif /* P11_PERSIST_H_ */
diff --git a/trust/tests/test-persist.c b/trust/tests/test-persist.c
index defeecf..107f131 100644
--- a/trust/tests/test-persist.c
+++ b/trust/tests/test-persist.c
@@ -127,12 +127,44 @@ check_read_msg (const char *file,
p11_array_free (expected);
}
+static void
+check_write_msg (const char *file,
+ int line,
+ const char *function,
+ const char *expected,
+ p11_array *input)
+{
+ p11_persist *persist;
+ p11_buffer buf;
+ int i;
+
+ persist = p11_persist_new ();
+ p11_buffer_init_null (&buf, 0);
+
+ for (i = 0; i < input->num; i++) {
+ if (!p11_persist_write (persist, input->elem[i], &buf))
+ p11_test_fail (file, line, function, "persist write failed");
+ }
+
+ if (strcmp (buf.data, expected) != 0) {
+ p11_test_fail (file, line, function, "persist doesn't match: (\n%s----\n%s\n)", \
+ expected, (char *)buf.data);
+ }
+
+ p11_buffer_uninit (&buf);
+ p11_array_free (input);
+ p11_persist_free (persist);
+}
+
#define check_read_success(input, objs) \
check_read_msg (__FILE__, __LINE__, __FUNCTION__, input, args_to_array objs)
#define check_read_failure(input) \
check_read_msg (__FILE__, __LINE__, __FUNCTION__, input, NULL)
+#define check_write_success(expected, inputs) \
+ check_write_msg (__FILE__, __LINE__, __FUNCTION__, expected, args_to_array inputs)
+
static CK_OBJECT_CLASS certificate = CKO_CERTIFICATE;
static CK_CERTIFICATE_TYPE x509 = CKC_X_509;
static CK_OBJECT_CLASS nss_trust = CKO_NSS_TRUST;
@@ -143,51 +175,53 @@ static CK_BBOOL falsev = CK_FALSE;
static void
test_simple (void)
{
- const char *input = "[p11-kit-object-v1]\n"
+ const char *output = "[p11-kit-object-v1]\n"
"class: data\n"
"value: \"blah\"\n"
- "application: \"test-persist\"\n";
+ "application: \"test-persist\"\n\n";
- CK_ATTRIBUTE expected[] = {
+ CK_ATTRIBUTE attrs[] = {
{ CKA_CLASS, &data, sizeof (data) },
{ CKA_VALUE, "blah", 4 },
{ CKA_APPLICATION, "test-persist", 12 },
{ CKA_INVALID },
};
- check_read_success (input, (expected, NULL));
+ check_read_success (output, (attrs, NULL));
+ check_write_success (output, (attrs, NULL));
}
static void
test_number (void)
{
- const char *input = "[p11-kit-object-v1]\n"
+ const char *output = "[p11-kit-object-v1]\n"
"class: data\n"
- "value: 29202390\n"
- "application: \"test-persist\"\n";
+ "value-len: 29202390\n"
+ "application: \"test-persist\"\n\n";
CK_ULONG value = 29202390;
- CK_ATTRIBUTE expected[] = {
+ CK_ATTRIBUTE attrs[] = {
{ CKA_CLASS, &data, sizeof (data) },
- { CKA_VALUE, &value, sizeof (value) },
+ { CKA_VALUE_LEN, &value, sizeof (value) },
{ CKA_APPLICATION, "test-persist", 12 },
{ CKA_INVALID },
};
- check_read_success (input, (expected, NULL));
+ check_read_success (output, (attrs, NULL));
+ check_write_success (output, (attrs, NULL));
}
static void
test_bool (void)
{
- const char *input = "[p11-kit-object-v1]\n"
+ const char *output = "[p11-kit-object-v1]\n"
"class: data\n"
"private: true\n"
"modifiable: false\n"
- "application: \"test-persist\"\n";
+ "application: \"test-persist\"\n\n";
- CK_ATTRIBUTE expected[] = {
+ CK_ATTRIBUTE attrs[] = {
{ CKA_CLASS, &data, sizeof (data) },
{ CKA_PRIVATE, &truev, sizeof (truev) },
{ CKA_MODIFIABLE, &falsev, sizeof (falsev) },
@@ -195,73 +229,144 @@ test_bool (void)
{ CKA_INVALID },
};
- check_read_success (input, (expected, NULL));
+ check_read_success (output, (attrs, NULL));
+ check_write_success (output, (attrs, NULL));
}
static void
test_oid (void)
{
- const char *input = "[p11-kit-object-v1]\n"
+ const char *output = "[p11-kit-object-v1]\n"
"class: data\n"
- "object-id: 1.2.3.4";
+ "object-id: 1.2.3.4\n\n";
- CK_ATTRIBUTE expected[] = {
+ CK_ATTRIBUTE attrs[] = {
{ CKA_CLASS, &data, sizeof (data) },
{ CKA_OBJECT_ID, "\x06\x03*\x03\x04", 5 },
{ CKA_INVALID },
};
- check_read_success (input, (expected, NULL));
+ check_read_success (output, (attrs, NULL));
+ check_write_success (output, (attrs, NULL));
}
static void
test_constant (void)
{
- const char *input = "[p11-kit-object-v1]\n"
+ const char *output = "[p11-kit-object-v1]\n"
"class: data\n"
- "trust-server-auth: nss-trust-unknown";
+ "certificate-type: x-509-attr-cert\n"
+ "key-type: rsa\n"
+ "x-assertion-type: x-pinned-certificate\n"
+ "certificate-category: authority\n"
+ "mechanism-type: rsa-pkcs-key-pair-gen\n"
+ "trust-server-auth: nss-trust-unknown\n\n";
CK_TRUST trust = CKT_NSS_TRUST_UNKNOWN;
+ CK_CERTIFICATE_TYPE type = CKC_X_509_ATTR_CERT;
+ CK_X_ASSERTION_TYPE ass = CKT_X_PINNED_CERTIFICATE;
+ CK_MECHANISM_TYPE mech = CKM_RSA_PKCS_KEY_PAIR_GEN;
+ CK_ULONG category = 2;
+ CK_KEY_TYPE key = CKK_RSA;
- CK_ATTRIBUTE expected[] = {
+ CK_ATTRIBUTE attrs[] = {
{ CKA_CLASS, &data, sizeof (data) },
+ { CKA_CERTIFICATE_TYPE, &type, sizeof (type) },
+ { CKA_KEY_TYPE, &key, sizeof (key) },
+ { CKA_X_ASSERTION_TYPE, &ass, sizeof (ass) },
+ { CKA_CERTIFICATE_CATEGORY, &category, sizeof (category) },
+ { CKA_MECHANISM_TYPE, &mech, sizeof (mech) },
{ CKA_TRUST_SERVER_AUTH, &trust, sizeof (trust) },
{ CKA_INVALID },
};
- check_read_success (input, (expected, NULL));
+ check_read_success (output, (attrs, NULL));
+ check_write_success (output, (attrs, NULL));
+}
+
+static void
+test_unknown (void)
+{
+ const char *output = "[p11-kit-object-v1]\n"
+ "class: data\n"
+ "38383838: \"the-value-here\"\n\n";
+
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_CLASS, &data, sizeof (data) },
+ { 38383838, "the-value-here", 14 },
+ { CKA_INVALID },
+ };
+
+ check_read_success (output, (attrs, NULL));
+ check_write_success (output, (attrs, NULL));
}
static void
test_multiple (void)
{
- const char *input = "[p11-kit-object-v1]\n"
+ const char *output = "[p11-kit-object-v1]\n"
"class: data\n"
- "object-id: 1.2.3.4\n"
+ "object-id: 1.2.3.4\n\n"
"[p11-kit-object-v1]\n"
"class: nss-trust\n"
- "trust-server-auth: nss-trust-unknown";
+ "trust-server-auth: nss-trust-unknown\n\n";
CK_TRUST trust = CKT_NSS_TRUST_UNKNOWN;
- CK_ATTRIBUTE expected1[] = {
+ CK_ATTRIBUTE attrs1[] = {
{ CKA_CLASS, &data, sizeof (data) },
{ CKA_OBJECT_ID, "\x06\x03*\x03\x04", 5 },
{ CKA_INVALID },
};
- CK_ATTRIBUTE expected2[] = {
+ CK_ATTRIBUTE attrs2[] = {
{ CKA_CLASS, &nss_trust, sizeof (nss_trust) },
{ CKA_TRUST_SERVER_AUTH, &trust, sizeof (trust) },
{ CKA_INVALID },
};
- check_read_success (input, (expected1, expected2, NULL));
+ check_read_success (output, (attrs1, attrs2, NULL));
+ check_write_success (output, (attrs1, attrs2, NULL));
}
static void
test_pem_block (void)
{
+ const char *output = "[p11-kit-object-v1]\n"
+ "id: \"292c92\"\n"
+ "trusted: true\n"
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkG\n"
+ "A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz\n"
+ "cyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2\n"
+ "MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV\n"
+ "BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmlt\n"
+ "YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN\n"
+ "ADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0f\n"
+ "zGVuDLDQVoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHi\n"
+ "TkVWaR94AoDa3EeRKbs2yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0G\n"
+ "CSqGSIb3DQEBBQUAA4GBAFgVKTk8d6PaXCUDfGD67gmZPCcQcMgMCeazh88K4hiW\n"
+ "NWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n0a3hUKw8fGJLj7qE1xIV\n"
+ "Gx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZRjXZ+Hxb\n"
+ "-----END CERTIFICATE-----\n"
+ "\n";
+
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_CLASS, &certificate, sizeof (certificate) },
+ { CKA_ID, "292c92", 6, },
+ { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) },
+ { CKA_VALUE, &verisign_v1_ca, sizeof (verisign_v1_ca) },
+ { CKA_TRUSTED, &truev, sizeof (truev) },
+ { CKA_INVALID },
+ };
+
+ check_read_success (output, (attrs, NULL));
+ check_write_success (output, (attrs, NULL));
+}
+
+static void
+test_pem_middle (void)
+{
const char *input = "[p11-kit-object-v1]\n"
"class: certificate\n"
"id: \"292c92\"\n"
@@ -436,6 +541,44 @@ test_attribute_first (void)
p11_message_loud ();
}
+static void
+test_not_boolean (void)
+{
+ const char *output = "[p11-kit-object-v1]\n"
+ "private: \"x\"\n\n";
+
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_PRIVATE, "x", 1 },
+ { CKA_INVALID },
+ };
+
+ check_write_success (output, (attrs, NULL));
+}
+
+static void
+test_not_ulong (void)
+{
+ char buffer[sizeof (CK_ULONG) + 1];
+ char *output;
+
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_BITS_PER_PIXEL, "xx", 2 },
+ { CKA_VALUE, buffer, sizeof (CK_ULONG) },
+ { CKA_INVALID },
+ };
+
+ memset (buffer, 'x', sizeof (buffer));
+ buffer[sizeof (CK_ULONG)] = 0;
+
+ if (asprintf (&output, "[p11-kit-object-v1]\n"
+ "bits-per-pixel: \"xx\"\n"
+ "value: \"%s\"\n\n", buffer) < 0)
+ assert_not_reached ();
+
+ check_write_success (output, (attrs, NULL));
+ free (output);
+}
+
int
main (int argc,
char *argv[])
@@ -446,8 +589,10 @@ main (int argc,
p11_test (test_bool, "/persist/bool");
p11_test (test_oid, "/persist/oid");
p11_test (test_constant, "/persist/constant");
+ p11_test (test_unknown, "/persist/unknown");
p11_test (test_multiple, "/persist/multiple");
p11_test (test_pem_block, "/persist/pem_block");
+ p11_test (test_pem_middle, "/persist/pem-middle");
p11_test (test_pem_invalid, "/persist/pem_invalid");
p11_test (test_pem_unsupported, "/persist/pem_unsupported");
p11_test (test_pem_first, "/persist/pem_first");
@@ -456,5 +601,7 @@ main (int argc,
p11_test (test_bad_field, "/persist/bad_field");
p11_test (test_skip_unknown, "/persist/skip_unknown");
p11_test (test_attribute_first, "/persist/attribute_first");
+ p11_test (test_not_boolean, "/persist/not-boolean");
+ p11_test (test_not_ulong, "/persist/not-ulong");
return p11_test_run (argc, argv);
}
diff --git a/trust/tests/test-trust.c b/trust/tests/test-trust.c
index 6b990dc..6a22946 100644
--- a/trust/tests/test-trust.c
+++ b/trust/tests/test-trust.c
@@ -147,6 +147,6 @@ test_check_attr_msg (const char *file,
p11_test_fail (file, line, function,
"attribute does not match: (expected %s but found %s)",
p11_attr_to_string (expected, klass),
- p11_attr_to_string (attr, klass));
+ attr ? p11_attr_to_string (attr, klass) : "(null)");
}
}