diff options
-rw-r--r-- | common/Makefile.am | 2 | ||||
-rw-r--r-- | common/basic.asn | 12 | ||||
-rw-r--r-- | common/basic.asn.h | 13 | ||||
-rw-r--r-- | doc/internal/persist-format.txt | 54 | ||||
-rw-r--r-- | trust/Makefile.am | 1 | ||||
-rw-r--r-- | trust/parser.c | 35 | ||||
-rw-r--r-- | trust/persist.c | 401 | ||||
-rw-r--r-- | trust/persist.h | 59 | ||||
-rw-r--r-- | trust/tests/Makefile.am | 1 | ||||
-rw-r--r-- | trust/tests/input/verisign-v1.p11-kit | 17 | ||||
-rw-r--r-- | trust/tests/test-builder.c | 39 | ||||
-rw-r--r-- | trust/tests/test-data.h | 39 | ||||
-rw-r--r-- | trust/tests/test-module.c | 2 | ||||
-rw-r--r-- | trust/tests/test-parser.c | 32 | ||||
-rw-r--r-- | trust/tests/test-persist.c | 472 | ||||
-rw-r--r-- | trust/tests/test-token.c | 2 |
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); |