]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream: expose PKCS#11 key labels/X.509 subjects as comments
authordjm@openbsd.org <djm@openbsd.org>
Sat, 25 Jan 2020 00:03:36 +0000 (00:03 +0000)
committerDamien Miller <djm@mindrot.org>
Sat, 25 Jan 2020 00:35:55 +0000 (11:35 +1100)
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
ssh-keygen.c
ssh-pkcs11-client.c
ssh-pkcs11-helper.c
ssh-pkcs11.c
ssh-pkcs11.h
ssh.c

index dd5d21d5a54a9389123581de778fa2ff020062ef..6092f19dc18d845e15e39e5d2eff663a78c31f4b 100644 (file)
@@ -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@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@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);
 }
 
index 2c9f67862a9980b4ac29856993e4c3cea98fd3af..14d2357a71bd515be7c92519a749d79b2ff63c2a 100644 (file)
@@ -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@cs.hut.fi>
  * Copyright (c) 1994 Tatu Ylonen <ylo@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");
index e7860de89815a0c208ae1994229bd943f072e40b..8a0ffef5dfb8224a549a4e93d274298148cee4be 100644 (file)
@@ -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) {
index 219ce9b5dd88294fe3b00de7e0133e067aa0378c..17220d62460790de3dddf1a6041b482e4b294cf6 100644 (file)
@@ -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);
index 09f1ea347cfab29af37eed0c0d2b1b8ead6cb96b..a302c79c0c18ce7ac9b9e3043f88332d20454591 100644 (file)
@@ -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);
index b9038450da8cf9ee908a07159b68e59fa3570c93..81f1d7c5d392781dd261468a8f6bbde7783bed5c 100644 (file)
@@ -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 851d85b50b76b46201ce5f3b5cd1faa035952d2d..8931ecf81cf0c750ade35efebf9b7649c681e052 100644 (file)
--- 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@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@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++) {