[openssh-commits] [openssh] 08/11: upstream: expose PKCS#11 key labels/X.509 subjects as comments

git+noreply at mindrot.org git+noreply at mindrot.org
Sat Jan 25 11:36:34 AEDT 2020


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 89a8d4525e8edd9958ed3df60cf683551142eae0
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Sat Jan 25 00:03:36 2020 +0000

    upstream: expose PKCS#11 key labels/X.509 subjects as comments
    
    Extract the key label or X.509 subject string when PKCS#11 keys
    are retrieved from the token and plumb this through to places where
    it may be used as a comment.
    
    based on https://github.com/openssh/openssh-portable/pull/138
    by Danielle Church
    
    feedback and ok markus@
    
    OpenBSD-Commit-ID: cae1fda10d9e10971dea29520916e27cfec7ca35
---
 ssh-agent.c         |  19 ++++---
 ssh-keygen.c        |  14 ++++--
 ssh-pkcs11-client.c |  14 ++++--
 ssh-pkcs11-helper.c |  21 +++++---
 ssh-pkcs11.c        | 142 ++++++++++++++++++++++++++++++++--------------------
 ssh-pkcs11.h        |   4 +-
 ssh.c               |  12 +++--
 7 files changed, 144 insertions(+), 82 deletions(-)

diff --git a/ssh-agent.c b/ssh-agent.c
index dd5d21d5..6092f19d 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.252 2020/01/23 07:10:22 dtucker Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.253 2020/01/25 00:03:36 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -633,6 +633,7 @@ static void
 process_add_smartcard_key(SocketEntry *e)
 {
 	char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX];
+	char **comments = NULL;
 	int r, i, count = 0, success = 0, confirm = 0;
 	u_int seconds;
 	time_t death = 0;
@@ -682,28 +683,34 @@ process_add_smartcard_key(SocketEntry *e)
 	if (lifetime && !death)
 		death = monotime() + lifetime;
 
-	count = pkcs11_add_provider(canonical_provider, pin, &keys);
+	count = pkcs11_add_provider(canonical_provider, pin, &keys, &comments);
 	for (i = 0; i < count; i++) {
 		k = keys[i];
 		if (lookup_identity(k) == NULL) {
 			id = xcalloc(1, sizeof(Identity));
 			id->key = k;
+			keys[i] = NULL; /* transferred */
 			id->provider = xstrdup(canonical_provider);
-			id->comment = xstrdup(canonical_provider); /* XXX */
+			if (*comments[i] != '\0') {
+				id->comment = comments[i];
+				comments[i] = NULL; /* transferred */
+			} else {
+				id->comment = xstrdup(canonical_provider);
+			}
 			id->death = death;
 			id->confirm = confirm;
 			TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
 			idtab->nentries++;
 			success = 1;
-		} else {
-			sshkey_free(k);
 		}
-		keys[i] = NULL;
+		sshkey_free(keys[i]);
+		free(comments[i]);
 	}
 send:
 	free(pin);
 	free(provider);
 	free(keys);
+	free(comments);
 	send_status(e, success);
 }
 
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 2c9f6786..14d2357a 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.391 2020/01/24 05:33:01 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.392 2020/01/25 00:03:36 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1994 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -829,13 +829,13 @@ do_download(struct passwd *pw)
 	int i, nkeys;
 	enum sshkey_fp_rep rep;
 	int fptype;
-	char *fp, *ra;
+	char *fp, *ra, **comments = NULL;
 
 	fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
 	rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
 
 	pkcs11_init(1);
-	nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys);
+	nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys, &comments);
 	if (nkeys <= 0)
 		fatal("cannot read public key from pkcs11");
 	for (i = 0; i < nkeys; i++) {
@@ -853,10 +853,13 @@ do_download(struct passwd *pw)
 			free(fp);
 		} else {
 			(void) sshkey_write(keys[i], stdout); /* XXX check */
-			fprintf(stdout, "\n");
+			fprintf(stdout, "%s%s\n",
+			    *(comments[i]) == '\0' ? "" : " ", comments[i]);
 		}
+		free(comments[i]);
 		sshkey_free(keys[i]);
 	}
+	free(comments);
 	free(keys);
 	pkcs11_terminate();
 	exit(0);
@@ -1703,7 +1706,8 @@ load_pkcs11_key(char *path)
 		fatal("Couldn't load CA public key \"%s\": %s",
 		    path, ssh_err(r));
 
-	nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys);
+	nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase,
+	    &keys, NULL);
 	debug3("%s: %d keys", __func__, nkeys);
 	if (nkeys <= 0)
 		fatal("cannot read public key from pkcs11");
diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c
index e7860de8..8a0ffef5 100644
--- a/ssh-pkcs11-client.c
+++ b/ssh-pkcs11-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-pkcs11-client.c,v 1.15 2019/01/21 12:53:35 djm Exp $ */
+/* $OpenBSD: ssh-pkcs11-client.c,v 1.16 2020/01/25 00:03:36 djm Exp $ */
 /*
  * Copyright (c) 2010 Markus Friedl.  All rights reserved.
  * Copyright (c) 2014 Pedro Martelletto. All rights reserved.
@@ -312,11 +312,13 @@ pkcs11_start_helper(void)
 }
 
 int
-pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp)
+pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
+    char ***labelsp)
 {
 	struct sshkey *k;
 	int r, type;
 	u_char *blob;
+	char *label;
 	size_t blen;
 	u_int nkeys, i;
 	struct sshbuf *msg;
@@ -338,16 +340,22 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp)
 		if ((r = sshbuf_get_u32(msg, &nkeys)) != 0)
 			fatal("%s: buffer error: %s", __func__, ssh_err(r));
 		*keysp = xcalloc(nkeys, sizeof(struct sshkey *));
+		if (labelsp)
+			*labelsp = xcalloc(nkeys, sizeof(char *));
 		for (i = 0; i < nkeys; i++) {
 			/* XXX clean up properly instead of fatal() */
 			if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 ||
-			    (r = sshbuf_skip_string(msg)) != 0)
+			    (r = sshbuf_get_cstring(msg, &label, NULL)) != 0)
 				fatal("%s: buffer error: %s",
 				    __func__, ssh_err(r));
 			if ((r = sshkey_from_blob(blob, blen, &k)) != 0)
 				fatal("%s: bad key: %s", __func__, ssh_err(r));
 			wrap_key(k);
 			(*keysp)[i] = k;
+			if (labelsp)
+				(*labelsp)[i] = label;
+			else
+				free(label);
 			free(blob);
 		}
 	} else if (type == SSH2_AGENT_FAILURE) {
diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c
index 219ce9b5..17220d62 100644
--- a/ssh-pkcs11-helper.c
+++ b/ssh-pkcs11-helper.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-pkcs11-helper.c,v 1.21 2019/09/06 05:23:55 djm Exp $ */
+/* $OpenBSD: ssh-pkcs11-helper.c,v 1.22 2020/01/25 00:03:36 djm Exp $ */
 /*
  * Copyright (c) 2010 Markus Friedl.  All rights reserved.
  *
@@ -50,7 +50,7 @@
 
 struct pkcs11_keyinfo {
 	struct sshkey	*key;
-	char		*providername;
+	char		*providername, *label;
 	TAILQ_ENTRY(pkcs11_keyinfo) next;
 };
 
@@ -63,13 +63,14 @@ struct sshbuf *iqueue;
 struct sshbuf *oqueue;
 
 static void
-add_key(struct sshkey *k, char *name)
+add_key(struct sshkey *k, char *name, char *label)
 {
 	struct pkcs11_keyinfo *ki;
 
 	ki = xcalloc(1, sizeof(*ki));
 	ki->providername = xstrdup(name);
 	ki->key = k;
+	ki->label = xstrdup(label);
 	TAILQ_INSERT_TAIL(&pkcs11_keylist, ki, next);
 }
 
@@ -83,6 +84,7 @@ del_keys_by_name(char *name)
 		if (!strcmp(ki->providername, name)) {
 			TAILQ_REMOVE(&pkcs11_keylist, ki, next);
 			free(ki->providername);
+			free(ki->label);
 			sshkey_free(ki->key);
 			free(ki);
 		}
@@ -96,7 +98,7 @@ lookup_key(struct sshkey *k)
 	struct pkcs11_keyinfo *ki;
 
 	TAILQ_FOREACH(ki, &pkcs11_keylist, next) {
-		debug("check %p %s", ki, ki->providername);
+		debug("check %p %s %s", ki, ki->providername, ki->label);
 		if (sshkey_equal(k, ki->key))
 			return (ki->key);
 	}
@@ -121,13 +123,14 @@ process_add(void)
 	u_char *blob;
 	size_t blen;
 	struct sshbuf *msg;
+	char **labels = NULL;
 
 	if ((msg = sshbuf_new()) == NULL)
 		fatal("%s: sshbuf_new failed", __func__);
 	if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
 	    (r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0)
 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
-	if ((nkeys = pkcs11_add_provider(name, pin, &keys)) > 0) {
+	if ((nkeys = pkcs11_add_provider(name, pin, &keys, &labels)) > 0) {
 		if ((r = sshbuf_put_u8(msg,
 		    SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
 		    (r = sshbuf_put_u32(msg, nkeys)) != 0)
@@ -139,11 +142,12 @@ process_add(void)
 				continue;
 			}
 			if ((r = sshbuf_put_string(msg, blob, blen)) != 0 ||
-			    (r = sshbuf_put_cstring(msg, name)) != 0)
+			    (r = sshbuf_put_cstring(msg, labels[i])) != 0)
 				fatal("%s: buffer error: %s",
 				    __func__, ssh_err(r));
 			free(blob);
-			add_key(keys[i], name);
+			add_key(keys[i], name, labels[i]);
+			free(labels[i]);
 		}
 	} else {
 		if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
@@ -151,7 +155,8 @@ process_add(void)
 		if ((r = sshbuf_put_u32(msg, -nkeys)) != 0)
 			fatal("%s: buffer error: %s", __func__, ssh_err(r));
 	}
-	free(keys);
+	free(labels);
+	free(keys); /* keys themselves are transferred to pkcs11_keylist */
 	free(pin);
 	free(name);
 	send_msg(msg);
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
index 09f1ea34..a302c79c 100644
--- a/ssh-pkcs11.c
+++ b/ssh-pkcs11.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-pkcs11.c,v 1.46 2019/10/01 10:22:53 djm Exp $ */
+/* $OpenBSD: ssh-pkcs11.c,v 1.47 2020/01/25 00:03:36 djm Exp $ */
 /*
  * Copyright (c) 2010 Markus Friedl.  All rights reserved.
  * Copyright (c) 2014 Pedro Martelletto. All rights reserved.
@@ -893,15 +893,16 @@ fail:
 	return (key);
 }
 
-static struct sshkey *
+static int
 pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
-    CK_OBJECT_HANDLE *obj)
+    CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp)
 {
 	CK_ATTRIBUTE		 cert_attr[3];
 	CK_SESSION_HANDLE	 session;
 	CK_FUNCTION_LIST	*f = NULL;
 	CK_RV			 rv;
 	X509			*x509 = NULL;
+	X509_NAME		*x509_name = NULL;
 	EVP_PKEY		*evp;
 	RSA			*rsa = NULL;
 #ifdef OPENSSL_HAS_ECC
@@ -912,7 +913,11 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
 #ifdef HAVE_EC_KEY_METHOD_NEW
 	int			 nid;
 #endif
-	const u_char		 *cp;
+	const u_char		*cp;
+	char			*subject = NULL;
+
+	*keyp = NULL;
+	*labelp = NULL;
 
 	memset(&cert_attr, 0, sizeof(cert_attr));
 	cert_attr[0].type = CKA_ID;
@@ -926,7 +931,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
 	rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3);
 	if (rv != CKR_OK) {
 		error("C_GetAttributeValue failed: %lu", rv);
-		return (NULL);
+		return -1;
 	}
 
 	/*
@@ -937,7 +942,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
 	if (cert_attr[1].ulValueLen == 0 ||
 	    cert_attr[2].ulValueLen == 0) {
 		error("invalid attribute length");
-		return (NULL);
+		return -1;
 	}
 
 	/* allocate buffers for attributes */
@@ -949,44 +954,45 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
 	rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3);
 	if (rv != CKR_OK) {
 		error("C_GetAttributeValue failed: %lu", rv);
-		goto fail;
+		goto out;
 	}
 
-	x509 = X509_new();
-	if (x509 == NULL) {
-		error("x509_new failed");
-		goto fail;
-	}
+	/* Decode DER-encoded cert subject */
+	cp = cert_attr[2].pValue;
+	if ((x509_name = d2i_X509_NAME(NULL, &cp,
+	    cert_attr[1].ulValueLen)) == NULL ||
+	    (subject = X509_NAME_oneline(x509_name, NULL, 0)) == NULL)
+		subject = xstrdup("invalid subject");
+	X509_NAME_free(x509_name);
 
 	cp = cert_attr[2].pValue;
-	if (d2i_X509(&x509, &cp, cert_attr[2].ulValueLen) == NULL) {
+	if ((x509 = d2i_X509(NULL, &cp, cert_attr[2].ulValueLen)) == NULL) {
 		error("d2i_x509 failed");
-		goto fail;
+		goto out;
 	}
 
-	evp = X509_get_pubkey(x509);
-	if (evp == NULL) {
+	if ((evp = X509_get_pubkey(x509)) == NULL) {
 		error("X509_get_pubkey failed");
-		goto fail;
+		goto out;
 	}
 
 	if (EVP_PKEY_base_id(evp) == EVP_PKEY_RSA) {
 		if (EVP_PKEY_get0_RSA(evp) == NULL) {
 			error("invalid x509; no rsa key");
-			goto fail;
+			goto out;
 		}
 		if ((rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(evp))) == NULL) {
 			error("RSAPublicKey_dup failed");
-			goto fail;
+			goto out;
 		}
 
 		if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa))
-			goto fail;
+			goto out;
 
 		key = sshkey_new(KEY_UNSPEC);
 		if (key == NULL) {
 			error("sshkey_new failed");
-			goto fail;
+			goto out;
 		}
 
 		key->rsa = rsa;
@@ -997,26 +1003,26 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
 	} else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) {
 		if (EVP_PKEY_get0_EC_KEY(evp) == NULL) {
 			error("invalid x509; no ec key");
-			goto fail;
+			goto out;
 		}
 		if ((ec = EC_KEY_dup(EVP_PKEY_get0_EC_KEY(evp))) == NULL) {
 			error("EC_KEY_dup failed");
-			goto fail;
+			goto out;
 		}
 
 		nid = sshkey_ecdsa_key_to_nid(ec);
 		if (nid < 0) {
 			error("couldn't get curve nid");
-			goto fail;
+			goto out;
 		}
 
 		if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec))
-			goto fail;
+			goto out;
 
 		key = sshkey_new(KEY_UNSPEC);
 		if (key == NULL) {
 			error("sshkey_new failed");
-			goto fail;
+			goto out;
 		}
 
 		key->ecdsa = ec;
@@ -1025,10 +1031,11 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
 		key->flags |= SSHKEY_FLAG_EXT;
 		ec = NULL;	/* now owned by key */
 #endif /* HAVE_EC_KEY_METHOD_NEW */
-	} else
+	} else {
 		error("unknown certificate key type");
-
-fail:
+		goto out;
+	}
+ out:
 	for (i = 0; i < 3; i++)
 		free(cert_attr[i].pValue);
 	X509_free(x509);
@@ -1036,8 +1043,14 @@ fail:
 #ifdef OPENSSL_HAS_ECC
 	EC_KEY_free(ec);
 #endif
-
-	return (key);
+	if (key == NULL) {
+		free(subject);
+		return -1;
+	}
+	/* success */
+	*keyp = key;
+	*labelp = subject;
+	return 0;
 }
 
 #if 0
@@ -1058,7 +1071,7 @@ have_rsa_key(const RSA *rsa)
  */
 static int
 pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx,
-    struct sshkey ***keysp, int *nkeys)
+    struct sshkey ***keysp, char ***labelsp, int *nkeys)
 {
 	struct sshkey		*key = NULL;
 	CK_OBJECT_CLASS		 key_class;
@@ -1069,6 +1082,7 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx,
 	CK_OBJECT_HANDLE	 obj;
 	CK_ULONG		 n = 0;
 	int			 ret = -1;
+	char			*label;
 
 	memset(&key_attr, 0, sizeof(key_attr));
 	memset(&obj, 0, sizeof(obj));
@@ -1110,18 +1124,19 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx,
 			goto fail;
 		}
 
+		key = NULL;
+		label = NULL;
 		switch (ck_cert_type) {
 		case CKC_X_509:
-			key = pkcs11_fetch_x509_pubkey(p, slotidx, &obj);
+			if (pkcs11_fetch_x509_pubkey(p, slotidx, &obj,
+			    &key, &label) != 0) {
+				error("failed to fetch key");
+				continue;
+			}
 			break;
 		default:
-			/* XXX print key type? */
-			key = NULL;
-			error("skipping unsupported certificate type");
-		}
-
-		if (key == NULL) {
-			error("failed to fetch key");
+			error("skipping unsupported certificate type %lu",
+			    ck_cert_type);
 			continue;
 		}
 
@@ -1132,6 +1147,11 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx,
 			*keysp = xrecallocarray(*keysp, *nkeys,
 			    *nkeys + 1, sizeof(struct sshkey *));
 			(*keysp)[*nkeys] = key;
+			if (labelsp != NULL) {
+				*labelsp = xrecallocarray(*labelsp, *nkeys,
+				    *nkeys + 1, sizeof(char *));
+				(*labelsp)[*nkeys] = xstrdup((char *)label);
+			}
 			*nkeys = *nkeys + 1;
 			debug("have %d keys", *nkeys);
 		}
@@ -1155,11 +1175,11 @@ fail:
  */
 static int
 pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
-    struct sshkey ***keysp, int *nkeys)
+    struct sshkey ***keysp, char ***labelsp, int *nkeys)
 {
 	struct sshkey		*key = NULL;
 	CK_OBJECT_CLASS		 key_class;
-	CK_ATTRIBUTE		 key_attr[1];
+	CK_ATTRIBUTE		 key_attr[2];
 	CK_SESSION_HANDLE	 session;
 	CK_FUNCTION_LIST	*f = NULL;
 	CK_RV			 rv;
@@ -1186,6 +1206,7 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
 
 	while (1) {
 		CK_KEY_TYPE	ck_key_type;
+		CK_UTF8CHAR	label[256];
 
 		rv = f->C_FindObjects(session, &obj, 1, &n);
 		if (rv != CKR_OK) {
@@ -1200,13 +1221,18 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
 		key_attr[0].type = CKA_KEY_TYPE;
 		key_attr[0].pValue = &ck_key_type;
 		key_attr[0].ulValueLen = sizeof(ck_key_type);
+		key_attr[1].type = CKA_LABEL;
+		key_attr[1].pValue = &label;
+		key_attr[1].ulValueLen = sizeof(label) - 1;
 
-		rv = f->C_GetAttributeValue(session, obj, key_attr, 1);
+		rv = f->C_GetAttributeValue(session, obj, key_attr, 2);
 		if (rv != CKR_OK) {
 			error("C_GetAttributeValue failed: %lu", rv);
 			goto fail;
 		}
 
+		label[key_attr[1].ulValueLen] = '\0';
+
 		switch (ck_key_type) {
 		case CKK_RSA:
 			key = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj);
@@ -1234,6 +1260,11 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
 			*keysp = xrecallocarray(*keysp, *nkeys,
 			    *nkeys + 1, sizeof(struct sshkey *));
 			(*keysp)[*nkeys] = key;
+			if (labelsp != NULL) {
+				*labelsp = xrecallocarray(*labelsp, *nkeys,
+				    *nkeys + 1, sizeof(char *));
+				(*labelsp)[*nkeys] = xstrdup((char *)label);
+			}
 			*nkeys = *nkeys + 1;
 			debug("have %d keys", *nkeys);
 		}
@@ -1440,7 +1471,8 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx,
  * keyp is provided, fetch keys.
  */
 static int
-pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp,
+pkcs11_register_provider(char *provider_id, char *pin,
+    struct sshkey ***keyp, char ***labelsp,
     struct pkcs11_provider **providerp, CK_ULONG user)
 {
 	int nkeys, need_finalize = 0;
@@ -1459,6 +1491,8 @@ pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp,
 
 	if (keyp != NULL)
 		*keyp = NULL;
+	if (labelsp != NULL)
+		*labelsp = NULL;
 
 	if (pkcs11_provider_lookup(provider_id) != NULL) {
 		debug("%s: provider already registered: %s",
@@ -1556,8 +1590,8 @@ pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp,
 		if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 ||
 		    keyp == NULL)
 			continue;
-		pkcs11_fetch_keys(p, i, keyp, &nkeys);
-		pkcs11_fetch_certs(p, i, keyp, &nkeys);
+		pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys);
+		pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys);
 		if (nkeys == 0 && !p->slotinfo[i].logged_in &&
 		    pkcs11_interactive) {
 			/*
@@ -1569,8 +1603,8 @@ pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp,
 				error("login failed");
 				continue;
 			}
-			pkcs11_fetch_keys(p, i, keyp, &nkeys);
-			pkcs11_fetch_certs(p, i, keyp, &nkeys);
+			pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys);
+			pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys);
 		}
 	}
 
@@ -1601,12 +1635,14 @@ fail:
  * fails if provider already exists
  */
 int
-pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp)
+pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp,
+    char ***labelsp)
 {
 	struct pkcs11_provider *p = NULL;
 	int nkeys;
 
-	nkeys = pkcs11_register_provider(provider_id, pin, keyp, &p, CKU_USER);
+	nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp,
+	    &p, CKU_USER);
 
 	/* no keys found or some other error, de-register provider */
 	if (nkeys <= 0 && p != NULL) {
@@ -1638,8 +1674,8 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label,
 
 	if ((p = pkcs11_provider_lookup(provider_id)) != NULL)
 		debug("%s: provider \"%s\" available", __func__, provider_id);
-	else if ((ret = pkcs11_register_provider(provider_id, pin, NULL, &p,
-	    CKU_SO)) < 0) {
+	else if ((ret = pkcs11_register_provider(provider_id, pin, NULL, NULL,
+	    &p, CKU_SO)) < 0) {
 		debug("%s: could not register provider %s", __func__,
 		    provider_id);
 		goto out;
@@ -1710,7 +1746,7 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx,
 
 	if ((p = pkcs11_provider_lookup(provider_id)) != NULL) {
 		debug("%s: using provider \"%s\"", __func__, provider_id);
-	} else if (pkcs11_register_provider(provider_id, pin, NULL, &p,
+	} else if (pkcs11_register_provider(provider_id, pin, NULL, NULL, &p,
 	    CKU_SO) < 0) {
 		debug("%s: could not register provider %s", __func__,
 		    provider_id);
diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h
index b9038450..81f1d7c5 100644
--- a/ssh-pkcs11.h
+++ b/ssh-pkcs11.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-pkcs11.h,v 1.5 2019/01/20 22:51:37 djm Exp $ */
+/* $OpenBSD: ssh-pkcs11.h,v 1.6 2020/01/25 00:03:36 djm Exp $ */
 /*
  * Copyright (c) 2010 Markus Friedl.  All rights reserved.
  *
@@ -24,7 +24,7 @@
 
 int	pkcs11_init(int);
 void	pkcs11_terminate(void);
-int	pkcs11_add_provider(char *, char *, struct sshkey ***);
+int	pkcs11_add_provider(char *, char *, struct sshkey ***, char ***);
 int	pkcs11_del_provider(char *);
 #ifdef WITH_PKCS11_KEYGEN
 struct sshkey *
diff --git a/ssh.c b/ssh.c
index 851d85b5..8931ecf8 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.513 2020/01/23 10:24:29 dtucker Exp $ */
+/* $OpenBSD: ssh.c,v 1.514 2020/01/25 00:03:36 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -2072,7 +2072,8 @@ load_public_identity_files(struct passwd *pw)
 	struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
 	int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES];
 #ifdef ENABLE_PKCS11
-	struct sshkey **keys;
+	struct sshkey **keys = NULL;
+	char **comments = NULL;
 	int nkeys;
 #endif /* PKCS11 */
 
@@ -2091,18 +2092,19 @@ load_public_identity_files(struct passwd *pw)
 	    options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
 	    (pkcs11_init(!options.batch_mode) == 0) &&
 	    (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL,
-	    &keys)) > 0) {
+	    &keys, &comments)) > 0) {
 		for (i = 0; i < nkeys; i++) {
 			if (n_ids >= SSH_MAX_IDENTITY_FILES) {
 				sshkey_free(keys[i]);
+				free(comments[i]);
 				continue;
 			}
 			identity_keys[n_ids] = keys[i];
-			identity_files[n_ids] =
-			    xstrdup(options.pkcs11_provider); /* XXX */
+			identity_files[n_ids] = comments[i]; /* transferred */
 			n_ids++;
 		}
 		free(keys);
+		free(comments);
 	}
 #endif /* ENABLE_PKCS11 */
 	for (i = 0; i < options.num_identity_files; i++) {

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list