From: Tobias Brunner Date: Wed, 2 Nov 2011 18:23:05 +0000 (+0100) Subject: pkcs11: We have to create our own hashes for some signature schemes. X-Git-Tag: 4.6.0~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fd48b220ed28c486d13e0e4d5166d63096778dbc;p=thirdparty%2Fstrongswan.git pkcs11: We have to create our own hashes for some signature schemes. --- diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c index fda6ae3925..a354070c14 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c @@ -103,18 +103,42 @@ METHOD(private_key_t, get_keysize, int, /** * See header. */ -CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme) +CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme, + hash_algorithm_t *hash) { static struct { signature_scheme_t scheme; CK_MECHANISM mechanism; + hash_algorithm_t hash; } mappings[] = { - {SIGN_RSA_EMSA_PKCS1_NULL, {CKM_RSA_PKCS, NULL, 0}}, - {SIGN_RSA_EMSA_PKCS1_SHA1, {CKM_SHA1_RSA_PKCS, NULL, 0}}, - {SIGN_RSA_EMSA_PKCS1_SHA256, {CKM_SHA256_RSA_PKCS, NULL, 0}}, - {SIGN_RSA_EMSA_PKCS1_SHA384, {CKM_SHA384_RSA_PKCS, NULL, 0}}, - {SIGN_RSA_EMSA_PKCS1_SHA512, {CKM_SHA512_RSA_PKCS, NULL, 0}}, - {SIGN_RSA_EMSA_PKCS1_MD5, {CKM_MD5_RSA_PKCS, NULL, 0}}, + {SIGN_RSA_EMSA_PKCS1_NULL, {CKM_RSA_PKCS, NULL, 0}, + HASH_UNKNOWN}, + {SIGN_RSA_EMSA_PKCS1_SHA1, {CKM_SHA1_RSA_PKCS, NULL, 0}, + HASH_UNKNOWN}, + {SIGN_RSA_EMSA_PKCS1_SHA256, {CKM_SHA256_RSA_PKCS, NULL, 0}, + HASH_UNKNOWN}, + {SIGN_RSA_EMSA_PKCS1_SHA384, {CKM_SHA384_RSA_PKCS, NULL, 0}, + HASH_UNKNOWN}, + {SIGN_RSA_EMSA_PKCS1_SHA512, {CKM_SHA512_RSA_PKCS, NULL, 0}, + HASH_UNKNOWN}, + {SIGN_RSA_EMSA_PKCS1_MD5, {CKM_MD5_RSA_PKCS, NULL, 0}, + HASH_UNKNOWN}, + {SIGN_ECDSA_WITH_NULL, {CKM_ECDSA, NULL, 0}, + HASH_UNKNOWN}, + {SIGN_ECDSA_WITH_SHA1_DER, {CKM_ECDSA_SHA1, NULL, 0}, + HASH_UNKNOWN}, + {SIGN_ECDSA_WITH_SHA256_DER, {CKM_ECDSA, NULL, 0}, + HASH_SHA256}, + {SIGN_ECDSA_WITH_SHA384_DER, {CKM_ECDSA, NULL, 0}, + HASH_SHA384}, + {SIGN_ECDSA_WITH_SHA512_DER, {CKM_ECDSA, NULL, 0}, + HASH_SHA512}, + {SIGN_ECDSA_256, {CKM_ECDSA, NULL, 0}, + HASH_SHA256}, + {SIGN_ECDSA_384, {CKM_ECDSA, NULL, 0}, + HASH_SHA384}, + {SIGN_ECDSA_521, {CKM_ECDSA, NULL, 0}, + HASH_SHA512}, }; int i; @@ -122,6 +146,10 @@ CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme) { if (mappings[i].scheme == scheme) { + if (hash) + { + *hash = mappings[i].hash; + } return &mappings[i].mechanism; } } @@ -198,8 +226,10 @@ METHOD(private_key_t, sign, bool, CK_BYTE_PTR buf; CK_ULONG len; CK_RV rv; + hash_algorithm_t hash_alg; + chunk_t hash = chunk_empty; - mechanism = pkcs11_signature_scheme_to_mech(scheme); + mechanism = pkcs11_signature_scheme_to_mech(scheme, &hash_alg); if (!mechanism) { DBG1(DBG_LIB, "signature scheme %N not supported", @@ -225,10 +255,27 @@ METHOD(private_key_t, sign, bool, DBG1(DBG_LIB, "C_SignInit() failed: %N", ck_rv_names, rv); return FALSE; } + if (hash_alg != HASH_UNKNOWN) + { + hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, hash_alg); + if (!hasher) + { + this->lib->f->C_CloseSession(session); + return FALSE; + } + hasher->allocate_hash(hasher, data, &hash); + hasher->destroy(hasher); + data = hash; + } len = (get_keysize(this) + 7) / 8; + if (this->type == KEY_ECDSA) + { /* signature is twice the length of the base point order */ + len *= 2; + } buf = malloc(len); rv = this->lib->f->C_Sign(session, data.ptr, data.len, buf, &len); this->lib->f->C_CloseSession(session); + chunk_free(&hash); if (rv != CKR_OK) { DBG1(DBG_LIB, "C_Sign() failed: %N", ck_rv_names, rv); diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h index 428913f0a1..1e4ec30688 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h @@ -1,4 +1,7 @@ /* + * Copyright (C) 2011 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -46,14 +49,18 @@ struct pkcs11_private_key_t { * * @param type type of the key * @param args builder_part_t argument list - * @return loaded key, NULL on failure + * @return loaded key, NULL on failure */ pkcs11_private_key_t *pkcs11_private_key_connect(key_type_t type, va_list args); /** * Get the Cryptoki mechanism for a signature scheme. + * + * @param scheme signature scheme + * @param hash hash algorithm to apply first (HASH_UNKNOWN if none) */ -CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme); +CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme, + hash_algorithm_t *hash); /** * Get the Cryptoki mechanism for a encryption scheme. diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c index 0be7b05091..2a3a511a57 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c @@ -204,8 +204,10 @@ METHOD(public_key_t, verify, bool, CK_MECHANISM_PTR mechanism; CK_SESSION_HANDLE session; CK_RV rv; + hash_algorithm_t hash_alg; + chunk_t hash = chunk_empty; - mechanism = pkcs11_signature_scheme_to_mech(scheme); + mechanism = pkcs11_signature_scheme_to_mech(scheme, &hash_alg); if (!mechanism) { DBG1(DBG_LIB, "signature scheme %N not supported", @@ -230,8 +232,21 @@ METHOD(public_key_t, verify, bool, DBG1(DBG_LIB, "C_VerifyInit() failed: %N", ck_rv_names, rv); return FALSE; } + if (hash_alg != HASH_UNKNOWN) + { + hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, hash_alg); + if (!hasher) + { + this->lib->f->C_CloseSession(session); + return FALSE; + } + hasher->allocate_hash(hasher, data, &hash); + hasher->destroy(hasher); + data = hash; + } rv = this->lib->f->C_Verify(session, data.ptr, data.len, sig.ptr, sig.len); this->lib->f->C_CloseSession(session); + chunk_free(&hash); if (rv != CKR_OK) { DBG1(DBG_LIB, "C_Verify() failed: %N", ck_rv_names, rv); diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h index 4fd94620e4..b3ea725a2e 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h @@ -42,7 +42,7 @@ struct pkcs11_public_key_t { * * @param type type of the key * @param args builder_part_t argument list - * @return loaded key, NULL on failure + * @return loaded key, NULL on failure */ pkcs11_public_key_t *pkcs11_public_key_load(key_type_t type, va_list args);