[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