[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