[pkg-opensc-commit] [libp11] 03/13: Prevented destroying existing keys/certs at login

Eric Dorland eric at moszumanska.debian.org
Mon May 22 03:43:00 UTC 2017


This is an automated email from the git hooks/post-receive script.

eric pushed a commit to annotated tag libp11-0.4.5
in repository libp11.

commit 9bbdd805fc8a8aef902bdf376504cb0a7472ac3f
Author: Michał Trojnara <Michal.Trojnara at stunnel.org>
Date:   Sun Feb 5 20:15:07 2017 +0100

    Prevented destroying existing keys/certs at login
---
 NEWS           |  1 +
 src/p11_cert.c | 33 ++++++++++++++++++++-------------
 src/p11_key.c  | 33 ++++++++++++++++++++-------------
 src/p11_slot.c | 23 ++++++-----------------
 4 files changed, 47 insertions(+), 43 deletions(-)

diff --git a/NEWS b/NEWS
index e777dbd..344341c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 NEWS for Libp11 -- History of user visible changes
 
 New in 0.4.5; unreleased
+* Prevented destroying existing keys/certs at login (Michał Trojnara)
 
 New in 0.4.4; 2017-01-26; Michał Trojnara
 * Fixed a state reset caused by re-login on LOAD_CERT_CTRL engine ctrl;
diff --git a/src/p11_cert.c b/src/p11_cert.c
index f99c11b..b4212f7 100644
--- a/src/p11_cert.c
+++ b/src/p11_cert.c
@@ -43,18 +43,18 @@ int pkcs11_enumerate_certs(PKCS11_TOKEN *token,
 	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
 	int rv;
 
-	if (tpriv->ncerts < 0) {
-		/* Make sure we have a session */
-		if (!spriv->haveSession && PKCS11_open_session(slot, 0))
-			return -1;
-		CRYPTO_THREAD_write_lock(cpriv->rwlock);
-		rv = pkcs11_find_certs(token);
-		CRYPTO_THREAD_unlock(cpriv->rwlock);
-		if (rv < 0) {
-			pkcs11_destroy_certs(token);
-			return -1;
-		}
+	/* Make sure we have a session */
+	if (!spriv->haveSession && PKCS11_open_session(slot, 0))
+		return -1;
+
+	CRYPTO_THREAD_write_lock(cpriv->rwlock);
+	rv = pkcs11_find_certs(token);
+	CRYPTO_THREAD_unlock(cpriv->rwlock);
+	if (rv < 0) {
+		pkcs11_destroy_certs(token);
+		return -1;
 	}
+
 	if (certp)
 		*certp = tpriv->certs;
 	if (countp)
@@ -104,7 +104,6 @@ static int pkcs11_find_certs(PKCS11_TOKEN *token)
 	rv = CRYPTOKI_call(ctx, C_FindObjectsInit(spriv->session, cert_search_attrs, 1));
 	CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_CERTS, rv);
 
-	tpriv->ncerts = 0;
 	do {
 		res = pkcs11_next_cert(ctx, token, spriv->session);
 	} while (res == 0);
@@ -143,6 +142,7 @@ static int pkcs11_init_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
 	unsigned char *data;
 	CK_CERTIFICATE_TYPE cert_type;
 	size_t size;
+	int i;
 
 	(void)ctx;
 	(void)session;
@@ -154,6 +154,13 @@ static int pkcs11_init_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
 	if (cert_type != CKC_X_509)
 		return 0;
 
+	/* Prevent re-adding existing PKCS#11 object handles */
+	/* TODO: Rewrite the O(n) algorithm as O(log n),
+	 * or it may be too slow with a large number of certificates */
+	for (i=0; i < PRIVTOKEN(token)->ncerts; ++i)
+		if (PRIVCERT(PRIVTOKEN(token)->certs + i)->object == obj)
+			return 0;
+
 	/* Allocate memory */
 	cpriv = OPENSSL_malloc(sizeof(PKCS11_CERT_private));
 	if (cpriv == NULL)
@@ -214,7 +221,7 @@ void pkcs11_destroy_certs(PKCS11_TOKEN *token)
 	if (tpriv->certs)
 		OPENSSL_free(tpriv->certs);
 	tpriv->certs = NULL;
-	tpriv->ncerts = -1;
+	tpriv->ncerts = 0;
 }
 
 /*
diff --git a/src/p11_key.c b/src/p11_key.c
index 20c00bc..7df1d66 100644
--- a/src/p11_key.c
+++ b/src/p11_key.c
@@ -395,18 +395,18 @@ int pkcs11_enumerate_keys(PKCS11_TOKEN *token, unsigned int type,
 	PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub;
 	int rv;
 
-	if (keys->num < 0) { /* No cache was built for the specified type */
-		/* Make sure we have a session */
-		if (!spriv->haveSession && PKCS11_open_session(slot, 0))
-			return -1;
-		CRYPTO_THREAD_write_lock(cpriv->rwlock);
-		rv = pkcs11_find_keys(token, type);
-		CRYPTO_THREAD_unlock(cpriv->rwlock);
-		if (rv < 0) {
-			pkcs11_destroy_keys(token, type);
-			return -1;
-		}
+	/* Make sure we have a session */
+	if (!spriv->haveSession && PKCS11_open_session(slot, 0))
+		return -1;
+
+	CRYPTO_THREAD_write_lock(cpriv->rwlock);
+	rv = pkcs11_find_keys(token, type);
+	CRYPTO_THREAD_unlock(cpriv->rwlock);
+	if (rv < 0) {
+		pkcs11_destroy_keys(token, type);
+		return -1;
 	}
+
 	if (keyp)
 		*keyp = keys->keys;
 	if (countp)
@@ -436,7 +436,6 @@ static int pkcs11_find_keys(PKCS11_TOKEN *token, unsigned int type)
 		C_FindObjectsInit(spriv->session, key_search_attrs, 1));
 	CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_KEYS, rv);
 
-	keys->num = 0;
 	do {
 		res = pkcs11_next_key(ctx, token, spriv->session, type);
 	} while (res == 0);
@@ -477,6 +476,7 @@ static int pkcs11_init_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
 	CK_KEY_TYPE key_type;
 	PKCS11_KEY_ops *ops;
 	size_t size;
+	int i;
 
 	(void)ctx;
 	(void)session;
@@ -499,6 +499,13 @@ static int pkcs11_init_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
 		return 0;
 	}
 
+	/* Prevent re-adding existing PKCS#11 object handles */
+	/* TODO: Rewrite the O(n) algorithm as O(log n),
+	 * or it may be too slow with a large number of keys */
+	for (i=0; i < keys->num; ++i)
+		if (PRIVKEY(keys->keys + i)->object == obj)
+			return 0;
+
 	/* Allocate memory */
 	kpriv = OPENSSL_malloc(sizeof(PKCS11_KEY_private));
 	if (kpriv == NULL)
@@ -554,7 +561,7 @@ void pkcs11_destroy_keys(PKCS11_TOKEN *token, unsigned int type)
 	if (keys->keys)
 		OPENSSL_free(keys->keys);
 	keys->keys = NULL;
-	keys->num = -1;
+	keys->num = 0;
 }
 
 /* vim: set noexpandtab: */
diff --git a/src/p11_slot.c b/src/p11_slot.c
index f907469..da887d6 100644
--- a/src/p11_slot.c
+++ b/src/p11_slot.c
@@ -189,20 +189,9 @@ int pkcs11_login(PKCS11_SLOT *slot, int so, const char *pin, int relogin)
 	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
 	int rv;
 
-	if (relogin == 0) {
-		/* Calling PKCS11_login invalidates all cached
-		 * keys we have */
-		if (slot->token) {
-			pkcs11_destroy_keys(slot->token, CKO_PRIVATE_KEY);
-			pkcs11_destroy_keys(slot->token, CKO_PUBLIC_KEY);
-			pkcs11_destroy_certs(slot->token);
-		}
-		if (spriv->loggedIn) {
-			/* already logged in, log out first */
-			if (PKCS11_logout(slot))
-				return -1;
-		}
-	}
+	if (!relogin && spriv->loggedIn)
+		return 0; /* Nothing to do */
+
 	if (!spriv->haveSession) {
 		/* SO gets a r/w session by default,
 		 * user gets a r/o session by default. */
@@ -486,10 +475,10 @@ static int pkcs11_check_token(PKCS11_CTX *ctx, PKCS11_SLOT *slot)
 	memset(tpriv, 0, sizeof(PKCS11_TOKEN_private));
 	tpriv->parent = slot;
 	tpriv->prv.keys = NULL;
-	tpriv->prv.num = -1;
+	tpriv->prv.num = 0;
 	tpriv->pub.keys = NULL;
-	tpriv->pub.num = -1;
-	tpriv->ncerts = -1;
+	tpriv->pub.num = 0;
+	tpriv->ncerts = 0;
 
 	slot->token->label = PKCS11_DUP(info.label);
 	slot->token->manufacturer = PKCS11_DUP(info.manufacturerID);

-- 
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