summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2013-03-15 11:50:24 +0100
committerStef Walter <stefw@gnome.org>2013-03-15 18:18:47 +0100
commit7fd74a78fcad81227be3650239669bca5851a1db (patch)
tree64f60c20357a7fd34f9aee30ac12dcfa2ebb1109
parent48004b92d4c65080ac71f6a48297abd4d83dfdcb (diff)
downloadp11-kit-7fd74a78fcad81227be3650239669bca5851a1db.tar.gz
trust: Support a p11-kit specific serialization format
This is documented in doc/internals/ subdirectory Add tests for the format as well. https://bugs.freedesktop.org/show_bug.cgi?id=62156
-rw-r--r--common/Makefile.am2
-rw-r--r--common/basic.asn12
-rw-r--r--common/basic.asn.h13
-rw-r--r--doc/internal/persist-format.txt54
-rw-r--r--trust/Makefile.am1
-rw-r--r--trust/parser.c35
-rw-r--r--trust/persist.c401
-rw-r--r--trust/persist.h59
-rw-r--r--trust/tests/Makefile.am1
-rw-r--r--trust/tests/input/verisign-v1.p11-kit17
-rw-r--r--trust/tests/test-builder.c39
-rw-r--r--trust/tests/test-data.h39
-rw-r--r--trust/tests/test-module.c2
-rw-r--r--trust/tests/test-parser.c32
-rw-r--r--trust/tests/test-persist.c472
-rw-r--r--trust/tests/test-token.c2
16 files changed, 1140 insertions, 41 deletions
diff --git a/common/Makefile.am b/common/Makefile.am
index a132984..3a54089 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -43,6 +43,7 @@ noinst_LTLIBRARIES += \
libp11_data_la_SOURCES = \
asn1.c asn1.h \
+ basic.asn basic.asn.h \
base64.c base64.h \
checksum.c checksum.h \
oid.c oid.h \
@@ -59,5 +60,6 @@ libp11_data_la_CFLAGS = \
asn:
asn1Parser -o pkix.asn.h pkix.asn
asn1Parser -o openssl.asn.h openssl.asn
+ asn1Parser -o basic.asn.h basic.asn
endif # WITH_ASN1
diff --git a/common/basic.asn b/common/basic.asn
new file mode 100644
index 0000000..3c79a4b
--- /dev/null
+++ b/common/basic.asn
@@ -0,0 +1,12 @@
+
+BASIC { }
+
+DEFINITIONS EXPLICIT TAGS ::=
+
+BEGIN
+
+Any ::= ANY
+
+ObjectIdentifier ::= OBJECT IDENTIFIER
+
+END \ No newline at end of file
diff --git a/common/basic.asn.h b/common/basic.asn.h
new file mode 100644
index 0000000..b63447b
--- /dev/null
+++ b/common/basic.asn.h
@@ -0,0 +1,13 @@
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <libtasn1.h>
+
+const ASN1_ARRAY_TYPE basic_asn1_tab[] = {
+ { "BASIC", 536872976, NULL },
+ { NULL, 1073741836, NULL },
+ { "Any", 1073741837, NULL },
+ { "ObjectIdentifier", 12, NULL },
+ { NULL, 0, NULL }
+};
diff --git a/doc/internal/persist-format.txt b/doc/internal/persist-format.txt
new file mode 100644
index 0000000..a0a3194
--- /dev/null
+++ b/doc/internal/persist-format.txt
@@ -0,0 +1,54 @@
+These are some notes about the p11-kit persistence format
+
+The format is designed to be somewhat human readable and debuggable, and a bit
+transparent but it is also not encouraged to read/write this format from other
+applications or tools without first discussing this at the the mailing list:
+
+p11-glue@lists.freedesktop.org
+
+The format of the file reflects the PKCS#11 attributes exposed by p11-kit. The
+attributes have a one to one mapping with PKCS#11 attributes of similar names.
+No assumptions should be made that an attribute does what you think it does
+from the label.
+
+Each object in the file starts with the header '[p11-kit-object-v1]'. After that
+point there are names and valeus separated by colons. Whitespace surrounding
+the names and values is ignored.
+
+Boolean values are 'true' and 'false'. Unsigned long attributes are plain
+numbers. String/binary attributes are surrounded with quotes and percent
+encoded. Object id attributes are in their dotted form. Various PKCS#11
+constants are available.
+
+PEM blocks can be present within an object, and these contribute certain
+PKCS#11 attributes to the object. The attributes that come from PEM blocks
+never override those explicitly specified. A 'CERTIFICATE' type PEM block
+contributes the 'value', 'class', 'certificate-type', 'subject', 'issuer'
+'start-date', 'end-date', 'id', 'certificate-category', 'check-value',
+'serial-number' attributes with appropriate values.
+
+Comments starting with a '#' and blank lines are ignored.
+
+Only rudimentary checks are done to make sure that the resulting attributes
+make sense. This may change in the future, and invalid files will be
+unceremoniously rejected. So again use the mailing list if there's a need
+to be writing these files at this point:
+
+p11-glue@lists.freedesktop.org
+
+Example file:
+
+[p11-kit-object-v1]
+class = certificate
+modifiable = true
+java-midp-security-domain = 0
+label = "My special label"
+id = "%01%02%03go"
+
+-----BEGIN CERTIFICATE-----
+MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
+................................................................
+B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy
+vUxFnmG6v4SBkgPR0ml8xQ==
+-----END CERTIFICATE-----
+x-distrusted = true
diff --git a/trust/Makefile.am b/trust/Makefile.am
index 0f84205..aff512e 100644
--- a/trust/Makefile.am
+++ b/trust/Makefile.am
@@ -14,6 +14,7 @@ MODULE_SRCS = \
builder.c builder.h \
index.c index.h \
parser.c parser.h \
+ persist.c persist.h \
module.c module.h \
session.c session.h \
token.c token.h \
diff --git a/trust/parser.c b/trust/parser.c
index 0ab9468..56d3226 100644
--- a/trust/parser.c
+++ b/trust/parser.c
@@ -47,6 +47,7 @@
#include "parser.h"
#include "pem.h"
#include "pkcs11x.h"
+#include "persist.h"
#include "x509.h"
#include <libtasn1.h>
@@ -65,6 +66,7 @@ struct _p11_parser {
p11_index *index;
p11_asn1_cache *asn1_cache;
p11_dict *asn1_defs;
+ p11_persist *persist;
char *basename;
int flags;
};
@@ -573,7 +575,38 @@ parse_pem_certificates (p11_parser *parser,
return P11_PARSE_SUCCESS;
}
+static int
+parse_p11_kit_persist (p11_parser *parser,
+ const unsigned char *data,
+ size_t length)
+{
+ p11_array *objects;
+ bool ret;
+ int i;
+
+ if (!p11_persist_magic (data, length))
+ return P11_PARSE_UNRECOGNIZED;
+
+ if (!parser->persist) {
+ parser->persist = p11_persist_new ();
+ return_val_if_fail (parser->persist != NULL, P11_PARSE_UNRECOGNIZED);
+ }
+
+ objects = p11_array_new (NULL);
+ return_val_if_fail (objects != NULL, P11_PARSE_FAILURE);
+
+ 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]);
+ }
+
+ p11_array_free (objects);
+ return ret ? P11_PARSE_SUCCESS : P11_PARSE_FAILURE;
+}
+
static parser_func all_parsers[] = {
+ parse_p11_kit_persist,
parse_pem_certificates,
parse_der_x509_certificate,
NULL,
@@ -598,6 +631,8 @@ p11_parser_new (p11_index *index,
void
p11_parser_free (p11_parser *parser)
{
+ return_if_fail (parser != NULL);
+ p11_persist_free (parser->persist);
free (parser);
}
diff --git a/trust/persist.c b/trust/persist.c
new file mode 100644
index 0000000..69af697
--- /dev/null
+++ b/trust/persist.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2013 Red Hat Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@redhat.com>
+ */
+
+#include "config.h"
+
+#include "asn1.h"
+#include "attrs.h"
+#include "constants.h"
+#include "debug.h"
+#include "lexer.h"
+#include "pem.h"
+#include "persist.h"
+#include "url.h"
+
+#include "basic.asn.h"
+
+#include <libtasn1.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#define PERSIST_HEADER "p11-kit-object-v1"
+
+struct _p11_persist {
+ p11_dict *constants;
+ node_asn *asn1_defs;
+
+ /* Used during parsing */
+ p11_lexer lexer;
+ CK_ATTRIBUTE *attrs;
+ bool result;
+ bool skip;
+};
+
+bool
+p11_persist_magic (const unsigned char *data,
+ size_t length)
+{
+ return (strnstr ((char *)data, "[" PERSIST_HEADER "]", length) != NULL);
+}
+
+p11_persist *
+p11_persist_new (void)
+{
+ p11_persist *persist;
+
+ persist = calloc (1, sizeof (p11_persist));
+ return_val_if_fail (persist != NULL, NULL);
+
+ persist->constants = p11_constant_reverse (true);
+ return_val_if_fail (persist->constants != NULL, NULL);
+
+ return persist;
+}
+
+void
+p11_persist_free (p11_persist *persist)
+{
+ if (!persist)
+ return;
+ p11_dict_free (persist->constants);
+ asn1_delete_structure (&persist->asn1_defs);
+ free (persist);
+}
+
+struct constant {
+ CK_ULONG value;
+ const char *string;
+};
+
+static bool
+parse_string (p11_lexer *lexer,
+ CK_ATTRIBUTE *attr)
+{
+ const char *value;
+ const char *end;
+ size_t length;
+ unsigned char *data;
+
+ value = lexer->tok.field.value;
+ end = value + strlen (value);
+
+ /* Not a string/binary value */
+ if (value == end || value[0] != '\"' || *(end - 1) != '\"')
+ return false;
+
+ /* Note that we don't skip whitespace when decoding, as you might in other URLs */
+ data = p11_url_decode (value + 1, end - 1, "", &length);
+ if (data == NULL) {
+ p11_lexer_msg(lexer, "bad encoding of attribute value");
+ return false;
+ }
+
+ attr->pValue = data;
+ attr->ulValueLen = length;
+ return true;
+}
+
+static bool
+parse_bool (p11_lexer *lexer,
+ CK_ATTRIBUTE *attr)
+{
+ const char *value = lexer->tok.field.value;
+ CK_BBOOL boolean;
+
+ if (strcmp (value, "true") == 0) {
+ boolean = CK_TRUE;
+
+ } else if (strcmp (value, "false") == 0) {
+ boolean = CK_FALSE;
+
+ } else {
+ /* Not a valid boolean value */
+ return false;
+ }
+
+ attr->pValue = memdup (&boolean, sizeof (boolean));
+ return_val_if_fail (attr != NULL, FALSE);
+ attr->ulValueLen = sizeof (boolean);
+ return true;
+}
+
+static bool
+parse_ulong (p11_lexer *lexer,
+ CK_ATTRIBUTE *attr)
+{
+ unsigned long value;
+ char *end;
+
+ end = NULL;
+ value = strtoul (lexer->tok.field.value, &end, 10);
+
+ /* Not a valid number value */
+ if (!end || *end != '\0')
+ return false;
+
+ attr->pValue = memdup (&value, sizeof (CK_ULONG));
+ return_val_if_fail (attr->pValue != NULL, false);
+ attr->ulValueLen = sizeof (CK_ULONG);
+ return true;
+}
+
+static bool
+parse_constant (p11_persist *persist,
+ p11_lexer *lexer,
+ CK_ATTRIBUTE *attr)
+{
+ CK_ULONG value;
+
+ value = p11_constant_resolve (persist->constants, lexer->tok.field.value);
+
+ /* Not a valid constant */
+ if (value == CKA_INVALID)
+ return false;
+
+ attr->pValue = memdup (&value, sizeof (CK_ULONG));
+ return_val_if_fail (attr->pValue != NULL, false);
+ attr->ulValueLen = sizeof (CK_ULONG);
+ return true;
+}
+
+
+static bool
+parse_oid (p11_persist *persist,
+ p11_lexer *lexer,
+ CK_ATTRIBUTE *attr)
+{
+ char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = { 0, };
+ node_asn *asn;
+ size_t length;
+ char *value;
+ int ret;
+
+ value = lexer->tok.field.value;
+ length = strlen (value);
+
+ /* Not an OID value? */
+ if (length < 4 ||
+ strchr (value, '.') == NULL ||
+ strspn (value, "0123456790.") != length ||
+ strstr (value, "..") != NULL ||
+ value[0] == '.' || value[0] == '0' ||
+ value[length - 1] == '.' ||
+ strchr (value, '.') == strrchr (value, '.')) {
+ 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_write_value (asn, "", value, 1);
+ if (ret == ASN1_VALUE_NOT_VALID) {
+ p11_lexer_msg (lexer, "invalid oid value");
+ asn1_delete_structure (&asn);
+ return false;
+ }
+ return_val_if_fail (ret == ASN1_SUCCESS, false);
+
+ attr->pValue = p11_asn1_encode (asn, &length);
+ return_val_if_fail (attr->pValue != NULL, false);
+ attr->ulValueLen = length;
+
+ asn1_delete_structure (&asn);
+ return true;
+}
+
+static bool
+parse_value (p11_persist *persist,
+ p11_lexer *lexer,
+ CK_ATTRIBUTE *attr)
+{
+ return parse_constant (persist, lexer, attr) ||
+ parse_string (lexer, attr) ||
+ parse_bool (lexer, attr) ||
+ parse_ulong (lexer, attr) ||
+ parse_oid (persist, lexer, attr);
+}
+
+static bool
+field_to_attribute (p11_persist *persist,
+ p11_lexer *lexer)
+{
+ CK_ATTRIBUTE attr = { 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)) {
+ p11_lexer_msg (lexer, "invalid value");
+ return false;
+ }
+
+ persist->attrs = p11_attrs_take (persist->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)
+{
+ 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, };
+
+ p11_persist *store = 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;
+
+ } else {
+ p11_lexer_msg (&store->lexer, "unsupported pem block in store");
+ store->result = false;
+ }
+}
+
+static bool
+pem_to_attributes (p11_persist *store,
+ p11_lexer *lexer)
+{
+ unsigned int count;
+
+ count = p11_pem_parse (lexer->tok.pem.begin,
+ lexer->tok.pem.length,
+ on_pem_block, store);
+
+ if (count == 0) {
+ p11_lexer_msg (lexer, "invalid pem block");
+ return false;
+ }
+
+ /* The lexer should have only matched one block */
+ return_val_if_fail (count == 1, false);
+ return store->result;
+}
+
+bool
+p11_persist_read (p11_persist *persist,
+ const char *filename,
+ const unsigned char *data,
+ size_t length,
+ p11_array *objects)
+{
+ bool failed = false;
+
+ return_val_if_fail (persist != NULL, false);
+ return_val_if_fail (objects != NULL, false);
+
+ persist->skip = false;
+ persist->result = false;
+ persist->attrs = NULL;
+
+ p11_lexer_init (&persist->lexer, filename, (const char *)data, length);
+ while (p11_lexer_next (&persist->lexer, &failed)) {
+ switch (persist->lexer.tok_type) {
+ case TOK_SECTION:
+ if (persist->attrs && !p11_array_push (objects, persist->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;
+ } else {
+ persist->attrs = p11_attrs_build (NULL, NULL);
+ return_val_if_fail (persist->attrs != NULL, false);
+ persist->skip = false;
+ }
+ failed = false;
+ break;
+ case TOK_FIELD:
+ if (persist->skip) {
+ failed = false;
+ } else if (!persist->attrs) {
+ p11_lexer_msg (&persist->lexer, "attribute before p11-kit section header");
+ failed = true;
+ } else {
+ failed = !field_to_attribute (persist, &persist->lexer);
+ }
+ break;
+ case TOK_PEM:
+ if (persist->skip) {
+ failed = false;
+ } else if (!persist->attrs) {
+ p11_lexer_msg (&persist->lexer, "pem block before p11-kit section header");
+ failed = true;
+ } else {
+ failed = !pem_to_attributes (persist, &persist->lexer);
+ }
+ break;
+ }
+
+ if (failed)
+ break;
+ }
+
+ if (persist->attrs && !p11_array_push (objects, persist->attrs))
+ return_val_if_reached (false);
+ persist->attrs = NULL;
+
+ p11_lexer_done (&persist->lexer);
+ return !failed;
+}
diff --git a/trust/persist.h b/trust/persist.h
new file mode 100644
index 0000000..04762f4
--- /dev/null
+++ b/trust/persist.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 Red Hat Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@redhat.com>
+ */
+
+#ifndef P11_PERSIST_H_
+#define P11_PERSIST_H_
+
+#include "array.h"
+#include "compat.h"
+#include "dict.h"
+
+#include <sys/types.h>
+
+typedef struct _p11_persist p11_persist;
+
+p11_persist * p11_persist_new (void);
+
+bool p11_persist_magic (const unsigned char *data,
+ size_t length);
+
+bool p11_persist_read (p11_persist *persist,
+ const char *filename,
+ const unsigned char *data,
+ size_t length,
+ p11_array *objects);
+
+void p11_persist_free (p11_persist *persist);
+
+#endif /* P11_PERSIST_H_ */
diff --git a/trust/tests/Makefile.am b/trust/tests/Makefile.am
index a675a56..fa70120 100644
--- a/trust/tests/Makefile.am
+++ b/trust/tests/Makefile.am
@@ -26,6 +26,7 @@ LDADD = \
$(NULL)
CHECK_PROGS = \
+ test-persist \
test-parser \
test-index \
test-builder \
diff --git a/trust/tests/input/verisign-v1.p11-kit b/trust/tests/input/verisign-v1.p11-kit
new file mode 100644
index 0000000..eaa080d
--- /dev/null
+++ b/trust/tests/input/verisign-v1.p11-kit
@@ -0,0 +1,17 @@
+[p11-kit-object-v1]
+trusted: true
+
+-----BEGIN CERTIFICATE-----
+MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkG
+A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
+cyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
+MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
+BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmlt
+YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
+ADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0f
+zGVuDLDQVoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHi
+TkVWaR94AoDa3EeRKbs2yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0G
+CSqGSIb3DQEBBQUAA4GBAFgVKTk8d6PaXCUDfGD67gmZPCcQcMgMCeazh88K4hiW
+NWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n0a3hUKw8fGJLj7qE1xIV
+Gx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZRjXZ+Hxb
+-----END CERTIFICATE-----
diff --git a/trust/tests/test-builder.c b/trust/tests/test-builder.c
index f879706..3d3d067 100644
--- a/trust/tests/test-builder.c
+++ b/trust/tests/test-builder.c
@@ -341,45 +341,6 @@ test_build_certificate_non_ca (CuTest *cu)
teardown (cu);
}
-static const unsigned char verisign_v1_ca[] = {
- 0x30, 0x82, 0x02, 0x3c, 0x30, 0x82, 0x01, 0xa5, 0x02, 0x10, 0x3f, 0x69, 0x1e, 0x81, 0x9c, 0xf0,
- 0x9a, 0x4a, 0xf3, 0x73, 0xff, 0xb9, 0x48, 0xa2, 0xe4, 0xdd, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
- 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63,
- 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2e, 0x43, 0x6c, 0x61, 0x73,
- 0x73, 0x20, 0x31, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61,
- 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x39, 0x36,
- 0x30, 0x31, 0x32, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30,
- 0x38, 0x30, 0x32, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09,
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55,
- 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
- 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2e, 0x43, 0x6c, 0x61,
- 0x73, 0x73, 0x20, 0x31, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
- 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x81, 0x9f, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
- 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xe5, 0x19, 0xbf, 0x6d, 0xa3, 0x56, 0x61, 0x2d,
- 0x99, 0x48, 0x71, 0xf6, 0x67, 0xde, 0xb9, 0x8d, 0xeb, 0xb7, 0x9e, 0x86, 0x80, 0x0a, 0x91, 0x0e,
- 0xfa, 0x38, 0x25, 0xaf, 0x46, 0x88, 0x82, 0xe5, 0x73, 0xa8, 0xa0, 0x9b, 0x24, 0x5d, 0x0d, 0x1f,
- 0xcc, 0x65, 0x6e, 0x0c, 0xb0, 0xd0, 0x56, 0x84, 0x18, 0x87, 0x9a, 0x06, 0x9b, 0x10, 0xa1, 0x73,
- 0xdf, 0xb4, 0x58, 0x39, 0x6b, 0x6e, 0xc1, 0xf6, 0x15, 0xd5, 0xa8, 0xa8, 0x3f, 0xaa, 0x12, 0x06,
- 0x8d, 0x31, 0xac, 0x7f, 0xb0, 0x34, 0xd7, 0x8f, 0x34, 0x67, 0x88, 0x09, 0xcd, 0x14, 0x11, 0xe2,
- 0x4e, 0x45, 0x56, 0x69, 0x1f, 0x78, 0x02, 0x80, 0xda, 0xdc, 0x47, 0x91, 0x29, 0xbb, 0x36, 0xc9,
- 0x63, 0x5c, 0xc5, 0xe0, 0xd7, 0x2d, 0x87, 0x7b, 0xa1, 0xb7, 0x32, 0xb0, 0x7b, 0x30, 0xba, 0x2a,
- 0x2f, 0x31, 0xaa, 0xee, 0xa3, 0x67, 0xda, 0xdb, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06,
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00,
- 0x58, 0x15, 0x29, 0x39, 0x3c, 0x77, 0xa3, 0xda, 0x5c, 0x25, 0x03, 0x7c, 0x60, 0xfa, 0xee, 0x09,
- 0x99, 0x3c, 0x27, 0x10, 0x70, 0xc8, 0x0c, 0x09, 0xe6, 0xb3, 0x87, 0xcf, 0x0a, 0xe2, 0x18, 0x96,
- 0x35, 0x62, 0xcc, 0xbf, 0x9b, 0x27, 0x79, 0x89, 0x5f, 0xc9, 0xc4, 0x09, 0xf4, 0xce, 0xb5, 0x1d,
- 0xdf, 0x2a, 0xbd, 0xe5, 0xdb, 0x86, 0x9c, 0x68, 0x25, 0xe5, 0x30, 0x7c, 0xb6, 0x89, 0x15, 0xfe,
- 0x67, 0xd1, 0xad, 0xe1, 0x50, 0xac, 0x3c, 0x7c, 0x62, 0x4b, 0x8f, 0xba, 0x84, 0xd7, 0x12, 0x15,
- 0x1b, 0x1f, 0xca, 0x5d, 0x0f, 0xc1, 0x52, 0x94, 0x2a, 0x11, 0x99, 0xda, 0x7b, 0xcf, 0x0c, 0x36,
- 0x13, 0xd5, 0x35, 0xdc, 0x10, 0x19, 0x59, 0xea, 0x94, 0xc1, 0x00, 0xbf, 0x75, 0x8f, 0xd9, 0xfa,
- 0xfd, 0x76, 0x04, 0xdb, 0x62, 0xbb, 0x90, 0x6a, 0x03, 0xd9, 0x46, 0x35, 0xd9, 0xf8, 0x7c, 0x5b,
-};
-
static void
test_build_certificate_v1_ca (CuTest *cu)
{
diff --git a/trust/tests/test-data.h b/trust/tests/test-data.h
index b07830d..9daff87 100644
--- a/trust/tests/test-data.h
+++ b/trust/tests/test-data.h
@@ -230,4 +230,43 @@ static const char test_cacert3_ca_serial[] = {
0x02, 0x03, 0x0a, 0x41, 0x8a,
};
+static const unsigned char verisign_v1_ca[] = {
+ 0x30, 0x82, 0x02, 0x3c, 0x30, 0x82, 0x01, 0xa5, 0x02, 0x10, 0x3f, 0x69, 0x1e, 0x81, 0x9c, 0xf0,
+ 0x9a, 0x4a, 0xf3, 0x73, 0xff, 0xb9, 0x48, 0xa2, 0xe4, 0xdd, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09, 0x06,
+ 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
+ 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+ 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2e, 0x43, 0x6c, 0x61, 0x73,
+ 0x73, 0x20, 0x31, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61,
+ 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x39, 0x36,
+ 0x30, 0x31, 0x32, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30,
+ 0x38, 0x30, 0x32, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09,
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55,
+ 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
+ 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2e, 0x43, 0x6c, 0x61,
+ 0x73, 0x73, 0x20, 0x31, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
+ 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x81, 0x9f, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
+ 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xe5, 0x19, 0xbf, 0x6d, 0xa3, 0x56, 0x61, 0x2d,
+ 0x99, 0x48, 0x71, 0xf6, 0x67, 0xde, 0xb9, 0x8d, 0xeb, 0xb7, 0x9e, 0x86, 0x80, 0x0a, 0x91, 0x0e,
+ 0xfa, 0x38, 0x25, 0xaf, 0x46, 0x88, 0x82, 0xe5, 0x73, 0xa8, 0xa0, 0x9b, 0x24, 0x5d, 0x0d, 0x1f,
+ 0xcc, 0x65, 0x6e, 0x0c, 0xb0, 0xd0, 0x56, 0x84, 0x18, 0x87, 0x9a, 0x06, 0x9b, 0x10, 0xa1, 0x73,
+ 0xdf, 0xb4, 0x58, 0x39, 0x6b, 0x6e, 0xc1, 0xf6, 0x15, 0xd5, 0xa8, 0xa8, 0x3f, 0xaa, 0x12, 0x06,
+ 0x8d, 0x31, 0xac, 0x7f, 0xb0, 0x34, 0xd7, 0x8f, 0x34, 0x67, 0x88, 0x09, 0xcd, 0x14, 0x11, 0xe2,
+ 0x4e, 0x45, 0x56, 0x69, 0x1f, 0x78, 0x02, 0x80, 0xda, 0xdc, 0x47, 0x91, 0x29, 0xbb, 0x36, 0xc9,
+ 0x63, 0x5c, 0xc5, 0xe0, 0xd7, 0x2d, 0x87, 0x7b, 0xa1, 0xb7, 0x32, 0xb0, 0x7b, 0x30, 0xba, 0x2a,
+ 0x2f, 0x31, 0xaa, 0xee, 0xa3, 0x67, 0xda, 0xdb, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00,
+ 0x58, 0x15, 0x29, 0x39, 0x3c, 0x77, 0xa3, 0xda, 0x5c, 0x25, 0x03, 0x7c, 0x60, 0xfa, 0xee, 0x09,
+ 0x99, 0x3c, 0x27, 0x10, 0x70, 0xc8, 0x0c, 0x09, 0xe6, 0xb3, 0x87, 0xcf, 0x0a, 0xe2, 0x18, 0x96,
+ 0x35, 0x62, 0xcc, 0xbf, 0x9b, 0x27, 0x79, 0x89, 0x5f, 0xc9, 0xc4, 0x09, 0xf4, 0xce, 0xb5, 0x1d,
+ 0xdf, 0x2a, 0xbd, 0xe5, 0xdb, 0x86, 0x9c, 0x68, 0x25, 0xe5, 0x30, 0x7c, 0xb6, 0x89, 0x15, 0xfe,
+ 0x67, 0xd1, 0xad, 0xe1, 0x50, 0xac, 0x3c, 0x7c, 0x62, 0x4b, 0x8f, 0xba, 0x84, 0xd7, 0x12, 0x15,
+ 0x1b, 0x1f, 0xca, 0x5d, 0x0f, 0xc1, 0x52, 0x94, 0x2a, 0x11, 0x99, 0xda, 0x7b, 0xcf, 0x0c, 0x36,
+ 0x13, 0xd5, 0x35, 0xdc, 0x10, 0x19, 0x59, 0xea, 0x94, 0xc1, 0x00, 0xbf, 0x75, 0x8f, 0xd9, 0xfa,
+ 0xfd, 0x76, 0x04, 0xdb, 0x62, 0xbb, 0x90, 0x6a, 0x03, 0xd9, 0x46, 0x35, 0xd9, 0xf8, 0x7c, 0x5b,
+};
+
#endif /* TEST_DATA_H_ */
diff --git a/trust/tests/test-module.c b/trust/tests/test-module.c
index 772dc8a..52eafe0 100644
--- a/trust/tests/test-module.c
+++ b/trust/tests/test-module.c
@@ -513,7 +513,7 @@ test_find_certificates (CuTest *cu)
setup (cu);
count = find_objects (cu, match, sessions, objects, 16);
- CuAssertIntEquals (cu, 7, count);
+ CuAssertIntEquals (cu, 8, count);
for (i = 0; i < count; i++)
check_certificate (cu, sessions[i], objects[i]);
diff --git a/trust/tests/test-parser.c b/trust/tests/test-parser.c
index a63d7a5..69049f7 100644
--- a/trust/tests/test-parser.c
+++ b/trust/tests/test-parser.c
@@ -156,6 +156,37 @@ test_parse_pem_certificate (CuTest *cu)
}
static void
+test_parse_p11_kit_persist (CuTest *cu)
+{
+ CK_ATTRIBUTE *cert;
+ int ret;
+
+ CK_ATTRIBUTE expected[] = {
+ { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) },
+ { CKA_CLASS, &certificate, sizeof (certificate) },
+ { CKA_VALUE, (void *)verisign_v1_ca, sizeof (verisign_v1_ca) },
+ { CKA_MODIFIABLE, &falsev, sizeof (falsev) },
+ { CKA_TRUSTED, &truev, sizeof (truev) },
+ { CKA_X_DISTRUSTED, &falsev, sizeof (falsev) },
+ { CKA_INVALID },
+ };
+
+ setup (cu);
+
+ ret = p11_parse_file (test.parser, SRCDIR "/input/verisign-v1.p11-kit",
+ P11_PARSE_FLAG_NONE);
+ CuAssertIntEquals (cu, P11_PARSE_SUCCESS, ret);
+
+ /* Should have gotten certificate */
+ CuAssertIntEquals (cu, 1, p11_index_size (test.index));
+
+ cert = parsed_attrs (certificate_match);
+ test_check_attrs (cu, expected, cert);
+
+ teardown (cu);
+}
+
+static void
test_parse_openssl_trusted (CuTest *cu)
{
CK_ATTRIBUTE cacert3[] = {
@@ -420,6 +451,7 @@ main (void)
SUITE_ADD_TEST (suite, test_parse_der_certificate);
SUITE_ADD_TEST (suite, test_parse_pem_certificate);
+ SUITE_ADD_TEST (suite, test_parse_p11_kit_persist);
SUITE_ADD_TEST (suite, test_parse_openssl_trusted);
SUITE_ADD_TEST (suite, test_parse_openssl_distrusted);
SUITE_ADD_TEST (suite, test_parse_anchor);
diff --git a/trust/tests/test-persist.c b/trust/tests/test-persist.c
new file mode 100644
index 0000000..d3bd117
--- /dev/null
+++ b/trust/tests/test-persist.c
@@ -0,0 +1,472 @@
+/*
+ * Copyright (c) 2013 Red Hat Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@redhat.com>
+ */
+
+#include "config.h"
+#include "CuTest.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "array.h"
+#include "attrs.h"
+#include "compat.h"
+#include "debug.h"
+#include "library.h"
+#include "persist.h"
+#include "pkcs11.h"
+#include "pkcs11x.h"
+
+#include "test-data.h"
+
+static void
+test_magic (CuTest *tc)
+{
+ const char *input = "[p11-kit-object-v1]\n"
+ "class: data\n"
+ "value: \"blah\"\n"
+ "application: \"test-persist\"\n";
+
+ const char *other = " "
+ "\n\n[p11-kit-object-v1]\n"
+ "class: data\n"
+ "value: \"blah\"\n"
+ "application: \"test-persist\"\n";
+
+ CuAssertTrue (tc, p11_persist_magic ((unsigned char *)input, strlen (input)));
+ CuAssertTrue (tc, !p11_persist_magic ((unsigned char *)input, 5));
+ CuAssertTrue (tc, p11_persist_magic ((unsigned char *)other, strlen (other)));
+ CuAssertTrue (tc, !p11_persist_magic ((unsigned char *)"blah", 4));
+}
+
+static p11_array *
+args_to_array (void *arg,
+ ...) GNUC_NULL_TERMINATED;
+
+static p11_array *
+args_to_array (void *arg,
+ ...)
+{
+ p11_array *array = p11_array_new (NULL);
+
+ va_list (va);
+ va_start (va, arg);
+
+ while (arg != NULL) {
+ p11_array_push (array, arg);
+ arg = va_arg (va, void *);
+ }
+
+ va_end (va);
+
+ return array;
+}
+
+static void
+check_read_msg (CuTest *tc,
+ const char *file,
+ int line,
+ const char *input,
+ p11_array *expected)
+{
+ p11_array *objects;
+ p11_persist *persist;
+ int i;
+
+ persist = p11_persist_new ();
+ objects = p11_array_new (p11_attrs_free);
+
+ if (p11_persist_read (persist, "test", (const unsigned char *)input, strlen (input), objects)) {
+ CuAssert_Line (tc, file, line, "decoding should have failed", expected != NULL);
+ for (i = 0; i < expected->num; i++) {
+ CuAssert_Line (tc, file, line, "too few objects read", i < objects->num);
+ test_check_attrs_msg (tc, file, line, expected->elem[i], objects->elem[i]);
+ }
+ CuAssert_Line (tc, file, line, "too many objects read", i == objects->num);
+ } else {
+ CuAssert_Line (tc, file, line, "decoding failed", expected == NULL);
+ }
+
+ p11_array_free (objects);
+ p11_persist_free (persist);
+ p11_array_free (expected);
+}
+
+#define check_read_success(tc, input, objs) \
+ check_read_msg (tc, __FILE__, __LINE__, input, args_to_array objs)
+
+#define check_read_failure(tc, input) \
+ check_read_msg (tc, __FILE__, __LINE__, input, NULL)
+
+static CK_OBJECT_CLASS certificate = CKO_CERTIFICATE;
+static CK_CERTIFICATE_TYPE x509 = CKC_X_509;
+static CK_OBJECT_CLASS nss_trust = CKO_NSS_TRUST;
+static CK_OBJECT_CLASS data = CKO_DATA;
+static CK_BBOOL truev = CK_TRUE;
+static CK_BBOOL falsev = CK_FALSE;
+
+static void
+test_simple (CuTest *tc)
+{
+ const char *input = "[p11-kit-object-v1]\n"
+ "class: data\n"
+ "value: \"blah\"\n"
+ "application: \"test-persist\"\n";
+
+ CK_ATTRIBUTE expected[] = {
+ { CKA_CLASS, &data, sizeof (data) },
+ { CKA_VALUE, "blah", 4 },
+ { CKA_APPLICATION, "test-persist", 12 },
+ { CKA_INVALID },
+ };
+
+ check_read_success (tc, input, (expected, NULL));
+}
+
+static void
+test_number (CuTest *tc)
+{
+ const char *input = "[p11-kit-object-v1]\n"
+ "class: data\n"
+ "value: 29202390239\n"
+ "application: \"test-persist\"\n";
+
+ CK_ULONG value = 29202390239;
+
+ CK_ATTRIBUTE expected[] = {
+ { CKA_CLASS, &data, sizeof (data) },
+ { CKA_VALUE, &value, sizeof (value) },
+ { CKA_APPLICATION, "test-persist", 12 },
+ { CKA_INVALID },
+ };
+
+ check_read_success (tc, input, (expected, NULL));
+}
+
+static void
+test_bool (CuTest *tc)
+{
+ const char *input = "[p11-kit-object-v1]\n"
+ "class: data\n"
+ "private: true\n"
+ "modifiable: false\n"
+ "application: \"test-persist\"\n";
+
+ CK_ATTRIBUTE expected[] = {
+ { CKA_CLASS, &data, sizeof (data) },
+ { CKA_PRIVATE, &truev, sizeof (truev) },
+ { CKA_MODIFIABLE, &falsev, sizeof (falsev) },
+ { CKA_APPLICATION, "test-persist", 12 },
+ { CKA_INVALID },
+ };
+
+ check_read_success (tc, input, (expected, NULL));
+}
+
+static void
+test_oid (CuTest *tc)
+{
+ const char *input = "[p11-kit-object-v1]\n"
+ "class: data\n"
+ "object-id: 1.2.3.4";
+
+ CK_ATTRIBUTE expected[] = {
+ { CKA_CLASS, &data, sizeof (data) },
+ { CKA_OBJECT_ID, "\x06\x03*\x03\x04", 5 },
+ { CKA_INVALID },
+ };
+
+ check_read_success (tc, input, (expected, NULL));
+}
+
+static void
+test_constant (CuTest *tc)
+{
+ const char *input = "[p11-kit-object-v1]\n"
+ "class: data\n"
+ "trust-server-auth: nss-trust-unknown";
+
+ CK_TRUST trust = CKT_NSS_TRUST_UNKNOWN;
+
+ CK_ATTRIBUTE expected[] = {
+ { CKA_CLASS, &data, sizeof (data) },
+ { CKA_TRUST_SERVER_AUTH, &trust, sizeof (trust) },
+ { CKA_INVALID },
+ };
+
+ check_read_success (tc, input, (expected, NULL));
+}
+
+static void
+test_multiple (CuTest *tc)
+{
+ const char *input = "[p11-kit-object-v1]\n"
+ "class: data\n"
+ "object-id: 1.2.3.4\n"
+ "[p11-kit-object-v1]\n"
+ "class: nss-trust\n"
+ "trust-server-auth: nss-trust-unknown";
+
+ CK_TRUST trust = CKT_NSS_TRUST_UNKNOWN;
+
+ CK_ATTRIBUTE expected1[] = {
+ { CKA_CLASS, &data, sizeof (data) },
+ { CKA_OBJECT_ID, "\x06\x03*\x03\x04", 5 },
+ { CKA_INVALID },
+ };
+
+ CK_ATTRIBUTE expected2[] = {
+ { CKA_CLASS, &nss_trust, sizeof (nss_trust) },
+ { CKA_TRUST_SERVER_AUTH, &trust, sizeof (trust) },
+ { CKA_INVALID },
+ };
+
+ check_read_success (tc, input, (expected1, expected2, NULL));
+}
+
+static void
+test_pem_block (CuTest *tc)
+{
+ const char *input = "[p11-kit-object-v1]\n"
+ "class: certificate\n"
+ "id: \"292c92\"\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"
+ "trusted: true";
+
+ CK_ATTRIBUTE expected[] = {
+ { CKA_CLASS, &certificate, sizeof (certificate) },
+ { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) },
+ { CKA_TRUSTED, &truev, sizeof (truev) },
+ { CKA_VALUE, &verisign_v1_ca, sizeof (verisign_v1_ca) },
+ { CKA_INVALID },
+ };
+
+ check_read_success (tc, input, (expected, NULL));
+}
+
+static void
+test_pem_invalid (CuTest *tc)
+{
+ const char *input = "[p11-kit-object-v1]\n"
+ "class: certificate\n"
+ "-----BEGIN CERT-----\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 CERTIFICATEXXX-----\n";
+
+ p11_message_quiet ();
+
+ check_read_failure (tc, input);
+
+ p11_message_loud ();
+}
+
+static void
+test_pem_unsupported (CuTest *tc)
+{
+ const char *input = "[p11-kit-object-v1]\n"
+ "class: certificate\n"
+ "-----BEGIN BLOCK1-----\n"
+ "aYNNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrx4a\n"
+ "-----END BLOCK1-----\n";
+
+ p11_message_quiet ();
+
+ check_read_failure (tc, input);
+
+ p11_message_loud ();
+}
+
+static void
+test_pem_first (CuTest *tc)
+{
+ const char *input = "-----BEGIN BLOCK1-----\n"
+ "aYNNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrx4a\n"
+ "-----END BLOCK1-----\n"
+ "[p11-kit-object-v1]\n"
+ "class: certificate\n";
+
+ p11_message_quiet ();
+
+ check_read_failure (tc, input);
+
+ p11_message_loud ();
+}
+
+static void
+test_skip_unknown (CuTest *tc)
+{
+ const char *input = "[version-2]\n"
+ "class: data\n"
+ "object-id: 1.2.3.4\n"
+ "-----BEGIN BLOCK1-----\n"
+ "aYNNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrx4a\n"
+ "-----END BLOCK1-----\n"
+ "[p11-kit-object-v1]\n"
+ "class: nss-trust\n"
+ "trust-server-auth: nss-trust-unknown";
+
+ CK_TRUST trust = CKT_NSS_TRUST_UNKNOWN;
+
+ CK_ATTRIBUTE expected2[] = {
+ { CKA_CLASS, &nss_trust, sizeof (nss_trust) },
+ { CKA_TRUST_SERVER_AUTH, &trust, sizeof (trust) },
+ { CKA_INVALID },
+ };
+
+ p11_message_quiet ();
+
+ check_read_success (tc, input, (expected2, NULL));
+
+ p11_message_loud ();
+}
+
+static void
+test_bad_value (CuTest *tc)
+{
+ const char *input = "[p11-kit-object-v1]\n"
+ "class: data\n"
+ "value: \"%38%\"\n";
+
+ p11_message_quiet ();
+
+ check_read_failure (tc, input);
+
+ p11_message_loud ();
+}
+
+static void
+test_bad_oid (CuTest *tc)
+{
+ const char *input = "[p11-kit-object-v1]\n"
+ "class: data\n"
+ "object-id: 1.2";
+
+ p11_message_quiet ();
+
+ check_read_failure (tc, input);
+
+ p11_message_loud ();
+}
+
+static void
+test_bad_field (CuTest *tc)
+{
+ const char *input = "[p11-kit-object-v1]\n"
+ "class: data\n"
+ "invalid-field: true";
+
+ p11_message_quiet ();
+
+ check_read_failure (tc, input);
+
+ p11_message_loud ();
+}
+
+static void
+test_attribute_first (CuTest *tc)
+{
+ const char *input = "class: data\n"
+ "[p11-kit-object-v1]\n"
+ "invalid-field: true";
+
+ p11_message_quiet ();
+
+ check_read_failure (tc, input);
+
+ p11_message_loud ();
+}
+
+int
+main (void)
+{
+ CuString *output = CuStringNew ();
+ CuSuite* suite = CuSuiteNew ();
+ int ret;
+
+ putenv ("P11_KIT_STRICT=1");
+ p11_debug_init ();
+ p11_library_init ();
+
+ SUITE_ADD_TEST (suite, test_magic);
+ SUITE_ADD_TEST (suite, test_simple);
+ SUITE_ADD_TEST (suite, test_number);
+ SUITE_ADD_TEST (suite, test_bool);
+ SUITE_ADD_TEST (suite, test_oid);
+ SUITE_ADD_TEST (suite, test_constant);
+ SUITE_ADD_TEST (suite, test_multiple);
+ SUITE_ADD_TEST (suite, test_pem_block);
+ SUITE_ADD_TEST (suite, test_pem_invalid);
+ SUITE_ADD_TEST (suite, test_pem_unsupported);
+ SUITE_ADD_TEST (suite, test_pem_first);
+ SUITE_ADD_TEST (suite, test_bad_value);
+ SUITE_ADD_TEST (suite, test_bad_oid);
+ SUITE_ADD_TEST (suite, test_bad_field);
+ SUITE_ADD_TEST (suite, test_skip_unknown);
+ SUITE_ADD_TEST (suite, test_attribute_first);
+
+ CuSuiteRun (suite);
+ CuSuiteSummary (suite, output);
+ CuSuiteDetails (suite, output);
+ printf ("%s\n", output->buffer);
+ ret = suite->failCount;
+ CuSuiteDelete (suite);
+ CuStringDelete (output);
+
+ return ret;
+}
diff --git a/trust/tests/test-token.c b/trust/tests/test-token.c
index 5cca233..c62fae2 100644
--- a/trust/tests/test-token.c
+++ b/trust/tests/test-token.c
@@ -74,7 +74,7 @@ test_token_load (CuTest *cu)
setup (cu, SRCDIR "/input");
count = p11_token_load (test.token);
- CuAssertIntEquals (cu, 6, count);
+ CuAssertIntEquals (cu, 7, count);
/* A certificate and trust object for each parsed object + builtin */
index = p11_token_index (test.token);