pkcs11: We have to create our own hashes for some signature schemes.
This commit is contained in:
@@ -103,18 +103,42 @@ METHOD(private_key_t, get_keysize, int,
|
|||||||
/**
|
/**
|
||||||
* See header.
|
* 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 {
|
static struct {
|
||||||
signature_scheme_t scheme;
|
signature_scheme_t scheme;
|
||||||
CK_MECHANISM mechanism;
|
CK_MECHANISM mechanism;
|
||||||
|
hash_algorithm_t hash;
|
||||||
} mappings[] = {
|
} mappings[] = {
|
||||||
{SIGN_RSA_EMSA_PKCS1_NULL, {CKM_RSA_PKCS, NULL, 0}},
|
{SIGN_RSA_EMSA_PKCS1_NULL, {CKM_RSA_PKCS, NULL, 0},
|
||||||
{SIGN_RSA_EMSA_PKCS1_SHA1, {CKM_SHA1_RSA_PKCS, NULL, 0}},
|
HASH_UNKNOWN},
|
||||||
{SIGN_RSA_EMSA_PKCS1_SHA256, {CKM_SHA256_RSA_PKCS, NULL, 0}},
|
{SIGN_RSA_EMSA_PKCS1_SHA1, {CKM_SHA1_RSA_PKCS, NULL, 0},
|
||||||
{SIGN_RSA_EMSA_PKCS1_SHA384, {CKM_SHA384_RSA_PKCS, NULL, 0}},
|
HASH_UNKNOWN},
|
||||||
{SIGN_RSA_EMSA_PKCS1_SHA512, {CKM_SHA512_RSA_PKCS, NULL, 0}},
|
{SIGN_RSA_EMSA_PKCS1_SHA256, {CKM_SHA256_RSA_PKCS, NULL, 0},
|
||||||
{SIGN_RSA_EMSA_PKCS1_MD5, {CKM_MD5_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;
|
int i;
|
||||||
|
|
||||||
@@ -122,6 +146,10 @@ CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme)
|
|||||||
{
|
{
|
||||||
if (mappings[i].scheme == scheme)
|
if (mappings[i].scheme == scheme)
|
||||||
{
|
{
|
||||||
|
if (hash)
|
||||||
|
{
|
||||||
|
*hash = mappings[i].hash;
|
||||||
|
}
|
||||||
return &mappings[i].mechanism;
|
return &mappings[i].mechanism;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,8 +226,10 @@ METHOD(private_key_t, sign, bool,
|
|||||||
CK_BYTE_PTR buf;
|
CK_BYTE_PTR buf;
|
||||||
CK_ULONG len;
|
CK_ULONG len;
|
||||||
CK_RV rv;
|
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)
|
if (!mechanism)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "signature scheme %N not supported",
|
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);
|
DBG1(DBG_LIB, "C_SignInit() failed: %N", ck_rv_names, rv);
|
||||||
return FALSE;
|
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;
|
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);
|
buf = malloc(len);
|
||||||
rv = this->lib->f->C_Sign(session, data.ptr, data.len, buf, &len);
|
rv = this->lib->f->C_Sign(session, data.ptr, data.len, buf, &len);
|
||||||
this->lib->f->C_CloseSession(session);
|
this->lib->f->C_CloseSession(session);
|
||||||
|
chunk_free(&hash);
|
||||||
if (rv != CKR_OK)
|
if (rv != CKR_OK)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "C_Sign() failed: %N", ck_rv_names, rv);
|
DBG1(DBG_LIB, "C_Sign() failed: %N", ck_rv_names, rv);
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2011 Tobias Brunner
|
||||||
|
* Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
* Copyright (C) 2010 Martin Willi
|
* Copyright (C) 2010 Martin Willi
|
||||||
* Copyright (C) 2010 revosec AG
|
* Copyright (C) 2010 revosec AG
|
||||||
*
|
*
|
||||||
@@ -46,14 +49,18 @@ struct pkcs11_private_key_t {
|
|||||||
*
|
*
|
||||||
* @param type type of the key
|
* @param type type of the key
|
||||||
* @param args builder_part_t argument list
|
* @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);
|
pkcs11_private_key_t *pkcs11_private_key_connect(key_type_t type, va_list args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Cryptoki mechanism for a signature scheme.
|
* 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.
|
* Get the Cryptoki mechanism for a encryption scheme.
|
||||||
|
|||||||
@@ -204,8 +204,10 @@ METHOD(public_key_t, verify, bool,
|
|||||||
CK_MECHANISM_PTR mechanism;
|
CK_MECHANISM_PTR mechanism;
|
||||||
CK_SESSION_HANDLE session;
|
CK_SESSION_HANDLE session;
|
||||||
CK_RV rv;
|
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)
|
if (!mechanism)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "signature scheme %N not supported",
|
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);
|
DBG1(DBG_LIB, "C_VerifyInit() failed: %N", ck_rv_names, rv);
|
||||||
return FALSE;
|
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);
|
rv = this->lib->f->C_Verify(session, data.ptr, data.len, sig.ptr, sig.len);
|
||||||
this->lib->f->C_CloseSession(session);
|
this->lib->f->C_CloseSession(session);
|
||||||
|
chunk_free(&hash);
|
||||||
if (rv != CKR_OK)
|
if (rv != CKR_OK)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "C_Verify() failed: %N", ck_rv_names, rv);
|
DBG1(DBG_LIB, "C_Verify() failed: %N", ck_rv_names, rv);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ struct pkcs11_public_key_t {
|
|||||||
*
|
*
|
||||||
* @param type type of the key
|
* @param type type of the key
|
||||||
* @param args builder_part_t argument list
|
* @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);
|
pkcs11_public_key_t *pkcs11_public_key_load(key_type_t type, va_list args);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user