[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