[pkg-opensc-commit] [libp11] 69/86: Added CKA_ALWAYS_AUTHENTICATE support for #72

Eric Dorland eric at moszumanska.debian.org
Sun Jul 24 21:40:24 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 3678317e49906ebe095ca0800741513f75b46f82
Author: Michał Trojnara <Michal.Trojnara at stunnel.org>
Date:   Fri Mar 11 20:04:16 2016 +0100

    Added CKA_ALWAYS_AUTHENTICATE support for #72
---
 NEWS             |  1 +
 src/libp11-int.h |  9 +++++++++
 src/p11_attr.c   |  6 ++++++
 src/p11_ec.c     |  2 ++
 src/p11_key.c    | 31 +++++++++++++++++++++++++++++++
 src/p11_rsa.c    |  6 ++++++
 6 files changed, 55 insertions(+)

diff --git a/NEWS b/NEWS
index 170353b..ad5a2cb 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,7 @@ New in 0.4.0; unreleased;
 * Added support for the ANSI X9.31 (RSA_X931_PADDING) RSA padding
   (Michał Trojnara)
 * Added support for RSA encryption (not only signing) (Michał Trojnara)
+* Added CKA_ALWAYS_AUTHENTICATE support (Michał Trojnara)
 * Fixed incorrect errors reported on signing/encryption/decryption
   (Michał Trojnara)
 * Fixed deadlocks in keys and certificates listing (Brian Hinz)
diff --git a/src/libp11-int.h b/src/libp11-int.h
index cafa956..10674a6 100644
--- a/src/libp11-int.h
+++ b/src/libp11-int.h
@@ -93,6 +93,7 @@ typedef struct pkcs11_key_ops {
 typedef struct pkcs11_key_private {
 	PKCS11_TOKEN *parent;
 	CK_OBJECT_HANDLE object;
+	CK_BBOOL always_authenticate;
 	unsigned char id[255];
 	size_t id_len;
 	PKCS11_KEY_ops *ops;
@@ -164,6 +165,8 @@ extern char *pkcs11_strdup(char *, size_t);
 
 extern int pkcs11_getattr_var(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
 	unsigned int, CK_BYTE *, size_t *);
+extern int pkcs11_getattr_val(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
+	unsigned int, void *, size_t);
 extern int pkcs11_getattr_alloc(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
 	unsigned int, CK_BYTE **, size_t *);
 extern int pkcs11_getattr_bn(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
@@ -174,6 +177,9 @@ extern int pkcs11_reload_key(PKCS11_KEY *);
 #define key_getattr_var(key, t, p, s) \
 	pkcs11_getattr_var(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s))
 
+#define key_getattr_val(key, t, p, s) \
+	pkcs11_getattr_val(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s))
+
 #define key_getattr_alloc(key, t, p, s) \
 	pkcs11_getattr_alloc(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s))
 
@@ -242,6 +248,9 @@ extern int pkcs11_login(PKCS11_SLOT * slot, int so, const char *pin, int relogin
 /* De-authenticate from the card */
 extern int pkcs11_logout(PKCS11_SLOT * slot);
 
+/* Authenticate a private the key operation if needed */
+int pkcs11_authenticate(PKCS11_KEY *key);
+
 /* Get a list of keys associated with this token */
 extern int pkcs11_enumerate_keys(PKCS11_TOKEN *token, unsigned int type,
 	PKCS11_KEY **keys, unsigned int *nkeys);
diff --git a/src/p11_attr.c b/src/p11_attr.c
index 74750a7..b7dfec4 100644
--- a/src/p11_attr.c
+++ b/src/p11_attr.c
@@ -59,6 +59,12 @@ int pkcs11_getattr_var(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
 		object, type, value, size);
 }
 
+int pkcs11_getattr_val(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
+		unsigned int type, void *value, size_t size)
+{
+	return pkcs11_getattr_var(token, object, type, value, &size);
+}
+
 int pkcs11_getattr_alloc(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
 		unsigned int type, CK_BYTE **value, size_t *size)
 {
diff --git a/src/p11_ec.c b/src/p11_ec.c
index f4e8889..b091900 100644
--- a/src/p11_ec.c
+++ b/src/p11_ec.c
@@ -202,6 +202,8 @@ static int pkcs11_ecdsa_sign(const unsigned char *msg, unsigned int msg_len,
 	rv = CRYPTOKI_call(ctx,
 		C_SignInit(spriv->session, &mechanism, kpriv->object));
 	if (!rv)
+		rv = pkcs11_authenticate(key);
+	if (!rv)
 		rv = CRYPTOKI_call(ctx,
 			C_Sign(spriv->session, (CK_BYTE *)msg, msg_len, sigret, &ck_sigsize));
 	CRYPTO_THREAD_unlock(PRIVSLOT(slot)->rwlock);
diff --git a/src/p11_key.c b/src/p11_key.c
index ce9bcb7..5d9efa3 100644
--- a/src/p11_key.c
+++ b/src/p11_key.c
@@ -291,11 +291,42 @@ EVP_PKEY *pkcs11_get_key(PKCS11_KEY *key, int isPrivate)
 		key->evp_key = kpriv->ops->get_evp_key(key);
 		if (key->evp_key == NULL)
 			return NULL;
+		kpriv->always_authenticate = CK_FALSE;
+		if(isPrivate) {
+			if(key_getattr_val(key, CKA_ALWAYS_AUTHENTICATE,
+					&kpriv->always_authenticate, sizeof(CK_BBOOL)))
+				fprintf(stderr, "Missing CKA_ALWAYS_AUTHENTICATE attribute\n");
+			else if (kpriv->always_authenticate)
+				fprintf(stderr, "CKA_ALWAYS_AUTHENTICATE attribute set\n");
+			else
+				fprintf(stderr, "CKA_ALWAYS_AUTHENTICATE attribute not set\n");
+		}
 	}
 	return key->evp_key;
 }
 
 /*
+ * Authenticate a private the key operation if needed
+ */
+int pkcs11_authenticate(PKCS11_KEY *key)
+{
+	PKCS11_KEY_private *kpriv = PRIVKEY(key);
+	PKCS11_SLOT *slot = KEY2SLOT(key);
+	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+	PKCS11_CTX *ctx = SLOT2CTX(slot);
+	int rv;
+
+	if (!kpriv->always_authenticate || spriv->prev_pin == NULL)
+		return 0;
+	rv = CRYPTOKI_call(ctx,
+		C_Login(spriv->session, CKU_CONTEXT_SPECIFIC,
+			(CK_UTF8CHAR *)spriv->prev_pin, strlen(spriv->prev_pin)));
+	if (rv == CKR_USER_ALREADY_LOGGED_IN) /* ignore */
+		rv = 0;
+	return rv;
+}
+
+/*
  * Return keys of a given type (public or private)
  * Use the cached values if available
  */
diff --git a/src/p11_rsa.c b/src/p11_rsa.c
index 4155a82..93bd411 100644
--- a/src/p11_rsa.c
+++ b/src/p11_rsa.c
@@ -97,6 +97,8 @@ int pkcs11_private_encrypt(int flen,
 	rv = CRYPTOKI_call(ctx,
 		C_SignInit(spriv->session, &mechanism, kpriv->object));
 	if (!rv)
+		rv = pkcs11_authenticate(key);
+	if (!rv)
 		rv = CRYPTOKI_call(ctx,
 			C_Sign(spriv->session, (CK_BYTE *)from, flen, to, &size));
 	if (rv == CKR_KEY_FUNCTION_NOT_PERMITTED) {
@@ -104,6 +106,8 @@ int pkcs11_private_encrypt(int flen,
 		rv = CRYPTOKI_call(ctx,
 			C_EncryptInit(spriv->session, &mechanism, kpriv->object));
 		if (!rv)
+			rv = pkcs11_authenticate(key);
+		if (!rv)
 			rv = CRYPTOKI_call(ctx,
 				C_Encrypt(spriv->session, (CK_BYTE *)from, flen, to, &size));
 	}
@@ -136,6 +140,8 @@ int pkcs11_private_decrypt(int flen, const unsigned char *from, unsigned char *t
 	rv = CRYPTOKI_call(ctx,
 		C_DecryptInit(spriv->session, &mechanism, kpriv->object));
 	if (!rv)
+		rv = pkcs11_authenticate(key);
+	if (!rv)
 		rv = CRYPTOKI_call(ctx,
 			C_Decrypt(spriv->session, (CK_BYTE *)from, size,
 				(CK_BYTE_PTR)to, &size));

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