[pkg-opensc-commit] [libp11] 47/67: Fixed a memory leak in pkcs11_get_evp_key_rsa()
Eric Dorland
eric at moszumanska.debian.org
Sat Jan 30 05:34:16 UTC 2016
This is an automated email from the git hooks/post-receive script.
eric pushed a commit to branch master
in repository libp11.
commit 097627e8fe17694763b1b2a859d42bf01844fca6
Author: Michał Trojnara <Michal.Trojnara at stunnel.org>
Date: Fri Jan 8 16:08:26 2016 +0100
Fixed a memory leak in pkcs11_get_evp_key_rsa()
---
NEWS | 1 +
src/p11_key.c | 2 +-
src/p11_rsa.c | 99 +++++++++++++++++++++++++++++++++--------------------------
3 files changed, 58 insertions(+), 44 deletions(-)
diff --git a/NEWS b/NEWS
index 4a862ae..3f10fc3 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
NEWS for Libp11 -- History of user visible changes
New in 0.3.1; unreleased;
+* Fixed a memory leak in pkcs11_get_evp_key_rsa() (Michał Trojnara)
* A private index is allocated for ex_data access (RSA and ECDSA classes)
instead of using the reserved index zero (app_data) (Michał Trojnara)
* Improved searching for dlopen() (Christoph Moench-Tegeder)
diff --git a/src/p11_key.c b/src/p11_key.c
index 5e26730..c9224e3 100644
--- a/src/p11_key.c
+++ b/src/p11_key.c
@@ -153,7 +153,7 @@ PKCS11_generate_key(PKCS11_TOKEN * token, int algorithm, unsigned int bits,
}
err = BIO_new_fp(stderr, BIO_NOCLOSE);
- rsa = RSA_generate_key(bits, 0x10001, NULL, err);
+ rsa = RSA_generate_key(bits, RSA_F4, NULL, err);
BIO_free(err);
if (rsa == NULL) {
PKCS11err(PKCS11_F_PKCS11_GENERATE_KEY, PKCS11_KEYGEN_FAILED);
diff --git a/src/p11_rsa.c b/src/p11_rsa.c
index 6b08749..1fbf4c4 100644
--- a/src/p11_rsa.c
+++ b/src/p11_rsa.c
@@ -33,64 +33,77 @@ static int rsa_ex_index = 0;
/*
* Get RSA key material
*/
-static EVP_PKEY *pkcs11_get_evp_key_rsa(PKCS11_KEY * key)
+static RSA *pkcs11_get_rsa(PKCS11_KEY * key)
{
- EVP_PKEY *pk;
- CK_BBOOL sensitive, extractable;
RSA *rsa;
-
- pk = EVP_PKEY_new();
- if (pk == NULL)
- return NULL;
+ PKCS11_KEY *keys = NULL;
+ unsigned int i, count = 0;
rsa = RSA_new();
- if (rsa == NULL) {
- EVP_PKEY_free(pk);
- return NULL;
- }
- EVP_PKEY_set1_RSA(pk, rsa); /* Also increments the rsa ref count */
-
- if (key_getattr(key, CKA_SENSITIVE, &sensitive, sizeof(sensitive))
- || key_getattr(key, CKA_EXTRACTABLE, &extractable, sizeof(extractable))) {
- EVP_PKEY_free(pk);
- RSA_free(rsa);
+ if (rsa == NULL)
return NULL;
- }
+ /* Retrieve the modulus and the public exponent */
if (key_getattr_bn(key, CKA_MODULUS, &rsa->n) ||
key_getattr_bn(key, CKA_PUBLIC_EXPONENT, &rsa->e)) {
- EVP_PKEY_free(pk);
RSA_free(rsa);
return NULL;
}
- if (BN_is_zero(rsa->e)) {
- PKCS11_TOKEN_private * tpriv = PRIVTOKEN(KEY2TOKEN(key));
- int ki;
- BIGNUM* pubmod = NULL;
- for(ki = 0; ki < tpriv->pub.num; ki++) {
- PKCS11_KEY* pubkey = &tpriv->pub.keys[ki];
-
- if (key_getattr_bn(pubkey, CKA_MODULUS, &pubmod)) {
- continue;
- }
- if (BN_cmp(rsa->n, pubmod)) { // Modulus not same -- this public from another key
- continue;
- }
-
- // If modulus are same -- we found required key, extract public exponent from it
- if (key_getattr_bn(pubkey, CKA_PUBLIC_EXPONENT, &rsa->e)) {
- continue;
- }
- if (BN_is_zero(rsa->e)) {
- continue;
+ if(!BN_is_zero(rsa->e)) /* The public exponent was retrieved */
+ return rsa;
+
+ /* The public exponent was not found in the private key:
+ * retrieve it from the corresponding public key */
+ if (!PKCS11_enumerate_public_keys(KEY2TOKEN(key), &keys, &count)) {
+ for(i = 0; i < count; i++) {
+ BIGNUM *pubmod;
+
+ if (key_getattr_bn(&keys[i], CKA_MODULUS, &pubmod))
+ continue; /* Failed to retrieve the modulus */
+ if (BN_cmp(rsa->n, pubmod) == 0) { /* The key was found */
+ BN_free(pubmod);
+ if (key_getattr_bn(&keys[i], CKA_PUBLIC_EXPONENT, &rsa->e))
+ continue; /* Failed to retrieve the public exponent */
+ return rsa;
+ } else {
+ BN_free(pubmod);
}
- break;
}
- if (pubmod!=NULL)
- BN_free(pubmod);
}
+ /* Last resort: use the most common default */
+ rsa->e = BN_new();
+ if(rsa->e && BN_set_word(rsa->e, RSA_F4))
+ return rsa;
+
+ RSA_free(rsa);
+ return NULL;
+}
+
+/*
+ * Build an EVP_PKEY object
+ */
+static EVP_PKEY *pkcs11_get_evp_key_rsa(PKCS11_KEY * key)
+{
+ EVP_PKEY *pk;
+ CK_BBOOL sensitive, extractable;
+ RSA *rsa;
+
+ if (key_getattr(key, CKA_SENSITIVE, &sensitive, sizeof(sensitive))
+ || key_getattr(key, CKA_EXTRACTABLE, &extractable, sizeof(extractable)))
+ return NULL;
+
+ rsa = pkcs11_get_rsa(key);
+ if (rsa == NULL)
+ return NULL;
+ pk = EVP_PKEY_new();
+ if (pk == NULL) {
+ RSA_free(rsa);
+ return NULL;
+ }
+ EVP_PKEY_set1_RSA(pk, rsa); /* Also increments the rsa ref count */
+
/* If the key is not extractable, create a key object
* that will use the card's functions to sign & decrypt */
if (sensitive || !extractable) {
@@ -103,7 +116,7 @@ static EVP_PKEY *pkcs11_get_evp_key_rsa(PKCS11_KEY * key)
rsa->flags |= RSA_FLAG_SIGN_VER;
RSA_set_ex_data(rsa, rsa_ex_index, key);
- RSA_free(rsa); /* drops our reference to it */
+ RSA_free(rsa); /* Drops our reference to it */
return pk;
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-opensc/libp11.git
More information about the pkg-opensc-commit
mailing list