diff options
author | Stef Walter <stef@thewalter.net> | 2013-06-26 13:16:42 +0200 |
---|---|---|
committer | Stef Walter <stef@thewalter.net> | 2013-06-26 13:16:42 +0200 |
commit | 1e777512e554db76ba2f1aba800ee09a9fa074f0 (patch) | |
tree | 091b9d079edc3dd6a29fd1be8e470204c1e1a7f4 | |
parent | c807b2432bb954caf89f3092b65ea61a1bc6942e (diff) |
trust: Implement validation for creating/modifying objects
-rw-r--r-- | trust/builder.c | 277 | ||||
-rw-r--r-- | trust/tests/test-builder.c | 427 |
2 files changed, 661 insertions, 43 deletions
diff --git a/trust/builder.c b/trust/builder.c index 698fef1..bfbc42d 100644 --- a/trust/builder.c +++ b/trust/builder.c @@ -47,6 +47,7 @@ #include "message.h" #include "oid.h" #include "pkcs11x.h" +#include "utf8.h" #include "x509.h" #include <assert.h> @@ -77,8 +78,10 @@ typedef struct { struct { CK_ATTRIBUTE_TYPE type; int flags; + bool (*validate) (p11_builder *, CK_ATTRIBUTE *); } attrs[32]; CK_ATTRIBUTE * (*populate) (p11_builder *, p11_index *, CK_ATTRIBUTE *); + CK_RV (*validate) (p11_builder *, CK_ATTRIBUTE *); } builder_schema; static node_asn * @@ -185,12 +188,140 @@ p11_builder_new (int flags) return builder; } +static int +atoin (const char *p, + int digits) +{ + int ret = 0, base = 1; + while(--digits >= 0) { + if (p[digits] < '0' || p[digits] > '9') + return -1; + ret += (p[digits] - '0') * base; + base *= 10; + } + return ret; +} + +static bool +type_bool (p11_builder *builder, + CK_ATTRIBUTE *attr) +{ + return (attr->pValue != NULL && + sizeof (CK_BBOOL) == attr->ulValueLen); +} + +static bool +type_ulong (p11_builder *builder, + CK_ATTRIBUTE *attr) +{ + return (attr->pValue != NULL && + sizeof (CK_ULONG) == attr->ulValueLen); +} + +static bool +type_utf8 (p11_builder *builder, + CK_ATTRIBUTE *attr) +{ + if (attr->ulValueLen == 0) + return true; + if (attr->pValue == NULL) + return false; + return p11_utf8_validate (attr->pValue, attr->ulValueLen); +} + +static bool +type_date (p11_builder *builder, + CK_ATTRIBUTE *attr) +{ + CK_DATE *date; + struct tm tm; + struct tm two; + + if (attr->ulValueLen == 0) + return true; + if (attr->pValue == NULL || attr->ulValueLen != sizeof (CK_DATE)) + return false; + + date = attr->pValue; + memset (&tm, 0, sizeof (tm)); + tm.tm_year = atoin ((char *)date->year, 4); + tm.tm_mon = atoin ((char *)date->month, 2); + tm.tm_mday = atoin ((char *)date->day, 2); + + if (tm.tm_year < 0 || tm.tm_mon <= 0 || tm.tm_mday <= 0) + return false; + + memcpy (&two, &tm, sizeof (tm)); + if (mktime (&two) < 0) + return false; + + /* If mktime changed anything, then bad date */ + if (tm.tm_year != two.tm_year || + tm.tm_mon != two.tm_mon || + tm.tm_mday != two.tm_mday) + return false; + + return true; +} + +static bool +check_der_struct (p11_builder *builder, + const char *struct_name, + CK_ATTRIBUTE *attr) +{ + node_asn *asn; + + if (attr->ulValueLen == 0) + return true; + if (attr->pValue == NULL) + return false; + + asn = p11_asn1_decode (builder->asn1_defs, struct_name, + attr->pValue, attr->ulValueLen, NULL); + + if (asn == NULL) + return false; + + asn1_delete_structure (&asn); + return true; +} + +static bool +type_der_name (p11_builder *builder, + CK_ATTRIBUTE *attr) +{ + return check_der_struct (builder, "PKIX1.Name", attr); +} + +static bool +type_der_serial (p11_builder *builder, + CK_ATTRIBUTE *attr) +{ + return check_der_struct (builder, "PKIX1.CertificateSerialNumber", attr); +} + +static bool +type_der_oid (p11_builder *builder, + CK_ATTRIBUTE *attr) +{ + /* AttributeType is an OBJECT ID */ + return check_der_struct (builder, "PKIX1.AttributeType", attr); +} + +static bool +type_der_cert (p11_builder *builder, + CK_ATTRIBUTE *attr) +{ + /* AttributeType is an OBJECT ID */ + return check_der_struct (builder, "PKIX1.Certificate", attr); +} + #define COMMON_ATTRS \ - { CKA_CLASS, REQUIRE | CREATE }, \ - { CKA_TOKEN, CREATE | WANT }, \ - { CKA_MODIFIABLE, CREATE | WANT }, \ - { CKA_PRIVATE, CREATE }, \ - { CKA_LABEL, CREATE | MODIFY | WANT }, \ + { CKA_CLASS, REQUIRE | CREATE, type_ulong }, \ + { CKA_TOKEN, CREATE | WANT, type_bool }, \ + { CKA_MODIFIABLE, CREATE | WANT, type_bool }, \ + { CKA_PRIVATE, CREATE, type_bool }, \ + { CKA_LABEL, CREATE | MODIFY | WANT, type_utf8 }, \ { CKA_X_GENERATED, CREATE } static CK_ATTRIBUTE * @@ -228,20 +359,6 @@ calc_check_value (const unsigned char *data, } static int -atoin (const char *p, - int digits) -{ - int ret = 0, base = 1; - while(--digits >= 0) { - if (p[digits] < '0' || p[digits] > '9') - return -1; - ret += (p[digits] - '0') * base; - base *= 10; - } - return ret; -} - -static int century_for_two_digit_year (int year) { time_t now; @@ -577,27 +694,58 @@ certificate_populate (p11_builder *builder, return p11_attrs_build (attrs, &category, &empty_value, NULL); } +static CK_RV +certificate_validate (p11_builder *builder, + CK_ATTRIBUTE *attrs) +{ + CK_ATTRIBUTE *attr; + + /* + * In theory we should be validating that in the absence of CKA_VALUE + * various other fields must be set. However we do not enforce this + * because we want to be able to have certificates without a value + * but issuer and serial number, for blacklisting purposes. + */ + + attr = p11_attrs_find (attrs, CKA_URL); + if (attr != NULL && attr->ulValueLen > 0) { + attr = p11_attrs_find (attrs, CKA_HASH_OF_SUBJECT_PUBLIC_KEY); + if (attr == NULL || attr->ulValueLen == 0) { + p11_message ("missing the CKA_HASH_OF_SUBJECT_PUBLIC_KEY attribute"); + return CKR_TEMPLATE_INCONSISTENT; + } + + attr = p11_attrs_find (attrs, CKA_HASH_OF_ISSUER_PUBLIC_KEY); + if (attr == NULL || attr->ulValueLen == 0) { + p11_message ("missing the CKA_HASH_OF_ISSUER_PUBLIC_KEY attribute"); + return CKR_TEMPLATE_INCONSISTENT; + } + } + + return CKR_OK; +} + const static builder_schema certificate_schema = { NORMAL_BUILD, { COMMON_ATTRS, - { CKA_CERTIFICATE_TYPE, REQUIRE | CREATE }, - { CKA_TRUSTED, }, - { CKA_X_DISTRUSTED, }, - { CKA_CERTIFICATE_CATEGORY, CREATE | MODIFY | WANT }, - { CKA_CHECK_VALUE, CREATE | MODIFY | WANT }, - { CKA_START_DATE, CREATE | MODIFY | WANT }, - { CKA_END_DATE, CREATE | MODIFY | WANT }, - { CKA_SUBJECT, CREATE | WANT }, + { CKA_CERTIFICATE_TYPE, REQUIRE | CREATE, type_ulong }, + { CKA_TRUSTED, NONE, type_bool }, + { CKA_X_DISTRUSTED, NONE, type_bool }, + { CKA_CERTIFICATE_CATEGORY, CREATE | WANT, type_ulong }, + { CKA_CHECK_VALUE, CREATE | WANT, }, + { CKA_START_DATE, CREATE | MODIFY | WANT, type_date }, + { CKA_END_DATE, CREATE | MODIFY | WANT, type_date }, + { CKA_SUBJECT, CREATE | WANT, type_der_name }, { CKA_ID, CREATE | MODIFY | WANT }, - { CKA_ISSUER, CREATE | MODIFY | WANT }, - { CKA_SERIAL_NUMBER, CREATE | MODIFY | WANT }, - { CKA_VALUE, CREATE }, - { CKA_URL, CREATE }, + { CKA_ISSUER, CREATE | MODIFY | WANT, type_der_name }, + { CKA_SERIAL_NUMBER, CREATE | MODIFY | WANT, type_der_serial }, + { CKA_VALUE, CREATE, type_der_cert }, + { CKA_URL, CREATE, type_utf8 }, { CKA_HASH_OF_SUBJECT_PUBLIC_KEY, CREATE }, { CKA_HASH_OF_ISSUER_PUBLIC_KEY, CREATE }, - { CKA_JAVA_MIDP_SECURITY_DOMAIN, CREATE }, + { CKA_JAVA_MIDP_SECURITY_DOMAIN, CREATE, type_ulong }, { CKA_INVALID }, - }, certificate_populate, + }, certificate_populate, certificate_validate, }; static CK_ATTRIBUTE * @@ -624,8 +772,8 @@ const static builder_schema extension_schema = { NORMAL_BUILD, { COMMON_ATTRS, { CKA_VALUE, REQUIRE | CREATE }, - { CKA_X_CRITICAL, WANT }, - { CKA_OBJECT_ID, REQUIRE | CREATE }, + { CKA_X_CRITICAL, WANT, type_bool }, + { CKA_OBJECT_ID, REQUIRE | CREATE, type_der_oid }, { CKA_ID, CREATE | MODIFY | WANT }, { CKA_INVALID }, }, extension_populate, @@ -651,8 +799,8 @@ const static builder_schema data_schema = { NORMAL_BUILD, { COMMON_ATTRS, { CKA_VALUE, CREATE | MODIFY | WANT }, - { CKA_APPLICATION, CREATE | MODIFY | WANT }, - { CKA_OBJECT_ID, CREATE | MODIFY | WANT }, + { CKA_APPLICATION, CREATE | MODIFY | WANT, type_utf8 }, + { CKA_OBJECT_ID, CREATE | MODIFY | WANT, type_der_oid }, { CKA_INVALID }, }, data_populate, }; @@ -749,6 +897,40 @@ type_name (CK_ATTRIBUTE_TYPE type) } static CK_RV +validate_for_schema (p11_builder *builder, + const builder_schema *schema, + CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *merge) +{ + CK_ATTRIBUTE *shallow; + CK_ULONG nattrs; + CK_ULONG nmerge; + CK_RV rv; + + if (!schema->validate) + return CKR_OK; + + nattrs = p11_attrs_count (attrs); + nmerge = p11_attrs_count (merge); + + /* Make a shallow copy of the combined attributes for validation */ + shallow = calloc (nmerge + nattrs + 1, sizeof (CK_ATTRIBUTE)); + return_val_if_fail (shallow != NULL, CKR_GENERAL_ERROR); + + memcpy (shallow, merge, sizeof (CK_ATTRIBUTE) * nmerge); + memcpy (shallow + nmerge, attrs, sizeof (CK_ATTRIBUTE) * nattrs); + + /* The terminator attribute */ + shallow[nmerge + nattrs].type = CKA_INVALID; + assert(p11_attrs_terminator (shallow + nmerge + nattrs)); + + rv = (schema->validate) (builder, shallow); + free (shallow); + + return rv; +} + +static CK_RV build_for_schema (p11_builder *builder, p11_index *index, const builder_schema *schema, @@ -765,6 +947,7 @@ build_for_schema (p11_builder *builder, bool found; int flags; int i, j; + CK_RV rv; attrs = *object; populate = false; @@ -813,6 +996,12 @@ build_for_schema (p11_builder *builder, type_name (schema->attrs[j].type)); return CKR_ATTRIBUTE_READ_ONLY; } + if (!loading && schema->attrs[j].validate != NULL && + !schema->attrs[j].validate (builder, merge + i)) { + p11_message ("the %s attribute has an invalid value", + type_name (schema->attrs[j].type)); + return CKR_ATTRIBUTE_VALUE_INVALID; + } found = true; break; } @@ -856,12 +1045,14 @@ build_for_schema (p11_builder *builder, merge = p11_attrs_merge (merge, extra, false); } - /* - * TODO: Validate the result, before committing to the change. We can - * do this by doing a shallow copy of merge + attrs and then validating - * that. Although there may be duplicate attributets, the validation - * code will see the new ones because they're first. - */ + /* Validate the result, before committing to the change. */ + if (!loading) { + rv = validate_for_schema (builder, schema, attrs, merge); + if (rv != CKR_OK) { + p11_attrs_free (merge); + return rv; + } + } *object = p11_attrs_merge (attrs, merge, true); return_val_if_fail (*object != NULL, CKR_HOST_MEMORY); diff --git a/trust/tests/test-builder.c b/trust/tests/test-builder.c index 891c722..91998fa 100644 --- a/trust/tests/test-builder.c +++ b/trust/tests/test-builder.c @@ -528,6 +528,416 @@ test_build_distant_end_date (void) } static void +test_valid_bool (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_BBOOL value = CK_TRUE; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_PRIVATE, &value, sizeof (value) }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_OK, rv); + + p11_attrs_free (attrs); +} + +static void +test_invalid_bool (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_PRIVATE, NULL, 0 }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + p11_message_quiet (); + + input[0].pValue = "123"; + input[0].ulValueLen = 3; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + + input[0].pValue = NULL; + input[0].ulValueLen = sizeof (CK_BBOOL); + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + p11_message_loud (); +} + +static void +test_valid_ulong (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_ULONG value = 2; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_CERTIFICATE_CATEGORY, &value, sizeof (value) }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_OK, rv); + + p11_attrs_free (attrs); +} + +static void +test_invalid_ulong (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_CERTIFICATE_CATEGORY, NULL, 0 }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + p11_message_quiet (); + + input[0].pValue = "123"; + input[0].ulValueLen = 3; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + + input[0].pValue = NULL; + input[0].ulValueLen = sizeof (CK_ULONG); + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + p11_message_loud (); +} + +static void +test_valid_utf8 (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_LABEL, NULL, 0 }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + input[0].pValue = NULL; + input[0].ulValueLen = 0; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_OK, rv); + + p11_attrs_free (attrs); +} + +static void +test_invalid_utf8 (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_LABEL, NULL, 0 }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + p11_message_quiet (); + + input[0].pValue = "\xfex23"; + input[0].ulValueLen = 4; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + + input[0].pValue = NULL; + input[0].ulValueLen = 4; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + p11_message_loud (); +} + +static void +test_valid_dates (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_DATE date; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_START_DATE, &date, sizeof (CK_DATE) }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + memcpy (&date, "20001010", sizeof (date)); + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_OK, rv); + + p11_attrs_free (attrs); + attrs = NULL; + + input[0].ulValueLen = 0; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_OK, rv); + + p11_attrs_free (attrs); +} + +static void +test_invalid_dates (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_DATE date; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_START_DATE, &date, sizeof (CK_DATE) }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + p11_message_quiet (); + + memcpy (&date, "AAAABBCC", sizeof (date)); + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + memcpy (&date, "20001580", sizeof (date)); + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + input[0].pValue = NULL; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + p11_message_loud (); +} + +static void +test_valid_name (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_SUBJECT, NULL, 0 }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + input[0].pValue = NULL; + input[0].ulValueLen = 0; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_OK, rv); + + p11_attrs_free (attrs); + attrs = NULL; + + input[0].pValue = (void *)test_cacert3_ca_issuer; + input[0].ulValueLen = sizeof (test_cacert3_ca_issuer); + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_OK, rv); + + p11_attrs_free (attrs); +} + +static void +test_invalid_name (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_SUBJECT, NULL, 0 }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + p11_message_quiet (); + + input[0].pValue = "blah"; + input[0].ulValueLen = 4; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + input[0].pValue = NULL; + input[0].ulValueLen = 4; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + p11_message_loud (); +} + +static void +test_valid_serial (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_SERIAL_NUMBER, NULL, 0 }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + input[0].pValue = NULL; + input[0].ulValueLen = 0; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_OK, rv); + + p11_attrs_free (attrs); + attrs = NULL; + + input[0].pValue = (void *)test_cacert3_ca_serial; + input[0].ulValueLen = sizeof (test_cacert3_ca_serial); + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_OK, rv); + + p11_attrs_free (attrs); +} + +static void +test_invalid_serial (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_SERIAL_NUMBER, NULL, 0 }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + p11_message_quiet (); + + input[0].pValue = "blah"; + input[0].ulValueLen = 4; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + input[0].pValue = (void *)test_cacert3_ca_subject; + input[0].ulValueLen = sizeof (test_cacert3_ca_subject); + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + input[0].pValue = NULL; + input[0].ulValueLen = 4; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + p11_message_loud (); +} + +static void +test_valid_cert (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_VALUE, NULL, 0 }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + input[0].pValue = NULL; + input[0].ulValueLen = 0; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_OK, rv); + + p11_attrs_free (attrs); + attrs = NULL; + + input[0].pValue = (void *)test_cacert3_ca_der; + input[0].ulValueLen = sizeof (test_cacert3_ca_der); + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_OK, rv); + + p11_attrs_free (attrs); +} + +static void +test_invalid_cert (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_VALUE, NULL, 0 }, + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_INVALID }, + }; + + p11_message_quiet (); + + input[0].pValue = "blah"; + input[0].ulValueLen = 4; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + input[0].pValue = (void *)test_cacert3_ca_subject; + input[0].ulValueLen = sizeof (test_cacert3_ca_subject); + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + input[0].pValue = NULL; + input[0].ulValueLen = 4; + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_ATTRIBUTE_VALUE_INVALID, rv); + + p11_message_loud (); +} + +static void +test_invalid_schema (void) +{ + CK_ATTRIBUTE *attrs = NULL; + CK_RV rv; + + CK_ATTRIBUTE input[] = { + { CKA_CLASS, &certificate, sizeof (certificate) }, + { CKA_CERTIFICATE_TYPE, &x509, sizeof (x509) }, + { CKA_URL, "http://blah", 11 }, + { CKA_INVALID }, + }; + + p11_message_quiet (); + + /* Missing CKA_HASH_OF_SUBJECT_PUBLIC_KEY and CKA_HASH_OF_ISSUER_PUBLIC_KEY */ + rv = p11_builder_build (test.builder, test.index, &attrs, p11_attrs_dup (input)); + assert_num_eq (CKR_TEMPLATE_INCONSISTENT, rv); + + p11_message_loud (); +} + +static void test_create_not_settable (void) { /* @@ -1597,6 +2007,23 @@ main (int argc, p11_test (test_build_certificate_bad_type, "/builder/build_certificate_bad_type"); p11_test (test_build_extension, "/builder/build_extension"); p11_test (test_build_distant_end_date, "/builder/build_distant_end_date"); + + p11_test (test_valid_bool, "/builder/valid-bool"); + p11_test (test_valid_ulong, "/builder/valid-ulong"); + p11_test (test_valid_utf8, "/builder/valid-utf8"); + p11_test (test_valid_dates, "/builder/valid-date"); + p11_test (test_valid_name, "/builder/valid-name"); + p11_test (test_valid_serial, "/builder/valid-serial"); + p11_test (test_valid_cert, "/builder/valid-cert"); + p11_test (test_invalid_bool, "/builder/invalid-bool"); + p11_test (test_invalid_ulong, "/builder/invalid-ulong"); + p11_test (test_invalid_utf8, "/builder/invalid-utf8"); + p11_test (test_invalid_dates, "/builder/invalid-date"); + p11_test (test_invalid_name, "/builder/invalid-name"); + p11_test (test_invalid_serial, "/builder/invalid-serial"); + p11_test (test_invalid_cert, "/builder/invalid-cert"); + p11_test (test_invalid_schema, "/builder/invalid-schema"); + p11_test (test_create_not_settable, "/builder/create_not_settable"); p11_test (test_create_but_loadable, "/builder/create_but_loadable"); p11_test (test_create_unsupported, "/builder/create_unsupported"); |