diff options
author | Martin Willi <martin@revosec.ch> | 2010-08-11 12:12:37 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-08-11 12:12:37 +0200 |
commit | 01e4f5f32f81972cbab0e0dc0564cd74d6ce800e (patch) | |
tree | 258d4edf9dab308cbb02997202cb9059a71a2f0a | |
parent | aea735ef63b809d5c50e058f164cea362fe3893c (diff) | |
download | strongswan-01e4f5f32f81972cbab0e0dc0564cd74d6ce800e.tar.bz2 strongswan-01e4f5f32f81972cbab0e0dc0564cd74d6ce800e.tar.xz |
Implemented public key encryption/private key decryption in PKCS#11
-rw-r--r-- | src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c | 67 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h | 7 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c | 47 |
3 files changed, 108 insertions, 13 deletions
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c index 52a9e09c2..e51d0aae4 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c @@ -89,7 +89,7 @@ METHOD(private_key_t, get_keysize, int, /** * See header. */ -CK_MECHANISM_PTR pkcs11_scheme_to_mechanism(signature_scheme_t scheme) +CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme) { static struct { signature_scheme_t scheme; @@ -115,6 +115,30 @@ CK_MECHANISM_PTR pkcs11_scheme_to_mechanism(signature_scheme_t scheme) } /** + * See header. + */ +CK_MECHANISM_PTR pkcs11_encryption_scheme_to_mech(encryption_scheme_t scheme) +{ + static struct { + encryption_scheme_t scheme; + CK_MECHANISM mechanism; + } mappings[] = { + {ENCRYPT_RSA_PKCS1, {CKM_RSA_PKCS, NULL, 0}}, + {ENCRYPT_RSA_OAEP_SHA1, {CKM_RSA_PKCS_OAEP, NULL, 0}}, + }; + int i; + + for (i = 0; i < countof(mappings); i++) + { + if (mappings[i].scheme == scheme) + { + return &mappings[i].mechanism; + } + } + return NULL; +} + +/** * Reauthenticate to do a signature */ static bool reauth(private_pkcs11_private_key_t *this) @@ -159,7 +183,7 @@ METHOD(private_key_t, sign, bool, CK_ULONG len; CK_RV rv; - mechanism = pkcs11_scheme_to_mechanism(scheme); + mechanism = pkcs11_signature_scheme_to_mech(scheme); if (!mechanism) { DBG1(DBG_LIB, "signature scheme %N not supported", @@ -194,9 +218,44 @@ METHOD(private_key_t, sign, bool, METHOD(private_key_t, decrypt, bool, private_pkcs11_private_key_t *this, encryption_scheme_t scheme, - chunk_t crypto, chunk_t *plain) + chunk_t crypt, chunk_t *plain) { - return FALSE; + CK_MECHANISM_PTR mechanism; + CK_BYTE_PTR buf; + CK_ULONG len; + CK_RV rv; + + mechanism = pkcs11_encryption_scheme_to_mech(scheme); + if (!mechanism) + { + DBG1(DBG_LIB, "encryption scheme %N not supported", + encryption_scheme_names, scheme); + return FALSE; + } + this->mutex->lock(this->mutex); + rv = this->lib->f->C_DecryptInit(this->session, mechanism, this->object); + if (this->reauth && !reauth(this)) + { + return FALSE; + } + if (rv != CKR_OK) + { + this->mutex->unlock(this->mutex); + DBG1(DBG_LIB, "C_DecryptInit() failed: %N", ck_rv_names, rv); + return FALSE; + } + len = (get_keysize(this) + 7) / 8; + buf = malloc(len); + rv = this->lib->f->C_Decrypt(this->session, crypt.ptr, crypt.len, buf, &len); + this->mutex->unlock(this->mutex); + if (rv != CKR_OK) + { + DBG1(DBG_LIB, "C_Decrypt() failed: %N", ck_rv_names, rv); + free(buf); + return FALSE; + } + *plain = chunk_create(buf, len); + return TRUE; } METHOD(private_key_t, get_public_key, public_key_t*, diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h index 921a02732..428913f0a 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h @@ -53,6 +53,11 @@ pkcs11_private_key_t *pkcs11_private_key_connect(key_type_t type, va_list args); /** * Get the Cryptoki mechanism for a signature scheme. */ -CK_MECHANISM_PTR pkcs11_scheme_to_mechanism(signature_scheme_t scheme); +CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme); + +/** + * Get the Cryptoki mechanism for a encryption scheme. + */ +CK_MECHANISM_PTR pkcs11_encryption_scheme_to_mech(encryption_scheme_t scheme); #endif /** PKCS11_PRIVATE_KEY_H_ @}*/ diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c index affd8cafc..8d32d9a3f 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c @@ -81,6 +81,12 @@ METHOD(public_key_t, get_type, key_type_t, return this->type; } +METHOD(public_key_t, get_keysize, int, + private_pkcs11_public_key_t *this) +{ + return this->k * 8; +} + METHOD(public_key_t, verify, bool, private_pkcs11_public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t sig) @@ -88,7 +94,7 @@ METHOD(public_key_t, verify, bool, CK_MECHANISM_PTR mechanism; CK_RV rv; - mechanism = pkcs11_scheme_to_mechanism(scheme); + mechanism = pkcs11_signature_scheme_to_mech(scheme); if (!mechanism) { DBG1(DBG_LIB, "signature scheme %N not supported", @@ -120,15 +126,40 @@ METHOD(public_key_t, verify, bool, METHOD(public_key_t, encrypt, bool, private_pkcs11_public_key_t *this, encryption_scheme_t scheme, - chunk_t plain, chunk_t *crypto) + chunk_t plain, chunk_t *crypt) { - return FALSE; -} + CK_MECHANISM_PTR mechanism; + CK_BYTE_PTR buf; + CK_ULONG len; + CK_RV rv; -METHOD(public_key_t, get_keysize, int, - private_pkcs11_public_key_t *this) -{ - return this->k * 8; + mechanism = pkcs11_encryption_scheme_to_mech(scheme); + if (!mechanism) + { + DBG1(DBG_LIB, "encryption scheme %N not supported", + encryption_scheme_names, scheme); + return FALSE; + } + this->mutex->lock(this->mutex); + rv = this->lib->f->C_EncryptInit(this->session, mechanism, this->object); + if (rv != CKR_OK) + { + this->mutex->unlock(this->mutex); + DBG1(DBG_LIB, "C_EncryptInit() failed: %N", ck_rv_names, rv); + return FALSE; + } + len = (get_keysize(this) + 7) / 8; + buf = malloc(len); + rv = this->lib->f->C_Encrypt(this->session, plain.ptr, plain.len, buf, &len); + this->mutex->unlock(this->mutex); + if (rv != CKR_OK) + { + DBG1(DBG_LIB, "C_Encrypt() failed: %N", ck_rv_names, rv); + free(buf); + return FALSE; + } + *crypt = chunk_create(buf, len); + return TRUE; } /** |