diff --git a/ssh-agent.c b/ssh-agent.c index dd5d21d5a54a..6092f19dc18d 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 * Copyright (c) 1995 Tatu Ylonen , 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 2c9f67862a99..14d2357a71bd 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 * Copyright (c) 1994 Tatu Ylonen , 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 e7860de89815..8a0ffef5dfb8 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 219ce9b5dd88..17220d624607 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 09f1ea347cfa..a302c79c0c18 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 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, 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 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, #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 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, */ 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 @@ pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, * 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 b9038450da8c..81f1d7c5d392 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 851d85b50b76..8931ecf81cf0 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 * Copyright (c) 1995 Tatu Ylonen , 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++) {