From b24ea47f610ab16fc14d9deee22cc68b7d3be214 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Sat, 14 May 2016 16:23:51 -0400 Subject: Key flag handling, more trailing whitespace cleanup. At this point we are passing most of the unit tests in RPC loopback mode. Remaining failure is TestKeys.test_keygen_token_vs_session(), which gets HAL_ERROR_KEY_NAME_IN_USE when attempting to generate a session key and a token key with the same CKA_ID value, so clearly something is not quite right yet in the keystore selection logic. --- GNUmakefile | 2 +- pkcs11.c | 133 ++++++++++++++++++++++++++++----------------------- scripts/py11-test.py | 6 +-- 3 files changed, 78 insertions(+), 63 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 71ca871..07eb372 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -62,7 +62,7 @@ SOFLAGS := -Wl,-Bsymbolic-functions -Wl,-Bsymbolic -Wl,-z,noexecstack LIBS := ${LIBHAL_DIR}/libhal.a ${LIBTFM_DIR}/libtfm.a ${SQLITE3_DIR}/libsqlite3.a ifeq "${ENABLE_FOOTNOTE_WARNINGS}" "no" - CFLAGS += -Wno-\#warnings + CFLAGS += -Wno-\#warnings -Wno-cpp endif ifeq "${ENABLE_THREADS}" "yes" diff --git a/pkcs11.c b/pkcs11.c index 6ed7bc3..b5878e5 100644 --- a/pkcs11.c +++ b/pkcs11.c @@ -254,19 +254,19 @@ static pid_t initialized_pid; #if DEBUG_PKCS11 -#define lose(_ck_rv_code_) \ - do { \ - rv = (_ck_rv_code_); \ - fprintf(stderr, "%s:%u: %s\n", __FILE__, __LINE__, #_ck_rv_code_); \ - goto fail; \ +#define lose(_ck_rv_code_) \ + do { \ + rv = (_ck_rv_code_); \ + fprintf(stderr, "\n%s:%u: %s\n", __FILE__, __LINE__, #_ck_rv_code_); \ + goto fail; \ } while (0) #else /* DEBUG_PKCS11 */ -#define lose(_ck_rv_code_) \ - do { \ - rv = (_ck_rv_code_); \ - goto fail; \ +#define lose(_ck_rv_code_) \ + do { \ + rv = (_ck_rv_code_); \ + goto fail; \ } while (0) #endif /* DEBUG_PKCS11 */ @@ -280,7 +280,7 @@ static pid_t initialized_pid; #if DEBUG_PKCS11 > 1 #define ENTER_PUBLIC_FUNCTION(_name_) \ - fprintf(stderr, "Entering function %s\n", #_name_) + fprintf(stderr, "\nEntering function %s\n", #_name_) #else /* DEBUG_PKCS11 > 1 */ @@ -298,7 +298,7 @@ static int _hal_check(const hal_error_t err, const char * const expr, const char { if (err == HAL_OK) return 1; - fprintf(stderr, "%s:%u: %s returned %s\n", file, line, expr, hal_error_string(err)); + fprintf(stderr, "\n%s:%u: %s returned %s\n", file, line, expr, hal_error_string(err)); return 0; } @@ -346,7 +346,7 @@ static sqlite3 *sqldb = NULL; #if DEBUG_SQL #define sql_whine(_expr_) \ - (fprintf(stderr, "%s:%u: %s returned %s\n", \ + (fprintf(stderr, "\n%s:%u: %s returned %s\n", \ __FILE__, __LINE__, #_expr_, sqlite3_errmsg(sqldb)), \ sql_breakpoint()) @@ -372,7 +372,7 @@ static sqlite3 *sqldb = NULL; #if DEBUG_SQL static void sql_breakpoint(void) { - fprintf(stderr, "[sql_breakpoint]\n"); + fprintf(stderr, "\n[sql_breakpoint]\n"); } #endif @@ -389,7 +389,7 @@ static int sql_exec(const char *cmd) #if DEBUG_SQL if (msg != NULL) - fprintf(stderr, "[%s]\n", msg); + fprintf(stderr, "\n[%s]\n", msg); #endif return 0; @@ -971,15 +971,12 @@ static void *p11_attribute_find_value_in_template(const CK_ATTRIBUTE_TYPE type, * after the default and mandatory values have been merged into the * values supplied by the application-supplied template. * - * Semantics of the flags follow RFC 5280 4.2.1.3, numeric values - * don't matter particularly as we only use them internally. + * Semantics of the flags follow RFC 5280 4.2.1.3. Numeric values + * don't matter particularly as we only use them internally so we + * can simplify things a bit by reusing libhal's flag values. */ -#define KEYUSAGE_DIGITALSIGNATURE (1 << 0) -#define KEYUSAGE_KEYENCIPHERMENT (1 << 1) -#define KEYUSAGE_DATAENCIPHERMENT (1 << 2) - -static void p11_attribute_apply_keyusage(unsigned *keyusage, const CK_ATTRIBUTE_TYPE type, const CK_BBOOL *value) +static void p11_attribute_apply_keyusage(hal_key_flags_t *keyusage, const CK_ATTRIBUTE_TYPE type, const CK_BBOOL *value) { unsigned flag; @@ -988,15 +985,15 @@ static void p11_attribute_apply_keyusage(unsigned *keyusage, const CK_ATTRIBUTE_ switch (type) { case CKA_SIGN: /* Generate signature */ case CKA_VERIFY: /* Verify signature */ - flag = KEYUSAGE_DIGITALSIGNATURE; + flag = HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE; break; case CKA_ENCRYPT: /* Encrypt bulk data (seldom used) */ case CKA_DECRYPT: /* Bulk decryption (seldom used) */ - flag = KEYUSAGE_DATAENCIPHERMENT; + flag = HAL_KEY_FLAG_USAGE_DATAENCIPHERMENT; break; case CKA_WRAP: /* Wrap key (normal way of doing encryption) */ case CKA_UNWRAP: /* Unwrap key (normal way of doing decryption) */ - flag = KEYUSAGE_KEYENCIPHERMENT; + flag = HAL_KEY_FLAG_USAGE_KEYENCIPHERMENT; break; default: return; /* Attribute not related to key usage */ @@ -1365,7 +1362,7 @@ static int p11_object_pkey_type(const CK_OBJECT_HANDLE object_handle, if (!p11_attribute_get_ulong(object_handle, CKA_CLASS, &cka_class) || !p11_attribute_get_ulong(object_handle, CKA_KEY_TYPE, &cka_key_type)) return 0; - + else if (cka_class == CKO_PRIVATE_KEY && cka_key_type == CKK_RSA) *pkey_type = HAL_KEY_TYPE_RSA_PRIVATE; @@ -1394,9 +1391,11 @@ static int p11_object_pkey_type(const CK_OBJECT_HANDLE object_handle, * Fetch the libhal pkey handle for a key object. */ +#warning Should do something about key usage flags in p11_object_get_*_public_key() + static inline int p11_object_get_rsa_public_key(const p11_session_t * const session, const CK_OBJECT_HANDLE object_handle, - hal_pkey_handle_t *pkey_handle, + hal_pkey_handle_t *pkey_handle, const char *flavor, const uint8_t * const name, const size_t name_len, const hal_key_flags_t flags) @@ -1814,14 +1813,14 @@ static CK_RV p11_template_check_1(const CK_ATTRIBUTE_TYPE type, if (atd->value != NULL && (atd->flags & P11_DESCRIPTOR_DEFAULT_VALUE) == 0 && memcmp(val, atd->value, atd->length) != 0) lose(CKR_TEMPLATE_INCONSISTENT); -#warning Add _LATCH checks here? +#warning Add _LATCH checks here? rv = CKR_OK; fail: #if DEBUG_PKCS11 if (rv != CKR_OK) - fprintf(stderr, "p11_template_check_1() rejected attribute 0x%08lx\n", (unsigned long) type); + fprintf(stderr, "\np11_template_check_1() rejected attribute 0x%08lx\n", (unsigned long) type); #endif return rv; } @@ -1875,7 +1874,7 @@ static CK_RV p11_template_check_2(const p11_session_t *session, /* Required attribute missing from template */ if (!forbidden_by_api && (required_by_api || !in_descriptor) && pos_in_template < 0) { #if DEBUG_PKCS11 - fprintf(stderr, "[Missing attribute 0x%lx]\n", atd->type); + fprintf(stderr, "\n[Missing attribute 0x%lx]\n", atd->type); #endif lose(CKR_TEMPLATE_INCOMPLETE); } @@ -1907,17 +1906,20 @@ static CK_RV p11_check_keypair_attributes(const p11_session_t *session, const CK_ATTRIBUTE_PTR pPublicKeyTemplate, const CK_ULONG ulPublicKeyAttributeCount, const p11_descriptor_t * const public_descriptor, + hal_key_flags_t *public_flags, const CK_ATTRIBUTE_PTR pPrivateKeyTemplate, const CK_ULONG ulPrivateKeyAttributeCount, - const p11_descriptor_t * const private_descriptor) + const p11_descriptor_t * const private_descriptor, + hal_key_flags_t *private_flags) { - unsigned public_keyusage = 0, private_keyusage = 0; CK_RV rv = CKR_OK; int i; assert(session != NULL && - pPublicKeyTemplate != NULL && public_descriptor != NULL && - pPrivateKeyTemplate != NULL && private_descriptor != NULL); + pPublicKeyTemplate != NULL && public_descriptor != NULL && public_flags != NULL && + pPrivateKeyTemplate != NULL && private_descriptor != NULL && private_flags != NULL); + + *public_flags = *private_flags = 0; /* * Read-only sessions can't create keys, doh. @@ -1942,7 +1944,7 @@ static CK_RV p11_check_keypair_attributes(const p11_session_t *session, P11_DESCRIPTOR_FORBIDDEN_BY_GENERATE)) != CKR_OK) goto fail; - p11_attribute_apply_keyusage(&public_keyusage, type, val); + p11_attribute_apply_keyusage(public_flags, type, val); } for (i = 0; i < ulPrivateKeyAttributeCount; i++) { @@ -1954,7 +1956,7 @@ static CK_RV p11_check_keypair_attributes(const p11_session_t *session, P11_DESCRIPTOR_FORBIDDEN_BY_GENERATE)) != CKR_OK) goto fail; - p11_attribute_apply_keyusage(&private_keyusage, type, val); + p11_attribute_apply_keyusage(private_flags, type, val); } /* @@ -1962,7 +1964,7 @@ static CK_RV p11_check_keypair_attributes(const p11_session_t *session, * key, and that they match. May not need to be this strict. */ - if (public_keyusage != private_keyusage || public_keyusage == 0) + if (*public_flags != *private_flags || *public_flags == 0) lose(CKR_TEMPLATE_INCONSISTENT); /* @@ -2000,10 +2002,12 @@ static CK_RV p11_check_keypair_attributes(const p11_session_t *session, static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session, const CK_ATTRIBUTE_PTR pPublicKeyTemplate, const CK_ULONG ulPublicKeyAttributeCount, + const CK_OBJECT_HANDLE public_handle, + const hal_key_flags_t public_flags, const CK_ATTRIBUTE_PTR pPrivateKeyTemplate, const CK_ULONG ulPrivateKeyAttributeCount, const CK_OBJECT_HANDLE private_handle, - const CK_OBJECT_HANDLE public_handle, + const hal_key_flags_t private_flags, const uint8_t * const id, const size_t id_len) { const uint8_t *public_exponent = const_0x010001; @@ -2038,12 +2042,11 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session, if (keysize == 0 || id == NULL) return CKR_TEMPLATE_INCOMPLETE; -#warning Should do something here with pkey flags - if (!hal_check(hal_rpc_pkey_generate_rsa(p11_session_hal_client(session), p11_session_hal_session(session), &pkey, id, id_len, keysize, - public_exponent, public_exponent_len, 0))) + public_exponent, public_exponent_len, + private_flags))) lose(CKR_FUNCTION_FAILED); { @@ -2078,10 +2081,12 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session, static CK_RV generate_keypair_ec(p11_session_t *session, const CK_ATTRIBUTE_PTR pPublicKeyTemplate, const CK_ULONG ulPublicKeyAttributeCount, + const CK_OBJECT_HANDLE public_handle, + const hal_key_flags_t public_flags, const CK_ATTRIBUTE_PTR pPrivateKeyTemplate, const CK_ULONG ulPrivateKeyAttributeCount, const CK_OBJECT_HANDLE private_handle, - const CK_OBJECT_HANDLE public_handle, + const hal_key_flags_t private_flags, const uint8_t * const id, const size_t id_len) { hal_pkey_handle_t pkey = {HAL_HANDLE_NONE}; @@ -2112,7 +2117,8 @@ static CK_RV generate_keypair_ec(p11_session_t *session, if (!hal_check(hal_rpc_pkey_generate_ec(p11_session_hal_client(session), p11_session_hal_session(session), - &pkey, id, id_len, curve, 0)) || + &pkey, id, id_len, curve, + private_flags)) || !p11_attribute_set(public_handle, CKA_EC_PARAMS, params, params_len) || !p11_attribute_set(private_handle, CKA_EC_PARAMS, params, params_len)) lose(CKR_FUNCTION_FAILED); @@ -2156,10 +2162,12 @@ static CK_RV generate_keypair(p11_session_t *session, CK_RV (*mechanism_handler)(p11_session_t *session, const CK_ATTRIBUTE_PTR pPublicKeyTemplate, const CK_ULONG ulPublicKeyAttributeCount, + const CK_OBJECT_HANDLE public_handle, + const hal_key_flags_t public_flags, const CK_ATTRIBUTE_PTR pPrivateKeyTemplate, const CK_ULONG ulPrivateKeyAttributeCount, const CK_OBJECT_HANDLE private_handle, - const CK_OBJECT_HANDLE public_handle, + const hal_key_flags_t private_flags, const uint8_t * const id, const size_t id_len), const p11_descriptor_t * const public_descriptor, const p11_descriptor_t * const private_descriptor) @@ -2168,12 +2176,14 @@ static CK_RV generate_keypair(p11_session_t *session, CK_OBJECT_HANDLE public_handle = CK_INVALID_HANDLE; handle_flavor_t public_handle_flavor = handle_flavor_session_object; handle_flavor_t private_handle_flavor = handle_flavor_session_object; + hal_key_flags_t public_flags = 0; + hal_key_flags_t private_flags = 0; CK_RV rv; int i; rv = p11_check_keypair_attributes(session, - pPublicKeyTemplate, ulPublicKeyAttributeCount, public_descriptor, - pPrivateKeyTemplate, ulPrivateKeyAttributeCount, private_descriptor); + pPublicKeyTemplate, ulPublicKeyAttributeCount, public_descriptor, &public_flags, + pPrivateKeyTemplate, ulPrivateKeyAttributeCount, private_descriptor, &private_flags); if (rv != CKR_OK) return rv; @@ -2189,6 +2199,12 @@ static CK_RV generate_keypair(p11_session_t *session, if (pPrivateKeyTemplate[i].type == CKA_TOKEN) private_handle_flavor = p11_handle_flavor_from_cka_token(pPrivateKeyTemplate[i].pValue); + if (public_handle_flavor == handle_flavor_session_object) + public_flags |= HAL_KEY_FLAG_PROXIMATE; + + if (private_handle_flavor == handle_flavor_session_object) + private_flags |= HAL_KEY_FLAG_PROXIMATE; + if (!sql_exec("BEGIN")) lose(CKR_FUNCTION_FAILED); @@ -2203,7 +2219,7 @@ static CK_RV generate_keypair(p11_session_t *session, lose(CKR_FUNCTION_FAILED); { - size_t id_len = 0; + CK_ULONG id_len = 0; if (!p11_attribute_get(private_handle, CKA_ID, NULL, &id_len, 0) && !p11_attribute_get(public_handle, CKA_ID, NULL, &id_len, 0)) @@ -2211,14 +2227,13 @@ static CK_RV generate_keypair(p11_session_t *session, uint8_t id[id_len]; - if (!p11_attribute_get(private_handle, CKA_ID, id, NULL, id_len) && - !p11_attribute_get(public_handle, CKA_ID, id, NULL, id_len)) + if (!p11_attribute_get(private_handle, CKA_ID, id, NULL, (size_t) id_len) && + !p11_attribute_get(public_handle, CKA_ID, id, NULL, (size_t) id_len)) lose(CKR_TEMPLATE_INCOMPLETE); if ((rv = mechanism_handler(session, - pPublicKeyTemplate, ulPublicKeyAttributeCount, - pPrivateKeyTemplate, ulPrivateKeyAttributeCount, - private_handle, public_handle, + pPublicKeyTemplate, ulPublicKeyAttributeCount, public_handle, public_flags, + pPrivateKeyTemplate, ulPrivateKeyAttributeCount, private_handle, private_flags, id, id_len)) != CKR_OK) goto fail; } @@ -2419,7 +2434,7 @@ static CK_RV sign_hal_rpc(p11_session_t *session, #warning Should pay more attention to translating error codes here if (pSignature != NULL && !hal_check(hal_rpc_pkey_sign(p11_session_hal_session(session), pkey, session->sign_digest_handle, - pData, ulDataLen, pSignature, pulSignatureLen, signature_len))) + pData, ulDataLen, pSignature, &signature_len, signature_len))) lose(CKR_FUNCTION_FAILED); rv = CKR_OK; /* Fall through */ @@ -3113,7 +3128,7 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, switch (*cka_class) { case CKO_PRIVATE_KEY: case CKO_SECRET_KEY: - if (!p11_attribute_set_bbool(handle, CKA_ALWAYS_SENSITIVE, CK_FALSE) || + if (!p11_attribute_set_bbool(handle, CKA_ALWAYS_SENSITIVE, CK_FALSE) || !p11_attribute_set_bbool(handle, CKA_NEVER_EXTRACTABLE, CK_FALSE)) lose(CKR_FUNCTION_FAILED); } @@ -3716,7 +3731,7 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession, case CKM_RSA_PKCS: case CKM_SHA1_RSA_PKCS: case CKM_SHA256_RSA_PKCS: - case CKM_SHA384_RSA_PKCS: + case CKM_SHA384_RSA_PKCS: case CKM_SHA512_RSA_PKCS: if (key_type != CKK_RSA) lose(CKR_KEY_TYPE_INCONSISTENT); @@ -3746,11 +3761,11 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession, case CKM_ECDSA_SHA256: session->sign_digest_algorithm = hal_digest_algorithm_sha256; break; - case CKM_SHA384_RSA_PKCS: + case CKM_SHA384_RSA_PKCS: case CKM_ECDSA_SHA384: session->sign_digest_algorithm = hal_digest_algorithm_sha384; break; - case CKM_SHA512_RSA_PKCS: + case CKM_SHA512_RSA_PKCS: case CKM_ECDSA_SHA512: session->sign_digest_algorithm = hal_digest_algorithm_sha512; break; @@ -3949,7 +3964,7 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession, case CKM_RSA_PKCS: case CKM_SHA1_RSA_PKCS: case CKM_SHA256_RSA_PKCS: - case CKM_SHA384_RSA_PKCS: + case CKM_SHA384_RSA_PKCS: case CKM_SHA512_RSA_PKCS: if (key_type != CKK_RSA) lose(CKR_KEY_TYPE_INCONSISTENT); @@ -4045,7 +4060,7 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession, default: lose(CKR_FUNCTION_FAILED); } - + fail: /* Fall through */ if (session != NULL) { @@ -4130,7 +4145,7 @@ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession, default: lose(CKR_FUNCTION_FAILED); } - + fail: /* Fall through */ if (session != NULL) { diff --git a/scripts/py11-test.py b/scripts/py11-test.py index 1719f8b..04372ec 100644 --- a/scripts/py11-test.py +++ b/scripts/py11-test.py @@ -112,19 +112,19 @@ print "Generating EC P256 keypair" ec_templates = genkeypair_templates("EC-P256", CKA_EC_PARAMS = ec_curve_oid_p256) ec_p256_keypair = p11.C_GenerateKeyPair(session, CKM_EC_KEY_PAIR_GEN, ec_templates[0], ec_templates[1]) print ec_p256_keypair - + print print "Generating EC P384 keypair" ec_templates = genkeypair_templates("EC-P384", CKA_EC_PARAMS = ec_curve_oid_p384) ec_p384_keypair = p11.C_GenerateKeyPair(session, CKM_EC_KEY_PAIR_GEN, ec_templates[0], ec_templates[1]) print ec_p384_keypair - + print print "Generating EC P521 keypair" ec_templates = genkeypair_templates("EC-P521", CKA_EC_PARAMS = ec_curve_oid_p521) ec_p521_keypair = p11.C_GenerateKeyPair(session, CKM_EC_KEY_PAIR_GEN, ec_templates[0], ec_templates[1]) print ec_p521_keypair - + print print "Listing keys" show_keys(session, CKO_PUBLIC_KEY, CKA_VERIFY, CKA_ENCRYPT, CKA_WRAP) -- cgit v1.2.3