summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/ssh-pkcs11.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/ssh-pkcs11.c')
-rw-r--r--crypto/openssh/ssh-pkcs11.c85
1 files changed, 54 insertions, 31 deletions
diff --git a/crypto/openssh/ssh-pkcs11.c b/crypto/openssh/ssh-pkcs11.c
index c49cbf4..92614a5 100644
--- a/crypto/openssh/ssh-pkcs11.c
+++ b/crypto/openssh/ssh-pkcs11.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-pkcs11.c,v 1.11 2013/11/13 13:48:20 markus Exp $ */
+/* $OpenBSD: ssh-pkcs11.c,v 1.21 2015/07/18 08:02:17 djm Exp $ */
/*
* Copyright (c) 2010 Markus Friedl. All rights reserved.
*
@@ -38,7 +38,7 @@
#include "log.h"
#include "misc.h"
-#include "key.h"
+#include "sshkey.h"
#include "ssh-pkcs11.h"
#include "xmalloc.h"
@@ -237,7 +237,7 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
{CKA_ID, NULL, 0},
{CKA_SIGN, NULL, sizeof(true_val) }
};
- char *pin, prompt[1024];
+ char *pin = NULL, prompt[1024];
int rval = -1;
key_filter[0].pValue = &private_key_class;
@@ -255,21 +255,30 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
si = &k11->provider->slotinfo[k11->slotidx];
if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
if (!pkcs11_interactive) {
- error("need pin");
+ error("need pin entry%s", (si->token.flags &
+ CKF_PROTECTED_AUTHENTICATION_PATH) ?
+ " on reader keypad" : "");
return (-1);
}
- snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ",
- si->token.label);
- pin = read_passphrase(prompt, RP_ALLOW_EOF);
- if (pin == NULL)
- return (-1); /* bail out */
- if ((rv = f->C_Login(si->session, CKU_USER,
- (u_char *)pin, strlen(pin))) != CKR_OK) {
+ if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
+ verbose("Deferring PIN entry to reader keypad.");
+ else {
+ snprintf(prompt, sizeof(prompt),
+ "Enter PIN for '%s': ", si->token.label);
+ pin = read_passphrase(prompt, RP_ALLOW_EOF);
+ if (pin == NULL)
+ return (-1); /* bail out */
+ }
+ rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
+ (pin != NULL) ? strlen(pin) : 0);
+ if (pin != NULL) {
+ explicit_bzero(pin, strlen(pin));
free(pin);
+ }
+ if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
error("C_Login failed: %lu", rv);
return (-1);
}
- free(pin);
si->logged_in = 1;
}
key_filter[1].pValue = k11->keyid;
@@ -366,8 +375,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin)
return (-1);
}
if (login_required && pin) {
- if ((rv = f->C_Login(session, CKU_USER,
- (u_char *)pin, strlen(pin))) != CKR_OK) {
+ rv = f->C_Login(session, CKU_USER,
+ (u_char *)pin, strlen(pin));
+ if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
error("C_Login failed: %lu", rv);
if ((rv = f->C_CloseSession(session)) != CKR_OK)
error("C_CloseSession failed: %lu", rv);
@@ -385,12 +395,12 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin)
* keysp points to an (possibly empty) array with *nkeys keys.
*/
static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG,
- CK_ATTRIBUTE [], CK_ATTRIBUTE [3], Key ***, int *)
+ CK_ATTRIBUTE [], CK_ATTRIBUTE [3], struct sshkey ***, int *)
__attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE))));
static int
pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
- Key ***keysp, int *nkeys)
+ struct sshkey ***keysp, int *nkeys)
{
CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY;
CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
@@ -422,12 +432,12 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
}
static int
-pkcs11_key_included(Key ***keysp, int *nkeys, Key *key)
+pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key)
{
int i;
for (i = 0; i < *nkeys; i++)
- if (key_equal(key, (*keysp)[i]))
+ if (sshkey_equal(key, (*keysp)[i]))
return (1);
return (0);
}
@@ -435,9 +445,9 @@ pkcs11_key_included(Key ***keysp, int *nkeys, Key *key)
static int
pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3],
- Key ***keysp, int *nkeys)
+ struct sshkey ***keysp, int *nkeys)
{
- Key *key;
+ struct sshkey *key;
RSA *rsa;
X509 *x509;
EVP_PKEY *evp;
@@ -471,15 +481,23 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
error("C_GetAttributeValue failed: %lu", rv);
continue;
}
- /* check that none of the attributes are zero length */
- if (attribs[0].ulValueLen == 0 ||
- attribs[1].ulValueLen == 0 ||
+ /*
+ * Allow CKA_ID (always first attribute) to be empty, but
+ * ensure that none of the others are zero length.
+ * XXX assumes CKA_ID is always first.
+ */
+ if (attribs[1].ulValueLen == 0 ||
attribs[2].ulValueLen == 0) {
continue;
}
/* allocate buffers for attributes */
- for (i = 0; i < 3; i++)
- attribs[i].pValue = xmalloc(attribs[i].ulValueLen);
+ for (i = 0; i < 3; i++) {
+ if (attribs[i].ulValueLen > 0) {
+ attribs[i].pValue = xmalloc(
+ attribs[i].ulValueLen);
+ }
+ }
+
/*
* retrieve ID, modulus and public exponent of RSA key,
* or ID, subject and value for certificates.
@@ -517,16 +535,16 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
}
if (rsa && rsa->n && rsa->e &&
pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
- key = key_new(KEY_UNSPEC);
+ key = sshkey_new(KEY_UNSPEC);
key->rsa = rsa;
key->type = KEY_RSA;
- key->flags |= KEY_FLAG_EXT;
+ key->flags |= SSHKEY_FLAG_EXT;
if (pkcs11_key_included(keysp, nkeys, key)) {
- key_free(key);
+ sshkey_free(key);
} else {
/* expand key array and add key */
- *keysp = xrealloc(*keysp, *nkeys + 1,
- sizeof(Key *));
+ *keysp = xreallocarray(*keysp, *nkeys + 1,
+ sizeof(struct sshkey *));
(*keysp)[*nkeys] = key;
*nkeys = *nkeys + 1;
debug("have %d keys", *nkeys);
@@ -544,7 +562,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
/* register a new provider, fails if provider already exists */
int
-pkcs11_add_provider(char *provider_id, char *pin, Key ***keyp)
+pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp)
{
int nkeys, need_finalize = 0;
struct pkcs11_provider *p = NULL;
@@ -621,6 +639,11 @@ pkcs11_add_provider(char *provider_id, char *pin, Key ***keyp)
error("C_GetTokenInfo failed: %lu", rv);
continue;
}
+ if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) {
+ debug2("%s: ignoring uninitialised token in slot %lu",
+ __func__, (unsigned long)i);
+ continue;
+ }
rmspace(token->label, sizeof(token->label));
rmspace(token->manufacturerID, sizeof(token->manufacturerID));
rmspace(token->model, sizeof(token->model));
OpenPOWER on IntegriCloud