aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2011-11-02 19:23:05 +0100
committerTobias Brunner <tobias@strongswan.org>2011-11-02 20:27:55 +0100
commitfd48b220ed28c486d13e0e4d5166d63096778dbc (patch)
treec4c00ede7665c52124d1876c8f7abe11a9bb32ee
parent30a3ede8cee48adb16ef73c9eddda1b7418d263f (diff)
downloadstrongswan-fd48b220ed28c486d13e0e4d5166d63096778dbc.tar.bz2
strongswan-fd48b220ed28c486d13e0e4d5166d63096778dbc.tar.xz
pkcs11: We have to create our own hashes for some signature schemes.
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c63
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h11
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c17
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h2
4 files changed, 81 insertions, 12 deletions
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
index fda6ae392..a354070c1 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 428913f0a..1e4ec3068 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 0be7b0509..2a3a511a5 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 4fd94620e..b3ea725a2 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);