diff options
| -rw-r--r-- | common/attrs.c | 795 | ||||
| -rw-r--r-- | common/attrs.h | 59 | ||||
| -rw-r--r-- | common/tests/test-attrs.c | 126 | 
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); | 
