summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c55
1 files changed, 39 insertions, 16 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index cc092368e..89ef9a143 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.415 2020/08/03 02:53:51 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.416 2020/08/27 01:06:18 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -589,7 +589,7 @@ do_convert_private_ssh2(struct sshbuf *b)
589 589
590 /* try the key */ 590 /* try the key */
591 if (sshkey_sign(key, &sig, &slen, data, sizeof(data), 591 if (sshkey_sign(key, &sig, &slen, data, sizeof(data),
592 NULL, NULL, 0) != 0 || 592 NULL, NULL, NULL, 0) != 0 ||
593 sshkey_verify(key, sig, slen, data, sizeof(data), 593 sshkey_verify(key, sig, slen, data, sizeof(data),
594 NULL, 0, NULL) != 0) { 594 NULL, 0, NULL) != 0) {
595 sshkey_free(key); 595 sshkey_free(key);
@@ -1727,7 +1727,8 @@ load_pkcs11_key(char *path)
1727static int 1727static int
1728agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp, 1728agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp,
1729 const u_char *data, size_t datalen, 1729 const u_char *data, size_t datalen,
1730 const char *alg, const char *provider, u_int compat, void *ctx) 1730 const char *alg, const char *provider, const char *pin,
1731 u_int compat, void *ctx)
1731{ 1732{
1732 int *agent_fdp = (int *)ctx; 1733 int *agent_fdp = (int *)ctx;
1733 1734
@@ -1744,7 +1745,7 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
1744 u_int n; 1745 u_int n;
1745 struct sshkey *ca, *public; 1746 struct sshkey *ca, *public;
1746 char valid[64], *otmp, *tmp, *cp, *out, *comment; 1747 char valid[64], *otmp, *tmp, *cp, *out, *comment;
1747 char *ca_fp = NULL, **plist = NULL; 1748 char *ca_fp = NULL, **plist = NULL, *pin = NULL;
1748 struct ssh_identitylist *agent_ids; 1749 struct ssh_identitylist *agent_ids;
1749 size_t j; 1750 size_t j;
1750 struct notifier_ctx *notifier = NULL; 1751 struct notifier_ctx *notifier = NULL;
@@ -1785,6 +1786,12 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
1785 } else { 1786 } else {
1786 /* CA key is assumed to be a private key on the filesystem */ 1787 /* CA key is assumed to be a private key on the filesystem */
1787 ca = load_identity(tmp, NULL); 1788 ca = load_identity(tmp, NULL);
1789 if (sshkey_is_sk(ca) &&
1790 (ca->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
1791 if ((pin = read_passphrase("Enter PIN for CA key: ",
1792 RP_ALLOW_STDIN)) == NULL)
1793 fatal("%s: couldn't read PIN", __func__);
1794 }
1788 } 1795 }
1789 free(tmp); 1796 free(tmp);
1790 1797
@@ -1844,7 +1851,7 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
1844 1851
1845 if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) { 1852 if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) {
1846 if ((r = sshkey_certify_custom(public, ca, 1853 if ((r = sshkey_certify_custom(public, ca,
1847 key_type_name, sk_provider, agent_signer, 1854 key_type_name, sk_provider, NULL, agent_signer,
1848 &agent_fd)) != 0) 1855 &agent_fd)) != 0)
1849 fatal("Couldn't certify key %s via agent: %s", 1856 fatal("Couldn't certify key %s via agent: %s",
1850 tmp, ssh_err(r)); 1857 tmp, ssh_err(r));
@@ -1856,7 +1863,7 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
1856 sshkey_type(ca), ca_fp); 1863 sshkey_type(ca), ca_fp);
1857 } 1864 }
1858 r = sshkey_certify(public, ca, key_type_name, 1865 r = sshkey_certify(public, ca, key_type_name,
1859 sk_provider); 1866 sk_provider, pin);
1860 notify_complete(notifier); 1867 notify_complete(notifier);
1861 if (r != 0) 1868 if (r != 0)
1862 fatal("Couldn't certify key %s: %s", 1869 fatal("Couldn't certify key %s: %s",
@@ -1890,6 +1897,8 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
1890 if (cert_serial_autoinc) 1897 if (cert_serial_autoinc)
1891 cert_serial++; 1898 cert_serial++;
1892 } 1899 }
1900 if (pin != NULL)
1901 freezero(pin, strlen(pin));
1893 free(ca_fp); 1902 free(ca_fp);
1894#ifdef ENABLE_PKCS11 1903#ifdef ENABLE_PKCS11
1895 pkcs11_terminate(); 1904 pkcs11_terminate();
@@ -2526,6 +2535,7 @@ sign_one(struct sshkey *signkey, const char *filename, int fd,
2526 struct sshbuf *sigbuf = NULL, *abuf = NULL; 2535 struct sshbuf *sigbuf = NULL, *abuf = NULL;
2527 int r = SSH_ERR_INTERNAL_ERROR, wfd = -1, oerrno; 2536 int r = SSH_ERR_INTERNAL_ERROR, wfd = -1, oerrno;
2528 char *wfile = NULL, *asig = NULL, *fp = NULL; 2537 char *wfile = NULL, *asig = NULL, *fp = NULL;
2538 char *pin = NULL, *prompt = NULL;
2529 2539
2530 if (!quiet) { 2540 if (!quiet) {
2531 if (fd == STDIN_FILENO) 2541 if (fd == STDIN_FILENO)
@@ -2533,17 +2543,25 @@ sign_one(struct sshkey *signkey, const char *filename, int fd,
2533 else 2543 else
2534 fprintf(stderr, "Signing file %s\n", filename); 2544 fprintf(stderr, "Signing file %s\n", filename);
2535 } 2545 }
2536 if (signer == NULL && sshkey_is_sk(signkey) && 2546 if (signer == NULL && sshkey_is_sk(signkey)) {
2537 (signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) { 2547 if ((signkey->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
2538 if ((fp = sshkey_fingerprint(signkey, fingerprint_hash, 2548 xasprintf(&prompt, "Enter PIN for %s key: ",
2539 SSH_FP_DEFAULT)) == NULL) 2549 sshkey_type(signkey));
2540 fatal("%s: sshkey_fingerprint failed", __func__); 2550 if ((pin = read_passphrase(prompt,
2541 fprintf(stderr, "Confirm user presence for key %s %s\n", 2551 RP_ALLOW_STDIN)) == NULL)
2542 sshkey_type(signkey), fp); 2552 fatal("%s: couldn't read PIN", __func__);
2543 free(fp); 2553 }
2554 if ((signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
2555 if ((fp = sshkey_fingerprint(signkey, fingerprint_hash,
2556 SSH_FP_DEFAULT)) == NULL)
2557 fatal("%s: fingerprint failed", __func__);
2558 fprintf(stderr, "Confirm user presence for key %s %s\n",
2559 sshkey_type(signkey), fp);
2560 free(fp);
2561 }
2544 } 2562 }
2545 if ((r = sshsig_sign_fd(signkey, NULL, sk_provider, fd, sig_namespace, 2563 if ((r = sshsig_sign_fd(signkey, NULL, sk_provider, pin,
2546 &sigbuf, signer, signer_ctx)) != 0) { 2564 fd, sig_namespace, &sigbuf, signer, signer_ctx)) != 0) {
2547 error("Signing %s failed: %s", filename, ssh_err(r)); 2565 error("Signing %s failed: %s", filename, ssh_err(r));
2548 goto out; 2566 goto out;
2549 } 2567 }
@@ -2591,7 +2609,10 @@ sign_one(struct sshkey *signkey, const char *filename, int fd,
2591 r = 0; 2609 r = 0;
2592 out: 2610 out:
2593 free(wfile); 2611 free(wfile);
2612 free(prompt);
2594 free(asig); 2613 free(asig);
2614 if (pin != NULL)
2615 freezero(pin, strlen(pin));
2595 sshbuf_free(abuf); 2616 sshbuf_free(abuf);
2596 sshbuf_free(sigbuf); 2617 sshbuf_free(sigbuf);
2597 if (wfd != -1) 2618 if (wfd != -1)
@@ -3554,6 +3575,8 @@ main(int argc, char **argv)
3554 for (i = 0; i < nopts; i++) { 3575 for (i = 0; i < nopts; i++) {
3555 if (strcasecmp(opts[i], "no-touch-required") == 0) { 3576 if (strcasecmp(opts[i], "no-touch-required") == 0) {
3556 sk_flags &= ~SSH_SK_USER_PRESENCE_REQD; 3577 sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;
3578 } else if (strcasecmp(opts[i], "verify-required") == 0) {
3579 sk_flags |= SSH_SK_USER_VERIFICATION_REQD;
3557 } else if (strcasecmp(opts[i], "resident") == 0) { 3580 } else if (strcasecmp(opts[i], "resident") == 0) {
3558 sk_flags |= SSH_SK_RESIDENT_KEY; 3581 sk_flags |= SSH_SK_RESIDENT_KEY;
3559 } else if (strncasecmp(opts[i], "device=", 7) == 0) { 3582 } else if (strncasecmp(opts[i], "device=", 7) == 0) {