[pkg-opensc-commit] [libp11] 02/51: Use UI to get the CKA_ALWAYS_AUTHENTICATE PIN

Eric Dorland eric at moszumanska.debian.org
Wed Dec 7 17:51:29 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 7573c6e800cae3b429ae018c6a6bcdfe61bc1b4b
Author: Michał Trojnara <Michal.Trojnara at stunnel.org>
Date:   Mon Sep 26 08:17:12 2016 +0200

    Use UI to get the CKA_ALWAYS_AUTHENTICATE PIN
---
 NEWS               |  1 +
 src/eng_back.c     |  1 +
 src/libp11-int.h   |  4 ++++
 src/libp11.exports |  1 +
 src/libp11.h       |  4 ++++
 src/p11_err.c      |  1 +
 src/p11_front.c    |  7 +++++++
 src/p11_key.c      | 40 ++++++++++++++++++++++++++++++++++++++--
 8 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index b96ec83..43c00db 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 NEWS for Libp11 -- History of user visible changes
 
 New in 0.4.3; unreleased
+* Use UI to get the CKA_ALWAYS_AUTHENTICATE PIN (Michał Trojnara).
 
 New in 0.4.2; 2016-09-25; Michał Trojnara
 * Fixed a 0.4.0 regression bug causing the engine finish function to
diff --git a/src/eng_back.c b/src/eng_back.c
index 9948c8a..62f458a 100644
--- a/src/eng_back.c
+++ b/src/eng_back.c
@@ -808,6 +808,7 @@ static EVP_PKEY *pkcs11_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id,
 	}
 
 	if (selected_key != NULL) {
+		PKCS11_set_ui_method(selected_key, ui_method);
 		pk = isPrivate ?
 			PKCS11_get_private_key(selected_key) :
 			PKCS11_get_public_key(selected_key);
diff --git a/src/libp11-int.h b/src/libp11-int.h
index 10674a6..3929f65 100644
--- a/src/libp11-int.h
+++ b/src/libp11-int.h
@@ -94,6 +94,7 @@ typedef struct pkcs11_key_private {
 	PKCS11_TOKEN *parent;
 	CK_OBJECT_HANDLE object;
 	CK_BBOOL always_authenticate;
+	UI_METHOD *ui_method;
 	unsigned char id[255];
 	size_t id_len;
 	PKCS11_KEY_ops *ops;
@@ -274,6 +275,9 @@ extern PKCS11_KEY *pkcs11_find_key_from_key(PKCS11_KEY *key);
 extern int pkcs11_enumerate_certs(PKCS11_TOKEN *token,
 	PKCS11_CERT **certs, unsigned int *ncerts);
 
+/* Set UI method to allow retrieving PIN values interactively */
+extern int pkcs11_set_ui_method(PKCS11_KEY *key, UI_METHOD *ui_method);
+
 /* Initialize a token */
 extern int pkcs11_init_token(PKCS11_TOKEN * token, const char *pin,
 	const char *label);
diff --git a/src/libp11.exports b/src/libp11.exports
index 0f09c99..3ec2365 100644
--- a/src/libp11.exports
+++ b/src/libp11.exports
@@ -41,3 +41,4 @@ PKCS11_get_ec_key_method
 PKCS11_get_ecdsa_method
 PKCS11_get_ecdh_method
 ERR_load_PKCS11_strings
+PKCS11_set_ui_method
diff --git a/src/libp11.h b/src/libp11.h
index 068cb83..a1c521c 100644
--- a/src/libp11.h
+++ b/src/libp11.h
@@ -281,6 +281,9 @@ extern PKCS11_KEY *PKCS11_find_key_from_key(PKCS11_KEY *);
 /* Get a list of all certificates associated with this token */
 extern int PKCS11_enumerate_certs(PKCS11_TOKEN *, PKCS11_CERT **, unsigned int *);
 
+/* Set UI method to allow retrieving PIN values interactively */
+extern int PKCS11_set_ui_method(PKCS11_KEY *key, UI_METHOD *ui_method);
+
 /**
  * Initialize a token
  *
@@ -509,6 +512,7 @@ P11_DEPRECATED_FUNC extern int PKCS11_private_decrypt(
 #define PKCS11_NO_SESSION			(PKCS11_ERR_BASE+5)
 #define PKCS11_KEYGEN_FAILED			(PKCS11_ERR_BASE+6)
 #define PKCS11_ALIEN_KEY			(PKCS11_ERR_BASE+7)
+#define PKCS11_UI_FAILED			(PKCS11_ERR_BASE+8)
 
 #ifdef __cplusplus
 }
diff --git a/src/p11_err.c b/src/p11_err.c
index 8353bc9..8e9789b 100644
--- a/src/p11_err.c
+++ b/src/p11_err.c
@@ -58,6 +58,7 @@ static ERR_STRING_DATA PKCS11_str_reasons[] = {
 	{PKCS11_NOT_SUPPORTED, "Not supported"},
 	{PKCS11_NO_SESSION, "No session open"},
 	{PKCS11_ALIEN_KEY, "Not a PKCS#11 key"},
+	{PKCS11_UI_FAILED, "UI request failed"},
 	{CKR_CANCEL, "Cancel"},
 	{CKR_HOST_MEMORY, "Host memory error"},
 	{CKR_SLOT_ID_INVALID, "Invalid slot ID"},
diff --git a/src/p11_front.c b/src/p11_front.c
index f6500e3..f69031f 100644
--- a/src/p11_front.c
+++ b/src/p11_front.c
@@ -379,6 +379,13 @@ int PKCS11_generate_random(PKCS11_SLOT *slot, unsigned char *r, unsigned int r_l
 	return pkcs11_generate_random(slot, r, r_len);
 }
 
+int PKCS11_set_ui_method(PKCS11_KEY *key, UI_METHOD *ui_method)
+{
+	if (check_key_fork(key) < 0)
+		return -1;
+	return pkcs11_set_ui_method(key, ui_method);
+}
+
 /* External interface to the deprecated features */
 
 int PKCS11_generate_key(PKCS11_TOKEN *token,
diff --git a/src/p11_key.c b/src/p11_key.c
index bf58909..2b506ff 100644
--- a/src/p11_key.c
+++ b/src/p11_key.c
@@ -19,12 +19,16 @@
 
 #include "libp11-int.h"
 #include <string.h>
+#include <openssl/ui.h>
 #include <openssl/bn.h>
 
 #ifdef _WIN32
 #define strncasecmp strnicmp
 #endif
 
+/* The maximum length of PIN */
+#define MAX_PIN_LENGTH   32
+
 static int pkcs11_find_keys(PKCS11_TOKEN *, unsigned int);
 static int pkcs11_next_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
 	CK_SESSION_HANDLE session, CK_OBJECT_CLASS type);
@@ -34,6 +38,16 @@ static int pkcs11_init_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
 static int pkcs11_store_key(PKCS11_TOKEN *, EVP_PKEY *, unsigned int,
 	char *, unsigned char *, size_t, PKCS11_KEY **);
 
+/* Set UI method to allow retrieving PIN values interactively */
+int pkcs11_set_ui_method(PKCS11_KEY *key, UI_METHOD *ui_method)
+{
+	PKCS11_KEY_private *kpriv = PRIVKEY(key);
+	if (kpriv == NULL)
+		return -1;
+	kpriv->ui_method = ui_method;
+	return 0;
+}
+
 /*
  * Find key matching a certificate
  */
@@ -326,14 +340,36 @@ int pkcs11_authenticate(PKCS11_KEY *key)
 	PKCS11_SLOT *slot = KEY2SLOT(key);
 	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
 	PKCS11_CTX *ctx = SLOT2CTX(slot);
+	char pin[MAX_PIN_LENGTH];
+	UI *ui;
 	int rv;
 
 	if (!kpriv->always_authenticate)
 		return 0;
+
+	/* Call UI to ask for a PIN */
+	if (kpriv->ui_method == NULL)
+		return PKCS11_UI_FAILED;
+	ui = UI_new();
+	if (ui == NULL)
+		return PKCS11_UI_FAILED;
+	UI_set_method(ui, kpriv->ui_method);
+	if (!UI_add_input_string(ui, "PKCS#11 key PIN: ",
+			UI_INPUT_FLAG_DEFAULT_PWD, pin, 1, MAX_PIN_LENGTH)) {
+		UI_free(ui);
+		return PKCS11_UI_FAILED;
+	}
+	if (UI_process(ui)) {
+		UI_free(ui);
+		return PKCS11_UI_FAILED;
+	}
+	UI_free(ui);
+
+	/* Login with the PIN */
 	rv = CRYPTOKI_call(ctx,
 		C_Login(spriv->session, CKU_CONTEXT_SPECIFIC,
-			(CK_UTF8CHAR *)spriv->prev_pin,
-			spriv->prev_pin ? strlen(spriv->prev_pin) : 0));
+			(CK_UTF8CHAR *)pin, strlen(pin)));
+	OPENSSL_cleanse(pin, MAX_PIN_LENGTH);
 	if (rv == CKR_USER_ALREADY_LOGGED_IN) /* ignore */
 		rv = 0;
 	return rv;

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