summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2013-01-24 14:36:59 +0100
committerStef Walter <stefw@gnome.org>2013-02-04 10:55:45 +0100
commit7ddff6795830deff6ec5fb1b8b0c704fbdea2c97 (patch)
treed9d4ad6c4889fa8d9ec6d01a7a76222bd9efac4f
parent322b4739cb51aa45568d9479224f2b07ac82a35f (diff)
Further tweaks and cleanup for functions dealing with PKCS#11 attributes
* Check that the size is correct when looking for a boolean or a ulong. * Make sure that the length is not the invalid negative ulong. * Functions for dumping out attribute contents * Make it possible to use attributes in hash tables
-rw-r--r--common/attrs.c795
-rw-r--r--common/attrs.h59
-rw-r--r--common/tests/test-attrs.c126
3 files changed, 910 insertions, 70 deletions
diff --git a/common/attrs.c b/common/attrs.c
index dd91afc..ab1bc59 100644
--- a/common/attrs.c
+++ b/common/attrs.c
@@ -36,22 +36,26 @@
#include "config.h"
#include "attrs.h"
+#include "buffer.h"
#include "compat.h"
#include "debug.h"
+#include "pkcs11.h"
+#include "pkcs11x.h"
#include <assert.h>
#include <stdarg.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-CK_BBOOL
-p11_attrs_is_empty (CK_ATTRIBUTE *attrs)
+bool
+p11_attrs_is_empty (const CK_ATTRIBUTE *attrs)
{
return (attrs == NULL || attrs->type == CKA_INVALID);
}
CK_ULONG
-p11_attrs_count (CK_ATTRIBUTE *attrs)
+p11_attrs_count (const CK_ATTRIBUTE *attrs)
{
CK_ULONG count;
@@ -169,7 +173,7 @@ template_generator (void *state)
CK_ATTRIBUTE *
p11_attrs_buildn (CK_ATTRIBUTE *attrs,
- CK_ATTRIBUTE *add,
+ const CK_ATTRIBUTE *add,
CK_ULONG count)
{
return attrs_build (attrs, count, true, template_generator, &add);
@@ -187,7 +191,7 @@ p11_attrs_take (CK_ATTRIBUTE *attrs,
}
CK_ATTRIBUTE *
-p11_attrs_dup (CK_ATTRIBUTE *attrs)
+p11_attrs_dup (const CK_ATTRIBUTE *attrs)
{
CK_ULONG count;
@@ -224,7 +228,116 @@ p11_attrs_findn (CK_ATTRIBUTE *attrs,
return NULL;
}
-CK_BBOOL
+bool
+p11_attrs_find_bool (CK_ATTRIBUTE *attrs,
+ CK_ATTRIBUTE_TYPE type,
+ CK_BBOOL *value)
+{
+ CK_ULONG i;
+
+ for (i = 0; !p11_attrs_is_empty (attrs + i); i++) {
+ if (attrs[i].type == type &&
+ attrs[i].ulValueLen == sizeof (CK_BBOOL) &&
+ attrs[i].pValue != NULL) {
+ *value = *((CK_BBOOL *)attrs[i].pValue);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+p11_attrs_findn_bool (CK_ATTRIBUTE *attrs,
+ CK_ULONG count,
+ CK_ATTRIBUTE_TYPE type,
+ CK_BBOOL *value)
+{
+ CK_ULONG i;
+
+ for (i = 0; i < count; i++) {
+ if (attrs[i].type == type &&
+ attrs[i].ulValueLen == sizeof (CK_BBOOL) &&
+ attrs[i].pValue != NULL) {
+ *value = *((CK_BBOOL *)attrs[i].pValue);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+p11_attrs_find_ulong (CK_ATTRIBUTE *attrs,
+ CK_ATTRIBUTE_TYPE type,
+ CK_ULONG *value)
+{
+ CK_ULONG i;
+
+ for (i = 0; !p11_attrs_is_empty (attrs + i); i++) {
+ if (attrs[i].type == type &&
+ attrs[i].ulValueLen == sizeof (CK_ULONG) &&
+ attrs[i].pValue != NULL) {
+ *value = *((CK_ULONG *)attrs[i].pValue);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+p11_attrs_findn_ulong (CK_ATTRIBUTE *attrs,
+ CK_ULONG count,
+ CK_ATTRIBUTE_TYPE type,
+ CK_ULONG *value)
+{
+ CK_ULONG i;
+
+ for (i = 0; i < count; i++) {
+ if (attrs[i].type == type &&
+ attrs[i].ulValueLen == sizeof (CK_ULONG) &&
+ attrs[i].pValue != NULL) {
+ *value = *((CK_ULONG *)attrs[i].pValue);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+CK_ATTRIBUTE *
+p11_attrs_find_valid (CK_ATTRIBUTE *attrs,
+ CK_ATTRIBUTE_TYPE type)
+{
+ CK_ULONG i;
+
+ for (i = 0; !p11_attrs_is_empty (attrs + i); i++) {
+ if (attrs[i].type == type &&
+ attrs[i].ulValueLen != (CK_ULONG)-1)
+ return attrs + i;
+ }
+
+ return NULL;
+}
+
+CK_ATTRIBUTE *
+p11_attrs_findn_valid (CK_ATTRIBUTE *attrs,
+ CK_ULONG count,
+ CK_ATTRIBUTE_TYPE type)
+{
+ CK_ULONG i;
+
+ for (i = 0; i < count; i++) {
+ if (attrs[i].type == type &&
+ attrs[i].ulValueLen != (CK_ULONG)-1)
+ return attrs + i;
+ }
+
+ return NULL;
+}
+
+bool
p11_attrs_remove (CK_ATTRIBUTE *attrs,
CK_ATTRIBUTE_TYPE type)
{
@@ -238,73 +351,675 @@ p11_attrs_remove (CK_ATTRIBUTE *attrs,
}
if (i == count)
- return CK_FALSE;
+ return false;
if (attrs[i].pValue)
free (attrs[i].pValue);
memmove (attrs + i, attrs + i + 1, (count - (i + 1)) * sizeof (CK_ATTRIBUTE));
attrs[count - 1].type = CKA_INVALID;
- return CK_TRUE;
+ return true;
}
-CK_BBOOL
-p11_attrs_match (CK_ATTRIBUTE *attrs,
- CK_ATTRIBUTE *match)
+bool
+p11_attrs_match (const CK_ATTRIBUTE *attrs,
+ const CK_ATTRIBUTE *match)
{
CK_ATTRIBUTE *attr;
for (; !p11_attrs_is_empty (match); match++) {
- attr = p11_attrs_find (attrs, match->type);
+ attr = p11_attrs_find ((CK_ATTRIBUTE *)attrs, match->type);
if (!attr)
- return CK_FALSE;
+ return false;
if (!p11_attr_equal (attr, match))
- return CK_FALSE;
+ return false;
}
- return CK_TRUE;
+ return true;
}
-CK_BBOOL
-p11_attrs_matchn (CK_ATTRIBUTE *attrs,
- CK_ATTRIBUTE *match,
+bool
+p11_attrs_matchn (const CK_ATTRIBUTE *attrs,
+ const CK_ATTRIBUTE *match,
CK_ULONG count)
{
CK_ATTRIBUTE *attr;
CK_ULONG i;
for (i = 0; i < count; i++) {
- attr = p11_attrs_find (attrs, match[i].type);
+ attr = p11_attrs_find ((CK_ATTRIBUTE *)attrs, match[i].type);
if (!attr)
- return CK_FALSE;
+ return false;
if (!p11_attr_equal (attr, match + i))
- return CK_FALSE;
+ return false;
}
- return CK_TRUE;
+ return true;
+
+}
+
+
+bool
+p11_attr_match_value (const CK_ATTRIBUTE *attr,
+ const void *value,
+ ssize_t length)
+{
+ if (length < 0)
+ length = strlen (value);
+ return (attr != NULL &&
+ attr->ulValueLen == length &&
+ (attr->pValue == value ||
+ (attr->pValue && value &&
+ memcmp (attr->pValue, value, attr->ulValueLen) == 0)));
+}
+
+bool
+p11_attr_equal (const void *v1,
+ const void *v2)
+{
+ const CK_ATTRIBUTE *one = v1;
+ const CK_ATTRIBUTE *two = v2;
+
+ return (one == two ||
+ (one && two && one->type == two->type &&
+ p11_attr_match_value (one, two->pValue, two->ulValueLen)));
+}
+
+unsigned int
+p11_attr_hash (const void *data)
+{
+ const CK_ATTRIBUTE *attr = data;
+ unsigned int hash = (unsigned int)attr->type;
+ const char *p, *end;
+
+ for (p = attr->pValue, end = p + attr->ulValueLen ; p != NULL && p != end; p++)
+ hash = (hash << 5) - hash + *p;
+
+ return hash;
+}
+
+static void
+buffer_append_printf (p11_buffer *buffer,
+ const char *format,
+ ...)
+{
+ char *string;
+ va_list va;
+
+ va_start (va, format);
+ if (vasprintf (&string, format, va) < 0)
+ return_if_reached ();
+ va_end (va);
+ p11_buffer_add (buffer, string, -1);
+ free (string);
+}
+
+static bool
+attribute_is_ulong_of_type (const CK_ATTRIBUTE *attr,
+ CK_ULONG type)
+{
+ if (attr->type != type)
+ return false;
+ if (attr->ulValueLen != sizeof (CK_ULONG))
+ return false;
+ if (!attr->pValue)
+ return false;
+ return true;
+}
+
+static bool
+attribute_is_trust_value (const CK_ATTRIBUTE *attr)
+{
+ switch (attr->type) {
+ case CKA_TRUST_DIGITAL_SIGNATURE:
+ case CKA_TRUST_NON_REPUDIATION:
+ case CKA_TRUST_KEY_ENCIPHERMENT:
+ case CKA_TRUST_DATA_ENCIPHERMENT:
+ case CKA_TRUST_KEY_AGREEMENT:
+ case CKA_TRUST_KEY_CERT_SIGN:
+ case CKA_TRUST_CRL_SIGN:
+ case CKA_TRUST_SERVER_AUTH:
+ case CKA_TRUST_CLIENT_AUTH:
+ case CKA_TRUST_CODE_SIGNING:
+ case CKA_TRUST_EMAIL_PROTECTION:
+ case CKA_TRUST_IPSEC_END_SYSTEM:
+ case CKA_TRUST_IPSEC_TUNNEL:
+ case CKA_TRUST_IPSEC_USER:
+ case CKA_TRUST_TIME_STAMPING:
+ break;
+ default:
+ return false;
+ }
+
+ return attribute_is_ulong_of_type (attr, attr->type);
+}
+
+static bool
+attribute_is_sensitive (const CK_ATTRIBUTE *attr)
+{
+ /*
+ * Don't print any just attribute, since they may contain
+ * sensitive data
+ */
+
+ switch (attr->type) {
+ #define X(x) case x: return false;
+ X (CKA_CLASS)
+ X (CKA_TOKEN)
+ X (CKA_PRIVATE)
+ X (CKA_LABEL)
+ X (CKA_APPLICATION)
+ X (CKA_OBJECT_ID)
+ X (CKA_CERTIFICATE_TYPE)
+ X (CKA_ISSUER)
+ X (CKA_SERIAL_NUMBER)
+ X (CKA_AC_ISSUER)
+ X (CKA_OWNER)
+ X (CKA_ATTR_TYPES)
+ X (CKA_TRUSTED)
+ X (CKA_CERTIFICATE_CATEGORY)
+ X (CKA_JAVA_MIDP_SECURITY_DOMAIN)
+ X (CKA_URL)
+ X (CKA_HASH_OF_SUBJECT_PUBLIC_KEY)
+ X (CKA_HASH_OF_ISSUER_PUBLIC_KEY)
+ X (CKA_CHECK_VALUE)
+ X (CKA_KEY_TYPE)
+ X (CKA_SUBJECT)
+ X (CKA_ID)
+ X (CKA_SENSITIVE)
+ X (CKA_ENCRYPT)
+ X (CKA_DECRYPT)
+ X (CKA_WRAP)
+ X (CKA_UNWRAP)
+ X (CKA_SIGN)
+ X (CKA_SIGN_RECOVER)
+ X (CKA_VERIFY)
+ X (CKA_VERIFY_RECOVER)
+ X (CKA_DERIVE)
+ X (CKA_START_DATE)
+ X (CKA_END_DATE)
+ X (CKA_MODULUS_BITS)
+ X (CKA_PRIME_BITS)
+ /* X (CKA_SUBPRIME_BITS) */
+ /* X (CKA_SUB_PRIME_BITS) */
+ X (CKA_VALUE_BITS)
+ X (CKA_VALUE_LEN)
+ X (CKA_EXTRACTABLE)
+ X (CKA_LOCAL)
+ X (CKA_NEVER_EXTRACTABLE)
+ X (CKA_ALWAYS_SENSITIVE)
+ X (CKA_KEY_GEN_MECHANISM)
+ X (CKA_MODIFIABLE)
+ X (CKA_SECONDARY_AUTH)
+ X (CKA_AUTH_PIN_FLAGS)
+ X (CKA_ALWAYS_AUTHENTICATE)
+ X (CKA_WRAP_WITH_TRUSTED)
+ X (CKA_WRAP_TEMPLATE)
+ X (CKA_UNWRAP_TEMPLATE)
+ X (CKA_HW_FEATURE_TYPE)
+ X (CKA_RESET_ON_INIT)
+ X (CKA_HAS_RESET)
+ X (CKA_PIXEL_X)
+ X (CKA_PIXEL_Y)
+ X (CKA_RESOLUTION)
+ X (CKA_CHAR_ROWS)
+ X (CKA_CHAR_COLUMNS)
+ X (CKA_COLOR)
+ X (CKA_BITS_PER_PIXEL)
+ X (CKA_CHAR_SETS)
+ X (CKA_ENCODING_METHODS)
+ X (CKA_MIME_TYPES)
+ X (CKA_MECHANISM_TYPE)
+ X (CKA_REQUIRED_CMS_ATTRIBUTES)
+ X (CKA_DEFAULT_CMS_ATTRIBUTES)
+ X (CKA_SUPPORTED_CMS_ATTRIBUTES)
+ X (CKA_ALLOWED_MECHANISMS)
+ X (CKA_X_ASSERTION_TYPE)
+ X (CKA_X_CERTIFICATE_VALUE)
+ X (CKA_X_PURPOSE)
+ X (CKA_X_PEER)
+ X (CKA_X_DISTRUSTED)
+ X (CKA_X_CRITICAL)
+ X (CKA_NETSCAPE_URL)
+ X (CKA_NETSCAPE_EMAIL)
+ X (CKA_NETSCAPE_SMIME_INFO)
+ X (CKA_NETSCAPE_SMIME_TIMESTAMP)
+ X (CKA_NETSCAPE_PKCS8_SALT)
+ X (CKA_NETSCAPE_PASSWORD_CHECK)
+ X (CKA_NETSCAPE_EXPIRES)
+ X (CKA_NETSCAPE_KRL)
+ X (CKA_NETSCAPE_PQG_COUNTER)
+ X (CKA_NETSCAPE_PQG_SEED)
+ X (CKA_NETSCAPE_PQG_H)
+ X (CKA_NETSCAPE_PQG_SEED_BITS)
+ X (CKA_NETSCAPE_MODULE_SPEC)
+ X (CKA_TRUST_DIGITAL_SIGNATURE)
+ X (CKA_TRUST_NON_REPUDIATION)
+ X (CKA_TRUST_KEY_ENCIPHERMENT)
+ X (CKA_TRUST_DATA_ENCIPHERMENT)
+ X (CKA_TRUST_KEY_AGREEMENT)
+ X (CKA_TRUST_KEY_CERT_SIGN)
+ X (CKA_TRUST_CRL_SIGN)
+ X (CKA_TRUST_SERVER_AUTH)
+ X (CKA_TRUST_CLIENT_AUTH)
+ X (CKA_TRUST_CODE_SIGNING)
+ X (CKA_TRUST_EMAIL_PROTECTION)
+ X (CKA_TRUST_IPSEC_END_SYSTEM)
+ X (CKA_TRUST_IPSEC_TUNNEL)
+ X (CKA_TRUST_IPSEC_USER)
+ X (CKA_TRUST_TIME_STAMPING)
+ X (CKA_TRUST_STEP_UP_APPROVED)
+ X (CKA_CERT_SHA1_HASH)
+ X (CKA_CERT_MD5_HASH)
+ #undef X
+ }
+
+ return true;
+}
+
+static void
+format_class (p11_buffer *buffer,
+ CK_OBJECT_CLASS klass)
+{
+ const char *string = NULL;
+
+ switch (klass) {
+ #define X(x) case x: string = #x; break;
+ X (CKO_DATA)
+ X (CKO_CERTIFICATE)
+ X (CKO_PUBLIC_KEY)
+ X (CKO_PRIVATE_KEY)
+ X (CKO_SECRET_KEY)
+ X (CKO_HW_FEATURE)
+ X (CKO_DOMAIN_PARAMETERS)
+ X (CKO_MECHANISM)
+ X (CKO_X_TRUST_ASSERTION)
+ X (CKO_X_CERTIFICATE_EXTENSION)
+ X (CKO_NETSCAPE_CRL)
+ X (CKO_NETSCAPE_SMIME)
+ X (CKO_NETSCAPE_TRUST)
+ X (CKO_NETSCAPE_BUILTIN_ROOT_LIST)
+ X (CKO_NETSCAPE_NEWSLOT)
+ X (CKO_NETSCAPE_DELSLOT)
+ #undef X
+ }
+
+ if (string != NULL)
+ p11_buffer_add (buffer, string, -1);
+ else
+ buffer_append_printf (buffer, "0x%08lX", klass);
+}
+
+static void
+format_assertion_type (p11_buffer *buffer,
+ CK_X_ASSERTION_TYPE type)
+{
+ const char *string = NULL;
+
+ switch (type) {
+ #define X(x) case x: string = #x; break;
+ X (CKT_X_DISTRUSTED_CERTIFICATE)
+ X (CKT_X_PINNED_CERTIFICATE)
+ X (CKT_X_ANCHORED_CERTIFICATE)
+ #undef X
+ }
+
+ if (string != NULL)
+ p11_buffer_add (buffer, string, -1);
+ else
+ buffer_append_printf (buffer, "0x%08lX", type);
+}
+
+static void
+format_key_type (p11_buffer *buffer,
+ CK_KEY_TYPE type)
+{
+ const char *string = NULL;
+
+ switch (type) {
+ #define X(x) case x: string = #x; break;
+ X (CKK_RSA)
+ X (CKK_DSA)
+ X (CKK_DH)
+ /* X (CKK_ECDSA) */
+ X (CKK_EC)
+ X (CKK_X9_42_DH)
+ X (CKK_KEA)
+ X (CKK_GENERIC_SECRET)
+ X (CKK_RC2)
+ X (CKK_RC4)
+ X (CKK_DES)
+ X (CKK_DES2)
+ X (CKK_DES3)
+ X (CKK_CAST)
+ X (CKK_CAST3)
+ X (CKK_CAST128)
+ X (CKK_RC5)
+ X (CKK_IDEA)
+ X (CKK_SKIPJACK)
+ X (CKK_BATON)
+ X (CKK_JUNIPER)
+ X (CKK_CDMF)
+ X (CKK_AES)
+ X (CKK_BLOWFISH)
+ X (CKK_TWOFISH)
+ X (CKK_NETSCAPE_PKCS8)
+ #undef X
+ }
+
+ if (string != NULL)
+ p11_buffer_add (buffer, string, -1);
+ else
+ buffer_append_printf (buffer, "0x%08lX", type);
+}
+
+static void
+format_certificate_type (p11_buffer *buffer,
+ CK_CERTIFICATE_TYPE type)
+{
+ const char *string = NULL;
+
+ switch (type) {
+ #define X(x) case x: string = #x; break;
+ X (CKC_X_509)
+ X (CKC_X_509_ATTR_CERT)
+ X (CKC_WTLS)
+ }
+
+ if (string != NULL)
+ p11_buffer_add (buffer, string, -1);
+ else
+ buffer_append_printf (buffer, "0x%08lX", type);
+}
+
+static void
+format_trust_value (p11_buffer *buffer,
+ CK_TRUST trust)
+{
+ const char *string = NULL;
+
+ switch (trust) {
+ #define X(x) case x: string = #x; break;
+ X (CKT_NETSCAPE_TRUSTED)
+ X (CKT_NETSCAPE_TRUSTED_DELEGATOR)
+ X (CKT_NETSCAPE_UNTRUSTED)
+ X (CKT_NETSCAPE_MUST_VERIFY)
+ X (CKT_NETSCAPE_TRUST_UNKNOWN)
+ }
+
+ if (string != NULL)
+ p11_buffer_add (buffer, string, -1);
+ else
+ buffer_append_printf (buffer, "0x%08lX", trust);
+}
+
+static void
+format_certificate_category (p11_buffer *buffer,
+ CK_ULONG category)
+{
+ const char *string = NULL;
+
+ switch (category) {
+ case 0:
+ string = "unspecified";
+ break;
+ case 1:
+ string = "token-user";
+ break;
+ case 2:
+ string = "authority";
+ break;
+ case 3:
+ string = "other-entry";
+ break;
+ }
+
+ if (string != NULL)
+ buffer_append_printf (buffer, "%lu (%s)", category, string);
+ else
+ buffer_append_printf (buffer, "%lu", category);
+}
+
+static void
+format_attribute_type (p11_buffer *buffer,
+ CK_ULONG type)
+{
+ const char *string = NULL;
+
+ switch (type) {
+ #define X(x) case x: string = #x; break;
+ X (CKA_CLASS)
+ X (CKA_TOKEN)
+ X (CKA_PRIVATE)
+ X (CKA_LABEL)
+ X (CKA_APPLICATION)
+ X (CKA_VALUE)
+ X (CKA_OBJECT_ID)
+ X (CKA_CERTIFICATE_TYPE)
+ X (CKA_ISSUER)
+ X (CKA_SERIAL_NUMBER)
+ X (CKA_AC_ISSUER)
+ X (CKA_OWNER)
+ X (CKA_ATTR_TYPES)
+ X (CKA_TRUSTED)
+ X (CKA_CERTIFICATE_CATEGORY)
+ X (CKA_JAVA_MIDP_SECURITY_DOMAIN)
+ X (CKA_URL)
+ X (CKA_HASH_OF_SUBJECT_PUBLIC_KEY)
+ X (CKA_HASH_OF_ISSUER_PUBLIC_KEY)
+ X (CKA_CHECK_VALUE)
+ X (CKA_KEY_TYPE)
+ X (CKA_SUBJECT)
+ X (CKA_ID)
+ X (CKA_SENSITIVE)
+ X (CKA_ENCRYPT)
+ X (CKA_DECRYPT)
+ X (CKA_WRAP)
+ X (CKA_UNWRAP)
+ X (CKA_SIGN)
+ X (CKA_SIGN_RECOVER)
+ X (CKA_VERIFY)
+ X (CKA_VERIFY_RECOVER)
+ X (CKA_DERIVE)
+ X (CKA_START_DATE)
+ X (CKA_END_DATE)
+ X (CKA_MODULUS)
+ X (CKA_MODULUS_BITS)
+ X (CKA_PUBLIC_EXPONENT)
+ X (CKA_PRIVATE_EXPONENT)
+ X (CKA_PRIME_1)
+ X (CKA_PRIME_2)
+ X (CKA_EXPONENT_1)
+ X (CKA_EXPONENT_2)
+ X (CKA_COEFFICIENT)
+ X (CKA_PRIME)
+ X (CKA_SUBPRIME)
+ X (CKA_BASE)
+ X (CKA_PRIME_BITS)
+ /* X (CKA_SUBPRIME_BITS) */
+ /* X (CKA_SUB_PRIME_BITS) */
+ X (CKA_VALUE_BITS)
+ X (CKA_VALUE_LEN)
+ X (CKA_EXTRACTABLE)
+ X (CKA_LOCAL)
+ X (CKA_NEVER_EXTRACTABLE)
+ X (CKA_ALWAYS_SENSITIVE)
+ X (CKA_KEY_GEN_MECHANISM)
+ X (CKA_MODIFIABLE)
+ X (CKA_ECDSA_PARAMS)
+ /* X (CKA_EC_PARAMS) */
+ X (CKA_EC_POINT)
+ X (CKA_SECONDARY_AUTH)
+ X (CKA_AUTH_PIN_FLAGS)
+ X (CKA_ALWAYS_AUTHENTICATE)
+ X (CKA_WRAP_WITH_TRUSTED)
+ X (CKA_WRAP_TEMPLATE)
+ X (CKA_UNWRAP_TEMPLATE)
+ X (CKA_HW_FEATURE_TYPE)
+ X (CKA_RESET_ON_INIT)
+ X (CKA_HAS_RESET)
+ X (CKA_PIXEL_X)
+ X (CKA_PIXEL_Y)
+ X (CKA_RESOLUTION)
+ X (CKA_CHAR_ROWS)
+ X (CKA_CHAR_COLUMNS)
+ X (CKA_COLOR)
+ X (CKA_BITS_PER_PIXEL)
+ X (CKA_CHAR_SETS)
+ X (CKA_ENCODING_METHODS)
+ X (CKA_MIME_TYPES)
+ X (CKA_MECHANISM_TYPE)
+ X (CKA_REQUIRED_CMS_ATTRIBUTES)
+ X (CKA_DEFAULT_CMS_ATTRIBUTES)
+ X (CKA_SUPPORTED_CMS_ATTRIBUTES)
+ X (CKA_ALLOWED_MECHANISMS)
+ X (CKA_X_ASSERTION_TYPE)
+ X (CKA_X_CERTIFICATE_VALUE)
+ X (CKA_X_PURPOSE)
+ X (CKA_X_PEER)
+ X (CKA_X_DISTRUSTED)
+ X (CKA_X_CRITICAL)
+ X (CKA_NETSCAPE_URL)
+ X (CKA_NETSCAPE_EMAIL)
+ X (CKA_NETSCAPE_SMIME_INFO)
+ X (CKA_NETSCAPE_SMIME_TIMESTAMP)
+ X (CKA_NETSCAPE_PKCS8_SALT)
+ X (CKA_NETSCAPE_PASSWORD_CHECK)
+ X (CKA_NETSCAPE_EXPIRES)
+ X (CKA_NETSCAPE_KRL)
+ X (CKA_NETSCAPE_PQG_COUNTER)
+ X (CKA_NETSCAPE_PQG_SEED)
+ X (CKA_NETSCAPE_PQG_H)
+ X (CKA_NETSCAPE_PQG_SEED_BITS)
+ X (CKA_NETSCAPE_MODULE_SPEC)
+ X (CKA_TRUST_DIGITAL_SIGNATURE)
+ X (CKA_TRUST_NON_REPUDIATION)
+ X (CKA_TRUST_KEY_ENCIPHERMENT)
+ X (CKA_TRUST_DATA_ENCIPHERMENT)
+ X (CKA_TRUST_KEY_AGREEMENT)
+ X (CKA_TRUST_KEY_CERT_SIGN)
+ X (CKA_TRUST_CRL_SIGN)
+ X (CKA_TRUST_SERVER_AUTH)
+ X (CKA_TRUST_CLIENT_AUTH)
+ X (CKA_TRUST_CODE_SIGNING)
+ X (CKA_TRUST_EMAIL_PROTECTION)
+ X (CKA_TRUST_IPSEC_END_SYSTEM)
+ X (CKA_TRUST_IPSEC_TUNNEL)
+ X (CKA_TRUST_IPSEC_USER)
+ X (CKA_TRUST_TIME_STAMPING)
+ X (CKA_TRUST_STEP_UP_APPROVED)
+ X (CKA_CERT_SHA1_HASH)
+ X (CKA_CERT_MD5_HASH)
+ #undef X
+ }
+
+ if (string != NULL)
+ p11_buffer_add (buffer, string, -1);
+ else
+ buffer_append_printf (buffer, "CKA_0x%08lX", type);
+}
+
+static void
+format_some_bytes (p11_buffer *buffer,
+ void *bytes,
+ CK_ULONG length)
+{
+ unsigned char ch;
+ const unsigned char *data = bytes;
+ CK_ULONG i;
+
+ if (bytes == NULL) {
+ p11_buffer_add (buffer, "NULL", -1);
+ return;
+ }
+
+ p11_buffer_add (buffer, "\"", 1);
+ for (i = 0; i < length && i < 128; i++) {
+ ch = data[i];
+ if (ch == '\t')
+ p11_buffer_add (buffer, "\\t", -1);
+ else if (ch == '\n')
+ p11_buffer_add (buffer, "\\n", -1);
+ else if (ch == '\r')
+ p11_buffer_add (buffer, "\\r", -1);
+ else if (ch >= 32 && ch < 127)
+ p11_buffer_add (buffer, &ch, 1);
+ else
+ buffer_append_printf (buffer, "\\x%02x", ch);
+ }
+
+ if (i < length)
+ buffer_append_printf (buffer, "...");
+ p11_buffer_add (buffer, "\"", 1);
+}
+
+static void
+format_attribute (p11_buffer *buffer,
+ const CK_ATTRIBUTE *attr)
+{
+ p11_buffer_add (buffer, "{ ", -1);
+ format_attribute_type (buffer, attr->type);
+ p11_buffer_add (buffer, " = ", -1);
+ if (attr->ulValueLen == CKA_INVALID) {
+ buffer_append_printf (buffer, "(-1) INVALID");
+ } else if (attribute_is_ulong_of_type (attr, CKA_CLASS)) {
+ format_class (buffer, *((CK_OBJECT_CLASS *)attr->pValue));
+ } else if (attribute_is_ulong_of_type (attr, CKA_X_ASSERTION_TYPE)) {
+ format_assertion_type (buffer, *((CK_X_ASSERTION_TYPE *)attr->pValue));
+ } else if (attribute_is_ulong_of_type (attr, CKA_CERTIFICATE_TYPE)) {
+ format_certificate_type (buffer, *((CK_CERTIFICATE_TYPE *)attr->pValue));
+ } else if (attribute_is_ulong_of_type (attr, CKA_CERTIFICATE_CATEGORY)) {
+ format_certificate_category (buffer, *((CK_ULONG *)attr->pValue));
+ } else if (attribute_is_ulong_of_type (attr, CKA_KEY_TYPE)) {
+ format_key_type (buffer, *((CK_KEY_TYPE *)attr->pValue));
+ } else if (attribute_is_trust_value (attr)) {
+ format_trust_value (buffer, *((CK_TRUST *)attr->pValue));
+ } else if (attribute_is_sensitive (attr)) {
+ buffer_append_printf (buffer, "(%lu) NOT-PRINTED", attr->ulValueLen);
+ } else {
+ buffer_append_printf (buffer, "(%lu) ", attr->ulValueLen);
+ format_some_bytes (buffer, attr->pValue, attr->ulValueLen);
+ }
+ p11_buffer_add (buffer, " }", -1);
+}
+
+static void
+format_attributes (p11_buffer *buffer,
+ const CK_ATTRIBUTE *attrs)
+{
+ CK_BBOOL first = CK_TRUE;
+ int count, i;
+
+ count = p11_attrs_count (attrs);
+ buffer_append_printf (buffer, "(%d) [", count);
+ for (i = 0; i < count; i++) {
+ if (first)
+ p11_buffer_add (buffer, " ", 1);
+ else
+ p11_buffer_add (buffer, ", ", 2);
+ first = CK_FALSE;
+ format_attribute (buffer, attrs + i);
+ }
+ p11_buffer_add (buffer, " ]", -1);
}
-CK_BBOOL
-p11_attr_match_boolean (CK_ATTRIBUTE *attr,
- CK_BBOOL value)
+char *
+p11_attrs_to_string (const CK_ATTRIBUTE *attrs)
{
- return (attr->ulValueLen == sizeof (value) &&
- attr->pValue != NULL &&
- memcmp (attr->pValue, &value, sizeof (value)) == 0);
+ p11_buffer buffer;
+ if (!p11_buffer_init_null (&buffer, 128))
+ return_val_if_reached (NULL);
+ format_attributes (&buffer, attrs);
+ return p11_buffer_steal (&buffer, NULL);
}
-CK_BBOOL
-p11_attr_equal (CK_ATTRIBUTE *one,
- CK_ATTRIBUTE *two)
+char *
+p11_attr_to_string (const CK_ATTRIBUTE *attr)
{
- if (one == two)
- return CK_TRUE;
- if (!one || !two || one->type != two->type || one->ulValueLen != two->ulValueLen)
- return CK_FALSE;
- if (one->pValue == two->pValue)
- return TRUE;
- if (!one->pValue || !two->pValue)
- return FALSE;
- return memcmp (one->pValue, two->pValue, one->ulValueLen) == 0;
+ p11_buffer buffer;
+ if (!p11_buffer_init_null (&buffer, 32))
+ return_val_if_reached (NULL);
+ format_attribute (&buffer, attr);
+ return p11_buffer_steal (&buffer, NULL);
}
diff --git a/common/attrs.h b/common/attrs.h
index 12a2798..870f0d1 100644
--- a/common/attrs.h
+++ b/common/attrs.h
@@ -36,17 +36,18 @@
#ifndef P11_ATTRS_H_
#define P11_ATTRS_H_
+#include "compat.h"
#include "pkcs11.h"
#define CKA_INVALID ((CK_ULONG)-1)
-CK_ATTRIBUTE * p11_attrs_dup (CK_ATTRIBUTE *attrs);
+CK_ATTRIBUTE * p11_attrs_dup (const CK_ATTRIBUTE *attrs);
CK_ATTRIBUTE * p11_attrs_build (CK_ATTRIBUTE *attrs,
...);
CK_ATTRIBUTE * p11_attrs_buildn (CK_ATTRIBUTE *attrs,
- CK_ATTRIBUTE *add,
+ const CK_ATTRIBUTE *add,
CK_ULONG count);
CK_ATTRIBUTE * p11_attrs_take (CK_ATTRIBUTE *attrs,
@@ -54,9 +55,9 @@ CK_ATTRIBUTE * p11_attrs_take (CK_ATTRIBUTE *attrs,
CK_VOID_PTR value,
CK_ULONG length);
-CK_BBOOL p11_attrs_is_empty (CK_ATTRIBUTE *attrs);
+bool p11_attrs_is_empty (const CK_ATTRIBUTE *attrs);
-CK_ULONG p11_attrs_count (CK_ATTRIBUTE *attrs);
+CK_ULONG p11_attrs_count (const CK_ATTRIBUTE *attrs);
void p11_attrs_free (void *attrs);
@@ -67,20 +68,52 @@ CK_ATTRIBUTE * p11_attrs_findn (CK_ATTRIBUTE *attrs,
CK_ULONG count,
CK_ATTRIBUTE_TYPE type);
-CK_BBOOL p11_attrs_remove (CK_ATTRIBUTE *attrs,
+bool p11_attrs_find_bool (CK_ATTRIBUTE *attrs,
+ CK_ATTRIBUTE_TYPE type,
+ CK_BBOOL *value);
+
+bool p11_attrs_findn_bool (CK_ATTRIBUTE *attrs,
+ CK_ULONG count,
+ CK_ATTRIBUTE_TYPE type,
+ CK_BBOOL *value);
+
+bool p11_attrs_find_ulong (CK_ATTRIBUTE *attrs,
+ CK_ATTRIBUTE_TYPE type,
+ CK_ULONG *value);
+
+bool p11_attrs_findn_ulong (CK_ATTRIBUTE *attrs,
+ CK_ULONG count,
+ CK_ATTRIBUTE_TYPE type,
+ CK_ULONG *value);
+
+CK_ATTRIBUTE * p11_attrs_find_valid (CK_ATTRIBUTE *attrs,
CK_ATTRIBUTE_TYPE type);
-CK_BBOOL p11_attrs_match (CK_ATTRIBUTE *attrs,
- CK_ATTRIBUTE *match);
+CK_ATTRIBUTE * p11_attrs_findn_valid (CK_ATTRIBUTE *attrs,
+ CK_ULONG count,
+ CK_ATTRIBUTE_TYPE type);
+
+bool p11_attrs_remove (CK_ATTRIBUTE *attrs,
+ CK_ATTRIBUTE_TYPE type);
-CK_BBOOL p11_attrs_matchn (CK_ATTRIBUTE *attrs,
- CK_ATTRIBUTE *match,
+bool p11_attrs_match (const CK_ATTRIBUTE *attrs,
+ const CK_ATTRIBUTE *match);
+
+bool p11_attrs_matchn (const CK_ATTRIBUTE *attrs,
+ const CK_ATTRIBUTE *match,
CK_ULONG count);
-CK_BBOOL p11_attr_equal (CK_ATTRIBUTE *one,
- CK_ATTRIBUTE *two);
+char * p11_attrs_to_string (const CK_ATTRIBUTE *attrs);
+
+char * p11_attr_to_string (const CK_ATTRIBUTE *attr);
+
+bool p11_attr_equal (const void *one,
+ const void *two);
+
+unsigned int p11_attr_hash (const void *data);
-CK_BBOOL p11_attr_match_boolean (CK_ATTRIBUTE *attr,
- CK_BBOOL value);
+bool p11_attr_match_value (const CK_ATTRIBUTE *attr,
+ const void *value,
+ ssize_t length);
#endif /* P11_ATTRS_H_ */
diff --git a/common/tests/test-attrs.c b/common/tests/test-attrs.c
index 445695f..ccbb801 100644
--- a/common/tests/test-attrs.c
+++ b/common/tests/test-attrs.c
@@ -319,6 +319,52 @@ test_equal (CuTest *tc)
}
static void
+test_hash (CuTest *tc)
+{
+ char *data = "extra attribute";
+ CK_ATTRIBUTE one = { CKA_LABEL, "yay", 3 };
+ CK_ATTRIBUTE null = { CKA_LABEL, NULL, 3 };
+ CK_ATTRIBUTE two = { CKA_VALUE, "yay", 3 };
+ CK_ATTRIBUTE other = { CKA_VALUE, data, 5 };
+ CK_ATTRIBUTE overflow = { CKA_VALUE, data, 5 };
+ CK_ATTRIBUTE content = { CKA_VALUE, "conte", 5 };
+ unsigned int hash;
+
+ hash = p11_attr_hash (&one);
+ CuAssertTrue (tc, hash != 0);
+
+ CuAssertTrue (tc, p11_attr_hash (&one) == hash);
+ CuAssertTrue (tc, p11_attr_hash (&two) != hash);
+ CuAssertTrue (tc, p11_attr_hash (&other) != hash);
+ CuAssertTrue (tc, p11_attr_hash (&overflow) != hash);
+ CuAssertTrue (tc, p11_attr_hash (&null) != hash);
+ CuAssertTrue (tc, p11_attr_hash (&content) != hash);
+}
+
+static void
+test_to_string (CuTest *tc)
+{
+ char *data = "extra attribute";
+ CK_ATTRIBUTE one = { CKA_LABEL, "yay", 3 };
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_LABEL, "yay", 3 },
+ { CKA_VALUE, data, 5 },
+ { CKA_INVALID },
+ };
+
+ char *string;
+
+
+ string = p11_attr_to_string (&one);
+ CuAssertStrEquals (tc, "{ CKA_LABEL = (3) \"yay\" }", string);
+ free (string);
+
+ string = p11_attrs_to_string (attrs);
+ CuAssertStrEquals (tc, "(2) [ { CKA_LABEL = (3) \"yay\" }, { CKA_VALUE = (5) NOT-PRINTED } ]", string);
+ free (string);
+}
+
+static void
test_find (CuTest *tc)
{
CK_BBOOL vtrue = CK_TRUE;
@@ -461,23 +507,65 @@ test_matchn (CuTest *tc)
}
static void
-test_match_boolean (CuTest *tc)
+test_find_bool (CuTest *tc)
{
CK_BBOOL vtrue = CK_TRUE;
CK_BBOOL vfalse = CK_FALSE;
- CK_ATTRIBUTE one = { CKA_LABEL, "\x01yy", 3 };
- CK_ATTRIBUTE two = { CKA_LABEL, "\x00yy", 3 };
- CK_ATTRIBUTE atrue = { CKA_TOKEN, &vtrue, sizeof (CK_BBOOL) };
- CK_ATTRIBUTE afalse = { CKA_TOKEN, &vfalse, sizeof (CK_BBOOL) };
-
- CuAssertTrue (tc, p11_attr_match_boolean (&atrue, CK_TRUE));
- CuAssertTrue (tc, !p11_attr_match_boolean (&atrue, CK_FALSE));
- CuAssertTrue (tc, p11_attr_match_boolean (&afalse, CK_FALSE));
- CuAssertTrue (tc, !p11_attr_match_boolean (&afalse, CK_TRUE));
- CuAssertTrue (tc, !p11_attr_match_boolean (&one, CK_TRUE));
- CuAssertTrue (tc, !p11_attr_match_boolean (&one, CK_FALSE));
- CuAssertTrue (tc, !p11_attr_match_boolean (&two, CK_FALSE));
- CuAssertTrue (tc, !p11_attr_match_boolean (&two, CK_TRUE));
+ CK_BBOOL value;
+
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_LABEL, "\x01yy", 3 },
+ { CKA_VALUE, &vtrue, (CK_ULONG)-1 },
+ { CKA_TOKEN, &vtrue, sizeof (CK_BBOOL) },
+ { CKA_TOKEN, &vfalse, sizeof (CK_BBOOL) },
+ { CKA_INVALID },
+ };
+
+ CuAssertTrue (tc, p11_attrs_find_bool (attrs, CKA_TOKEN, &value) && value == CK_TRUE);
+ CuAssertTrue (tc, !p11_attrs_find_bool (attrs, CKA_LABEL, &value));
+ CuAssertTrue (tc, !p11_attrs_find_bool (attrs, CKA_VALUE, &value));
+}
+
+static void
+test_find_ulong (CuTest *tc)
+{
+ CK_ULONG v33 = 33UL;
+ CK_ULONG v45 = 45UL;
+ CK_ULONG value;
+
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_LABEL, &v33, 2 },
+ { CKA_VALUE, &v45, (CK_ULONG)-1 },
+ { CKA_BITS_PER_PIXEL, &v33, sizeof (CK_ULONG) },
+ { CKA_BITS_PER_PIXEL, &v45, sizeof (CK_ULONG) },
+ { CKA_INVALID },
+ };
+
+ CuAssertTrue (tc, p11_attrs_find_ulong (attrs, CKA_BITS_PER_PIXEL, &value) && value == v33);
+ CuAssertTrue (tc, !p11_attrs_find_ulong (attrs, CKA_LABEL, &value));
+ CuAssertTrue (tc, !p11_attrs_find_ulong (attrs, CKA_VALUE, &value));
+}
+
+static void
+test_find_valid (CuTest *tc)
+{
+ CK_ATTRIBUTE *attr;
+
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_LABEL, "", (CK_ULONG)-1 },
+ { CKA_LABEL, "test", 4 },
+ { CKA_VALUE, NULL, 0 },
+ { CKA_INVALID },
+ };
+
+ attr = p11_attrs_find_valid (attrs, CKA_LABEL);
+ CuAssertPtrEquals (tc, attrs + 1, attr);
+
+ attr = p11_attrs_find_valid (attrs, CKA_VALUE);
+ CuAssertPtrEquals (tc, attrs + 2, attr);
+
+ attr = p11_attrs_find_valid (attrs, CKA_TOKEN);
+ CuAssertPtrEquals (tc, NULL, attr);
}
int
@@ -490,6 +578,10 @@ main (void)
setenv ("P11_KIT_STRICT", "1", 1);
p11_debug_init ();
+ SUITE_ADD_TEST (suite, test_equal);
+ SUITE_ADD_TEST (suite, test_hash);
+ SUITE_ADD_TEST (suite, test_to_string);
+
SUITE_ADD_TEST (suite, test_count);
SUITE_ADD_TEST (suite, test_build_one);
SUITE_ADD_TEST (suite, test_build_two);
@@ -505,11 +597,11 @@ main (void)
SUITE_ADD_TEST (suite, test_matchn);
SUITE_ADD_TEST (suite, test_find);
SUITE_ADD_TEST (suite, test_findn);
+ SUITE_ADD_TEST (suite, test_find_bool);
+ SUITE_ADD_TEST (suite, test_find_ulong);
+ SUITE_ADD_TEST (suite, test_find_valid);
SUITE_ADD_TEST (suite, test_remove);
- SUITE_ADD_TEST (suite, test_match_boolean);
- SUITE_ADD_TEST (suite, test_equal);
-
CuSuiteRun (suite);
CuSuiteSummary (suite, output);
CuSuiteDetails (suite, output);