summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2020-02-21 11:57:14 +0000
committerColin Watson <cjwatson@debian.org>2020-02-21 14:27:02 +0000
commit886e47e745586c34e81cfd5c5fb9b5dbc8e84d04 (patch)
treedd6c3b4dc64a17c520af7aaf213163f8a0a63e56 /ssh-keygen.c
parentac2b4c0697fcac554041ab95f81736887eadf6ec (diff)
parenta2dabf35ce0228c86a288d11cc847a9d9801604f (diff)
New upstream release (8.2p1)
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c828
1 files changed, 603 insertions, 225 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 8c829cad6..0d6ed1fff 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.355 2019/10/03 17:07:50 jmc Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.398 2020/02/07 03:27:54 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
@@ -63,6 +63,8 @@
63#include "utf8.h" 63#include "utf8.h"
64#include "authfd.h" 64#include "authfd.h"
65#include "sshsig.h" 65#include "sshsig.h"
66#include "ssh-sk.h"
67#include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */
66 68
67#ifdef WITH_OPENSSL 69#ifdef WITH_OPENSSL
68# define DEFAULT_KEY_TYPE_NAME "rsa" 70# define DEFAULT_KEY_TYPE_NAME "rsa"
@@ -118,11 +120,12 @@ static u_int64_t cert_valid_from = 0;
118static u_int64_t cert_valid_to = ~0ULL; 120static u_int64_t cert_valid_to = ~0ULL;
119 121
120/* Certificate options */ 122/* Certificate options */
121#define CERTOPT_X_FWD (1) 123#define CERTOPT_X_FWD (1)
122#define CERTOPT_AGENT_FWD (1<<1) 124#define CERTOPT_AGENT_FWD (1<<1)
123#define CERTOPT_PORT_FWD (1<<2) 125#define CERTOPT_PORT_FWD (1<<2)
124#define CERTOPT_PTY (1<<3) 126#define CERTOPT_PTY (1<<3)
125#define CERTOPT_USER_RC (1<<4) 127#define CERTOPT_USER_RC (1<<4)
128#define CERTOPT_NO_REQUIRE_USER_PRESENCE (1<<5)
126#define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \ 129#define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \
127 CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC) 130 CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC)
128static u_int32_t certflags_flags = CERTOPT_DEFAULT; 131static u_int32_t certflags_flags = CERTOPT_DEFAULT;
@@ -150,16 +153,16 @@ static char *key_type_name = NULL;
150/* Load key from this PKCS#11 provider */ 153/* Load key from this PKCS#11 provider */
151static char *pkcs11provider = NULL; 154static char *pkcs11provider = NULL;
152 155
156/* FIDO/U2F provider to use */
157static char *sk_provider = NULL;
158
153/* Format for writing private keys */ 159/* Format for writing private keys */
154static int private_key_format = SSHKEY_PRIVATE_OPENSSH; 160static int private_key_format = SSHKEY_PRIVATE_OPENSSH;
155 161
156/* Cipher for new-format private keys */ 162/* Cipher for new-format private keys */
157static char *openssh_format_cipher = NULL; 163static char *openssh_format_cipher = NULL;
158 164
159/* 165/* Number of KDF rounds to derive new format keys. */
160 * Number of KDF rounds to derive new format keys /
161 * number of primality trials when screening moduli.
162 */
163static int rounds = 0; 166static int rounds = 0;
164 167
165/* argv0 */ 168/* argv0 */
@@ -269,6 +272,10 @@ ask_filename(struct passwd *pw, const char *prompt)
269 case KEY_ECDSA: 272 case KEY_ECDSA:
270 name = _PATH_SSH_CLIENT_ID_ECDSA; 273 name = _PATH_SSH_CLIENT_ID_ECDSA;
271 break; 274 break;
275 case KEY_ECDSA_SK_CERT:
276 case KEY_ECDSA_SK:
277 name = _PATH_SSH_CLIENT_ID_ECDSA_SK;
278 break;
272#endif 279#endif
273 case KEY_RSA_CERT: 280 case KEY_RSA_CERT:
274 case KEY_RSA: 281 case KEY_RSA:
@@ -278,6 +285,10 @@ ask_filename(struct passwd *pw, const char *prompt)
278 case KEY_ED25519_CERT: 285 case KEY_ED25519_CERT:
279 name = _PATH_SSH_CLIENT_ID_ED25519; 286 name = _PATH_SSH_CLIENT_ID_ED25519;
280 break; 287 break;
288 case KEY_ED25519_SK:
289 case KEY_ED25519_SK_CERT:
290 name = _PATH_SSH_CLIENT_ID_ED25519_SK;
291 break;
281 case KEY_XMSS: 292 case KEY_XMSS:
282 case KEY_XMSS_CERT: 293 case KEY_XMSS_CERT:
283 name = _PATH_SSH_CLIENT_ID_XMSS; 294 name = _PATH_SSH_CLIENT_ID_XMSS;
@@ -391,6 +402,16 @@ do_convert_to_pem(struct sshkey *k)
391 if (!PEM_write_RSAPublicKey(stdout, k->rsa)) 402 if (!PEM_write_RSAPublicKey(stdout, k->rsa))
392 fatal("PEM_write_RSAPublicKey failed"); 403 fatal("PEM_write_RSAPublicKey failed");
393 break; 404 break;
405 case KEY_DSA:
406 if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
407 fatal("PEM_write_DSA_PUBKEY failed");
408 break;
409#ifdef OPENSSL_HAS_ECC
410 case KEY_ECDSA:
411 if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
412 fatal("PEM_write_EC_PUBKEY failed");
413 break;
414#endif
394 default: 415 default:
395 fatal("%s: unsupported key type %s", __func__, sshkey_type(k)); 416 fatal("%s: unsupported key type %s", __func__, sshkey_type(k));
396 } 417 }
@@ -568,8 +589,10 @@ do_convert_private_ssh2(struct sshbuf *b)
568 error("%s: remaining bytes in key blob %d", __func__, rlen); 589 error("%s: remaining bytes in key blob %d", __func__, rlen);
569 590
570 /* try the key */ 591 /* try the key */
571 if (sshkey_sign(key, &sig, &slen, data, sizeof(data), NULL, 0) != 0 || 592 if (sshkey_sign(key, &sig, &slen, data, sizeof(data),
572 sshkey_verify(key, sig, slen, data, sizeof(data), NULL, 0) != 0) { 593 NULL, NULL, 0) != 0 ||
594 sshkey_verify(key, sig, slen, data, sizeof(data),
595 NULL, 0, NULL) != 0) {
573 sshkey_free(key); 596 sshkey_free(key);
574 free(sig); 597 free(sig);
575 return NULL; 598 return NULL;
@@ -651,6 +674,7 @@ do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private)
651 *k = do_convert_private_ssh2(buf); 674 *k = do_convert_private_ssh2(buf);
652 else if ((r = sshkey_fromb(buf, k)) != 0) 675 else if ((r = sshkey_fromb(buf, k)) != 0)
653 fatal("decode blob failed: %s", ssh_err(r)); 676 fatal("decode blob failed: %s", ssh_err(r));
677 sshbuf_free(buf);
654 fclose(fp); 678 fclose(fp);
655} 679}
656 680
@@ -807,13 +831,13 @@ do_download(struct passwd *pw)
807 int i, nkeys; 831 int i, nkeys;
808 enum sshkey_fp_rep rep; 832 enum sshkey_fp_rep rep;
809 int fptype; 833 int fptype;
810 char *fp, *ra; 834 char *fp, *ra, **comments = NULL;
811 835
812 fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; 836 fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
813 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; 837 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
814 838
815 pkcs11_init(1); 839 pkcs11_init(1);
816 nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); 840 nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys, &comments);
817 if (nkeys <= 0) 841 if (nkeys <= 0)
818 fatal("cannot read public key from pkcs11"); 842 fatal("cannot read public key from pkcs11");
819 for (i = 0; i < nkeys; i++) { 843 for (i = 0; i < nkeys; i++) {
@@ -831,10 +855,13 @@ do_download(struct passwd *pw)
831 free(fp); 855 free(fp);
832 } else { 856 } else {
833 (void) sshkey_write(keys[i], stdout); /* XXX check */ 857 (void) sshkey_write(keys[i], stdout); /* XXX check */
834 fprintf(stdout, "\n"); 858 fprintf(stdout, "%s%s\n",
859 *(comments[i]) == '\0' ? "" : " ", comments[i]);
835 } 860 }
861 free(comments[i]);
836 sshkey_free(keys[i]); 862 sshkey_free(keys[i]);
837 } 863 }
864 free(comments);
838 free(keys); 865 free(keys);
839 pkcs11_terminate(); 866 pkcs11_terminate();
840 exit(0); 867 exit(0);
@@ -1247,8 +1274,10 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
1247 if (fp == NULL || ra == NULL) 1274 if (fp == NULL || ra == NULL)
1248 fatal("%s: sshkey_fingerprint failed", 1275 fatal("%s: sshkey_fingerprint failed",
1249 __func__); 1276 __func__);
1250 mprintf("%s %s %s %s\n", ctx->host, 1277 mprintf("%s %s %s%s%s\n", ctx->host,
1251 sshkey_type(l->key), fp, l->comment); 1278 sshkey_type(l->key), fp,
1279 l->comment[0] ? " " : "",
1280 l->comment);
1252 if (log_level_get() >= SYSLOG_LEVEL_VERBOSE) 1281 if (log_level_get() >= SYSLOG_LEVEL_VERBOSE)
1253 printf("%s\n", ra); 1282 printf("%s\n", ra);
1254 free(ra); 1283 free(ra);
@@ -1650,6 +1679,9 @@ prepare_options_buf(struct sshbuf *c, int which)
1650 (certflags_flags & CERTOPT_USER_RC) != 0) 1679 (certflags_flags & CERTOPT_USER_RC) != 0)
1651 add_flag_option(c, "permit-user-rc"); 1680 add_flag_option(c, "permit-user-rc");
1652 if ((which & OPTIONS_CRITICAL) != 0 && 1681 if ((which & OPTIONS_CRITICAL) != 0 &&
1682 (certflags_flags & CERTOPT_NO_REQUIRE_USER_PRESENCE) != 0)
1683 add_flag_option(c, "no-touch-required");
1684 if ((which & OPTIONS_CRITICAL) != 0 &&
1653 certflags_src_addr != NULL) 1685 certflags_src_addr != NULL)
1654 add_string_option(c, "source-address", certflags_src_addr); 1686 add_string_option(c, "source-address", certflags_src_addr);
1655 for (i = 0; i < ncert_userext; i++) { 1687 for (i = 0; i < ncert_userext; i++) {
@@ -1676,7 +1708,8 @@ load_pkcs11_key(char *path)
1676 fatal("Couldn't load CA public key \"%s\": %s", 1708 fatal("Couldn't load CA public key \"%s\": %s",
1677 path, ssh_err(r)); 1709 path, ssh_err(r));
1678 1710
1679 nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys); 1711 nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase,
1712 &keys, NULL);
1680 debug3("%s: %d keys", __func__, nkeys); 1713 debug3("%s: %d keys", __func__, nkeys);
1681 if (nkeys <= 0) 1714 if (nkeys <= 0)
1682 fatal("cannot read public key from pkcs11"); 1715 fatal("cannot read public key from pkcs11");
@@ -1699,7 +1732,7 @@ load_pkcs11_key(char *path)
1699static int 1732static int
1700agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp, 1733agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp,
1701 const u_char *data, size_t datalen, 1734 const u_char *data, size_t datalen,
1702 const char *alg, u_int compat, void *ctx) 1735 const char *alg, const char *provider, u_int compat, void *ctx)
1703{ 1736{
1704 int *agent_fdp = (int *)ctx; 1737 int *agent_fdp = (int *)ctx;
1705 1738
@@ -1715,10 +1748,12 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
1715 int r, i, fd, found, agent_fd = -1; 1748 int r, i, fd, found, agent_fd = -1;
1716 u_int n; 1749 u_int n;
1717 struct sshkey *ca, *public; 1750 struct sshkey *ca, *public;
1718 char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL; 1751 char valid[64], *otmp, *tmp, *cp, *out, *comment;
1752 char *ca_fp = NULL, **plist = NULL;
1719 FILE *f; 1753 FILE *f;
1720 struct ssh_identitylist *agent_ids; 1754 struct ssh_identitylist *agent_ids;
1721 size_t j; 1755 size_t j;
1756 struct notifier_ctx *notifier = NULL;
1722 1757
1723#ifdef ENABLE_PKCS11 1758#ifdef ENABLE_PKCS11
1724 pkcs11_init(1); 1759 pkcs11_init(1);
@@ -1759,11 +1794,16 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
1759 } 1794 }
1760 free(tmp); 1795 free(tmp);
1761 1796
1762 if (key_type_name != NULL && 1797 if (key_type_name != NULL) {
1763 sshkey_type_from_name(key_type_name) != ca->type) { 1798 if (sshkey_type_from_name(key_type_name) != ca->type) {
1764 fatal("CA key type %s doesn't match specified %s", 1799 fatal("CA key type %s doesn't match specified %s",
1765 sshkey_ssh_name(ca), key_type_name); 1800 sshkey_ssh_name(ca), key_type_name);
1801 }
1802 } else if (ca->type == KEY_RSA) {
1803 /* Default to a good signature algorithm */
1804 key_type_name = "rsa-sha2-512";
1766 } 1805 }
1806 ca_fp = sshkey_fingerprint(ca, fingerprint_hash, SSH_FP_DEFAULT);
1767 1807
1768 for (i = 0; i < argc; i++) { 1808 for (i = 0; i < argc; i++) {
1769 /* Split list of principals */ 1809 /* Split list of principals */
@@ -1785,9 +1825,7 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
1785 if ((r = sshkey_load_public(tmp, &public, &comment)) != 0) 1825 if ((r = sshkey_load_public(tmp, &public, &comment)) != 0)
1786 fatal("%s: unable to open \"%s\": %s", 1826 fatal("%s: unable to open \"%s\": %s",
1787 __func__, tmp, ssh_err(r)); 1827 __func__, tmp, ssh_err(r));
1788 if (public->type != KEY_RSA && public->type != KEY_DSA && 1828 if (sshkey_is_cert(public))
1789 public->type != KEY_ECDSA && public->type != KEY_ED25519 &&
1790 public->type != KEY_XMSS)
1791 fatal("%s: key \"%s\" type %s cannot be certified", 1829 fatal("%s: key \"%s\" type %s cannot be certified",
1792 __func__, tmp, sshkey_type(public)); 1830 __func__, tmp, sshkey_type(public));
1793 1831
@@ -1811,11 +1849,21 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
1811 1849
1812 if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) { 1850 if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) {
1813 if ((r = sshkey_certify_custom(public, ca, 1851 if ((r = sshkey_certify_custom(public, ca,
1814 key_type_name, agent_signer, &agent_fd)) != 0) 1852 key_type_name, sk_provider, agent_signer,
1853 &agent_fd)) != 0)
1815 fatal("Couldn't certify key %s via agent: %s", 1854 fatal("Couldn't certify key %s via agent: %s",
1816 tmp, ssh_err(r)); 1855 tmp, ssh_err(r));
1817 } else { 1856 } else {
1818 if ((sshkey_certify(public, ca, key_type_name)) != 0) 1857 if (sshkey_is_sk(ca) &&
1858 (ca->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
1859 notifier = notify_start(0,
1860 "Confirm user presence for key %s %s",
1861 sshkey_type(ca), ca_fp);
1862 }
1863 r = sshkey_certify(public, ca, key_type_name,
1864 sk_provider);
1865 notify_complete(notifier);
1866 if (r != 0)
1819 fatal("Couldn't certify key %s: %s", 1867 fatal("Couldn't certify key %s: %s",
1820 tmp, ssh_err(r)); 1868 tmp, ssh_err(r));
1821 } 1869 }
@@ -1853,6 +1901,7 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
1853 if (cert_serial_autoinc) 1901 if (cert_serial_autoinc)
1854 cert_serial++; 1902 cert_serial++;
1855 } 1903 }
1904 free(ca_fp);
1856#ifdef ENABLE_PKCS11 1905#ifdef ENABLE_PKCS11
1857 pkcs11_terminate(); 1906 pkcs11_terminate();
1858#endif 1907#endif
@@ -1951,6 +2000,10 @@ add_cert_option(char *opt)
1951 certflags_flags &= ~CERTOPT_USER_RC; 2000 certflags_flags &= ~CERTOPT_USER_RC;
1952 else if (strcasecmp(opt, "permit-user-rc") == 0) 2001 else if (strcasecmp(opt, "permit-user-rc") == 0)
1953 certflags_flags |= CERTOPT_USER_RC; 2002 certflags_flags |= CERTOPT_USER_RC;
2003 else if (strcasecmp(opt, "touch-required") == 0)
2004 certflags_flags &= ~CERTOPT_NO_REQUIRE_USER_PRESENCE;
2005 else if (strcasecmp(opt, "no-touch-required") == 0)
2006 certflags_flags |= CERTOPT_NO_REQUIRE_USER_PRESENCE;
1954 else if (strncasecmp(opt, "force-command=", 14) == 0) { 2007 else if (strncasecmp(opt, "force-command=", 14) == 0) {
1955 val = opt + 14; 2008 val = opt + 14;
1956 if (*val == '\0') 2009 if (*val == '\0')
@@ -2004,9 +2057,10 @@ show_options(struct sshbuf *optbuf, int in_critical)
2004 strcmp(name, "permit-agent-forwarding") == 0 || 2057 strcmp(name, "permit-agent-forwarding") == 0 ||
2005 strcmp(name, "permit-port-forwarding") == 0 || 2058 strcmp(name, "permit-port-forwarding") == 0 ||
2006 strcmp(name, "permit-pty") == 0 || 2059 strcmp(name, "permit-pty") == 0 ||
2007 strcmp(name, "permit-user-rc") == 0)) 2060 strcmp(name, "permit-user-rc") == 0 ||
2061 strcmp(name, "no-touch-required") == 0)) {
2008 printf("\n"); 2062 printf("\n");
2009 else if (in_critical && 2063 } else if (in_critical &&
2010 (strcmp(name, "force-command") == 0 || 2064 (strcmp(name, "force-command") == 0 ||
2011 strcmp(name, "source-address") == 0)) { 2065 strcmp(name, "source-address") == 0)) {
2012 if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0) 2066 if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0)
@@ -2135,15 +2189,10 @@ static void
2135load_krl(const char *path, struct ssh_krl **krlp) 2189load_krl(const char *path, struct ssh_krl **krlp)
2136{ 2190{
2137 struct sshbuf *krlbuf; 2191 struct sshbuf *krlbuf;
2138 int r, fd; 2192 int r;
2139 2193
2140 if ((krlbuf = sshbuf_new()) == NULL) 2194 if ((r = sshbuf_load_file(path, &krlbuf)) != 0)
2141 fatal("sshbuf_new failed");
2142 if ((fd = open(path, O_RDONLY)) == -1)
2143 fatal("open %s: %s", path, strerror(errno));
2144 if ((r = sshkey_load_file(fd, krlbuf)) != 0)
2145 fatal("Unable to load KRL: %s", ssh_err(r)); 2195 fatal("Unable to load KRL: %s", ssh_err(r));
2146 close(fd);
2147 /* XXX check sigs */ 2196 /* XXX check sigs */
2148 if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 || 2197 if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 ||
2149 *krlp == NULL) 2198 *krlp == NULL)
@@ -2345,7 +2394,7 @@ do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
2345 struct ssh_krl *krl; 2394 struct ssh_krl *krl;
2346 struct stat sb; 2395 struct stat sb;
2347 struct sshkey *ca = NULL; 2396 struct sshkey *ca = NULL;
2348 int fd, i, r, wild_ca = 0; 2397 int i, r, wild_ca = 0;
2349 char *tmp; 2398 char *tmp;
2350 struct sshbuf *kbuf; 2399 struct sshbuf *kbuf;
2351 2400
@@ -2387,12 +2436,8 @@ do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
2387 fatal("sshbuf_new failed"); 2436 fatal("sshbuf_new failed");
2388 if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0) 2437 if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0)
2389 fatal("Couldn't generate KRL"); 2438 fatal("Couldn't generate KRL");
2390 if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) 2439 if ((r = sshbuf_write_file(identity_file, kbuf)) != 0)
2391 fatal("open %s: %s", identity_file, strerror(errno));
2392 if (atomicio(vwrite, fd, sshbuf_mutable_ptr(kbuf), sshbuf_len(kbuf)) !=
2393 sshbuf_len(kbuf))
2394 fatal("write %s: %s", identity_file, strerror(errno)); 2440 fatal("write %s: %s", identity_file, strerror(errno));
2395 close(fd);
2396 sshbuf_free(kbuf); 2441 sshbuf_free(kbuf);
2397 ssh_krl_free(krl); 2442 ssh_krl_free(krl);
2398 sshkey_free(ca); 2443 sshkey_free(ca);
@@ -2488,8 +2533,7 @@ sign_one(struct sshkey *signkey, const char *filename, int fd,
2488{ 2533{
2489 struct sshbuf *sigbuf = NULL, *abuf = NULL; 2534 struct sshbuf *sigbuf = NULL, *abuf = NULL;
2490 int r = SSH_ERR_INTERNAL_ERROR, wfd = -1, oerrno; 2535 int r = SSH_ERR_INTERNAL_ERROR, wfd = -1, oerrno;
2491 char *wfile = NULL; 2536 char *wfile = NULL, *asig = NULL, *fp = NULL;
2492 char *asig = NULL;
2493 2537
2494 if (!quiet) { 2538 if (!quiet) {
2495 if (fd == STDIN_FILENO) 2539 if (fd == STDIN_FILENO)
@@ -2497,7 +2541,16 @@ sign_one(struct sshkey *signkey, const char *filename, int fd,
2497 else 2541 else
2498 fprintf(stderr, "Signing file %s\n", filename); 2542 fprintf(stderr, "Signing file %s\n", filename);
2499 } 2543 }
2500 if ((r = sshsig_sign_fd(signkey, NULL, fd, sig_namespace, 2544 if (signer == NULL && sshkey_is_sk(signkey) &&
2545 (signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
2546 if ((fp = sshkey_fingerprint(signkey, fingerprint_hash,
2547 SSH_FP_DEFAULT)) == NULL)
2548 fatal("%s: sshkey_fingerprint failed", __func__);
2549 fprintf(stderr, "Confirm user presence for key %s %s\n",
2550 sshkey_type(signkey), fp);
2551 free(fp);
2552 }
2553 if ((r = sshsig_sign_fd(signkey, NULL, sk_provider, fd, sig_namespace,
2501 &sigbuf, signer, signer_ctx)) != 0) { 2554 &sigbuf, signer, signer_ctx)) != 0) {
2502 error("Signing %s failed: %s", filename, ssh_err(r)); 2555 error("Signing %s failed: %s", filename, ssh_err(r));
2503 goto out; 2556 goto out;
@@ -2555,7 +2608,7 @@ sign_one(struct sshkey *signkey, const char *filename, int fd,
2555} 2608}
2556 2609
2557static int 2610static int
2558sign(const char *keypath, const char *sig_namespace, int argc, char **argv) 2611sig_sign(const char *keypath, const char *sig_namespace, int argc, char **argv)
2559{ 2612{
2560 int i, fd = -1, r, ret = -1; 2613 int i, fd = -1, r, ret = -1;
2561 int agent_fd = -1; 2614 int agent_fd = -1;
@@ -2626,38 +2679,37 @@ done:
2626} 2679}
2627 2680
2628static int 2681static int
2629verify(const char *signature, const char *sig_namespace, const char *principal, 2682sig_verify(const char *signature, const char *sig_namespace,
2630 const char *allowed_keys, const char *revoked_keys) 2683 const char *principal, const char *allowed_keys, const char *revoked_keys)
2631{ 2684{
2632 int r, ret = -1, sigfd = -1; 2685 int r, ret = -1;
2633 struct sshbuf *sigbuf = NULL, *abuf = NULL; 2686 struct sshbuf *sigbuf = NULL, *abuf = NULL;
2634 struct sshkey *sign_key = NULL; 2687 struct sshkey *sign_key = NULL;
2635 char *fp = NULL; 2688 char *fp = NULL;
2689 struct sshkey_sig_details *sig_details = NULL;
2636 2690
2637 if ((abuf = sshbuf_new()) == NULL) 2691 memset(&sig_details, 0, sizeof(sig_details));
2638 fatal("%s: sshbuf_new() failed", __func__); 2692 if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
2639
2640 if ((sigfd = open(signature, O_RDONLY)) < 0) {
2641 error("Couldn't open signature file %s", signature);
2642 goto done;
2643 }
2644
2645 if ((r = sshkey_load_file(sigfd, abuf)) != 0) {
2646 error("Couldn't read signature file: %s", ssh_err(r)); 2693 error("Couldn't read signature file: %s", ssh_err(r));
2647 goto done; 2694 goto done;
2648 } 2695 }
2696
2649 if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) { 2697 if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
2650 error("%s: sshsig_armor: %s", __func__, ssh_err(r)); 2698 error("%s: sshsig_armor: %s", __func__, ssh_err(r));
2651 return r; 2699 goto done;
2652 } 2700 }
2653 if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace, 2701 if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace,
2654 &sign_key)) != 0) 2702 &sign_key, &sig_details)) != 0)
2655 goto done; /* sshsig_verify() prints error */ 2703 goto done; /* sshsig_verify() prints error */
2656 2704
2657 if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash, 2705 if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
2658 SSH_FP_DEFAULT)) == NULL) 2706 SSH_FP_DEFAULT)) == NULL)
2659 fatal("%s: sshkey_fingerprint failed", __func__); 2707 fatal("%s: sshkey_fingerprint failed", __func__);
2660 debug("Valid (unverified) signature from key %s", fp); 2708 debug("Valid (unverified) signature from key %s", fp);
2709 if (sig_details != NULL) {
2710 debug2("%s: signature details: counter = %u, flags = 0x%02x",
2711 __func__, sig_details->sk_counter, sig_details->sk_flags);
2712 }
2661 free(fp); 2713 free(fp);
2662 fp = NULL; 2714 fp = NULL;
2663 2715
@@ -2697,21 +2749,312 @@ done:
2697 printf("Could not verify signature.\n"); 2749 printf("Could not verify signature.\n");
2698 } 2750 }
2699 } 2751 }
2700 if (sigfd != -1)
2701 close(sigfd);
2702 sshbuf_free(sigbuf); 2752 sshbuf_free(sigbuf);
2703 sshbuf_free(abuf); 2753 sshbuf_free(abuf);
2704 sshkey_free(sign_key); 2754 sshkey_free(sign_key);
2755 sshkey_sig_details_free(sig_details);
2705 free(fp); 2756 free(fp);
2706 return ret; 2757 return ret;
2707} 2758}
2708 2759
2760static int
2761sig_find_principals(const char *signature, const char *allowed_keys) {
2762 int r, ret = -1;
2763 struct sshbuf *sigbuf = NULL, *abuf = NULL;
2764 struct sshkey *sign_key = NULL;
2765 char *principals = NULL, *cp, *tmp;
2766
2767 if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
2768 error("Couldn't read signature file: %s", ssh_err(r));
2769 goto done;
2770 }
2771 if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
2772 error("%s: sshsig_armor: %s", __func__, ssh_err(r));
2773 goto done;
2774 }
2775 if ((r = sshsig_get_pubkey(sigbuf, &sign_key)) != 0) {
2776 error("%s: sshsig_get_pubkey: %s",
2777 __func__, ssh_err(r));
2778 goto done;
2779 }
2780 if ((r = sshsig_find_principals(allowed_keys, sign_key,
2781 &principals)) != 0) {
2782 error("%s: sshsig_get_principal: %s",
2783 __func__, ssh_err(r));
2784 goto done;
2785 }
2786 ret = 0;
2787done:
2788 if (ret == 0 ) {
2789 /* Emit matching principals one per line */
2790 tmp = principals;
2791 while ((cp = strsep(&tmp, ",")) != NULL && *cp != '\0')
2792 puts(cp);
2793 } else {
2794 fprintf(stderr, "No principal matched.\n");
2795 }
2796 sshbuf_free(sigbuf);
2797 sshbuf_free(abuf);
2798 sshkey_free(sign_key);
2799 free(principals);
2800 return ret;
2801}
2802
2803static void
2804do_moduli_gen(const char *out_file, char **opts, size_t nopts)
2805{
2806#ifdef WITH_OPENSSL
2807 /* Moduli generation/screening */
2808 u_int32_t memory = 0;
2809 BIGNUM *start = NULL;
2810 int moduli_bits = 0;
2811 FILE *out;
2812 size_t i;
2813 const char *errstr;
2814
2815 /* Parse options */
2816 for (i = 0; i < nopts; i++) {
2817 if (strncmp(opts[i], "memory=", 7) == 0) {
2818 memory = (u_int32_t)strtonum(opts[i]+7, 1,
2819 UINT_MAX, &errstr);
2820 if (errstr) {
2821 fatal("Memory limit is %s: %s",
2822 errstr, opts[i]+7);
2823 }
2824 } else if (strncmp(opts[i], "start=", 6) == 0) {
2825 /* XXX - also compare length against bits */
2826 if (BN_hex2bn(&start, opts[i]+6) == 0)
2827 fatal("Invalid start point.");
2828 } else if (strncmp(opts[i], "bits=", 5) == 0) {
2829 moduli_bits = (int)strtonum(opts[i]+5, 1,
2830 INT_MAX, &errstr);
2831 if (errstr) {
2832 fatal("Invalid number: %s (%s)",
2833 opts[i]+12, errstr);
2834 }
2835 } else {
2836 fatal("Option \"%s\" is unsupported for moduli "
2837 "generation", opts[i]);
2838 }
2839 }
2840
2841 if ((out = fopen(out_file, "w")) == NULL) {
2842 fatal("Couldn't open modulus candidate file \"%s\": %s",
2843 out_file, strerror(errno));
2844 }
2845 setvbuf(out, NULL, _IOLBF, 0);
2846
2847 if (moduli_bits == 0)
2848 moduli_bits = DEFAULT_BITS;
2849 if (gen_candidates(out, memory, moduli_bits, start) != 0)
2850 fatal("modulus candidate generation failed");
2851#else /* WITH_OPENSSL */
2852 fatal("Moduli generation is not supported");
2853#endif /* WITH_OPENSSL */
2854}
2855
2856static void
2857do_moduli_screen(const char *out_file, char **opts, size_t nopts)
2858{
2859#ifdef WITH_OPENSSL
2860 /* Moduli generation/screening */
2861 char *checkpoint = NULL;
2862 u_int32_t generator_wanted = 0;
2863 unsigned long start_lineno = 0, lines_to_process = 0;
2864 int prime_tests = 0;
2865 FILE *out, *in = stdin;
2866 size_t i;
2867 const char *errstr;
2868
2869 /* Parse options */
2870 for (i = 0; i < nopts; i++) {
2871 if (strncmp(opts[i], "lines=", 6) == 0) {
2872 lines_to_process = strtoul(opts[i]+6, NULL, 10);
2873 } else if (strncmp(opts[i], "start-line=", 11) == 0) {
2874 start_lineno = strtoul(opts[i]+11, NULL, 10);
2875 } else if (strncmp(opts[i], "checkpoint=", 11) == 0) {
2876 checkpoint = xstrdup(opts[i]+11);
2877 } else if (strncmp(opts[i], "generator=", 10) == 0) {
2878 generator_wanted = (u_int32_t)strtonum(
2879 opts[i]+10, 1, UINT_MAX, &errstr);
2880 if (errstr != NULL) {
2881 fatal("Generator invalid: %s (%s)",
2882 opts[i]+10, errstr);
2883 }
2884 } else if (strncmp(opts[i], "prime-tests=", 12) == 0) {
2885 prime_tests = (int)strtonum(opts[i]+12, 1,
2886 INT_MAX, &errstr);
2887 if (errstr) {
2888 fatal("Invalid number: %s (%s)",
2889 opts[i]+12, errstr);
2890 }
2891 } else {
2892 fatal("Option \"%s\" is unsupported for moduli "
2893 "screening", opts[i]);
2894 }
2895 }
2896
2897 if (have_identity && strcmp(identity_file, "-") != 0) {
2898 if ((in = fopen(identity_file, "r")) == NULL) {
2899 fatal("Couldn't open modulus candidate "
2900 "file \"%s\": %s", identity_file,
2901 strerror(errno));
2902 }
2903 }
2904
2905 if ((out = fopen(out_file, "a")) == NULL) {
2906 fatal("Couldn't open moduli file \"%s\": %s",
2907 out_file, strerror(errno));
2908 }
2909 setvbuf(out, NULL, _IOLBF, 0);
2910 if (prime_test(in, out, prime_tests == 0 ? 100 : prime_tests,
2911 generator_wanted, checkpoint,
2912 start_lineno, lines_to_process) != 0)
2913 fatal("modulus screening failed");
2914#else /* WITH_OPENSSL */
2915 fatal("Moduli screening is not supported");
2916#endif /* WITH_OPENSSL */
2917}
2918
2919static char *
2920private_key_passphrase(void)
2921{
2922 char *passphrase1, *passphrase2;
2923
2924 /* Ask for a passphrase (twice). */
2925 if (identity_passphrase)
2926 passphrase1 = xstrdup(identity_passphrase);
2927 else if (identity_new_passphrase)
2928 passphrase1 = xstrdup(identity_new_passphrase);
2929 else {
2930passphrase_again:
2931 passphrase1 =
2932 read_passphrase("Enter passphrase (empty for no "
2933 "passphrase): ", RP_ALLOW_STDIN);
2934 passphrase2 = read_passphrase("Enter same passphrase again: ",
2935 RP_ALLOW_STDIN);
2936 if (strcmp(passphrase1, passphrase2) != 0) {
2937 /*
2938 * The passphrases do not match. Clear them and
2939 * retry.
2940 */
2941 freezero(passphrase1, strlen(passphrase1));
2942 freezero(passphrase2, strlen(passphrase2));
2943 printf("Passphrases do not match. Try again.\n");
2944 goto passphrase_again;
2945 }
2946 /* Clear the other copy of the passphrase. */
2947 freezero(passphrase2, strlen(passphrase2));
2948 }
2949 return passphrase1;
2950}
2951
2952static const char *
2953skip_ssh_url_preamble(const char *s)
2954{
2955 if (strncmp(s, "ssh://", 6) == 0)
2956 return s + 6;
2957 else if (strncmp(s, "ssh:", 4) == 0)
2958 return s + 4;
2959 return s;
2960}
2961
2962static int
2963do_download_sk(const char *skprovider, const char *device)
2964{
2965 struct sshkey **keys;
2966 size_t nkeys, i;
2967 int r, ok = -1;
2968 char *fp, *pin, *pass = NULL, *path, *pubpath;
2969 const char *ext;
2970
2971 if (skprovider == NULL)
2972 fatal("Cannot download keys without provider");
2973
2974 pin = read_passphrase("Enter PIN for authenticator: ", RP_ALLOW_STDIN);
2975 if ((r = sshsk_load_resident(skprovider, device, pin,
2976 &keys, &nkeys)) != 0) {
2977 freezero(pin, strlen(pin));
2978 error("Unable to load resident keys: %s", ssh_err(r));
2979 return -1;
2980 }
2981 if (nkeys == 0)
2982 logit("No keys to download");
2983 freezero(pin, strlen(pin));
2984
2985 for (i = 0; i < nkeys; i++) {
2986 if (keys[i]->type != KEY_ECDSA_SK &&
2987 keys[i]->type != KEY_ED25519_SK) {
2988 error("Unsupported key type %s (%d)",
2989 sshkey_type(keys[i]), keys[i]->type);
2990 continue;
2991 }
2992 if ((fp = sshkey_fingerprint(keys[i],
2993 fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
2994 fatal("%s: sshkey_fingerprint failed", __func__);
2995 debug("%s: key %zu: %s %s %s (flags 0x%02x)", __func__, i,
2996 sshkey_type(keys[i]), fp, keys[i]->sk_application,
2997 keys[i]->sk_flags);
2998 ext = skip_ssh_url_preamble(keys[i]->sk_application);
2999 xasprintf(&path, "id_%s_rk%s%s",
3000 keys[i]->type == KEY_ECDSA_SK ? "ecdsa_sk" : "ed25519_sk",
3001 *ext == '\0' ? "" : "_", ext);
3002
3003 /* If the file already exists, ask the user to confirm. */
3004 if (!confirm_overwrite(path)) {
3005 free(path);
3006 break;
3007 }
3008
3009 /* Save the key with the application string as the comment */
3010 if (pass == NULL)
3011 pass = private_key_passphrase();
3012 if ((r = sshkey_save_private(keys[i], path, pass,
3013 keys[i]->sk_application, private_key_format,
3014 openssh_format_cipher, rounds)) != 0) {
3015 error("Saving key \"%s\" failed: %s",
3016 path, ssh_err(r));
3017 free(path);
3018 break;
3019 }
3020 if (!quiet) {
3021 printf("Saved %s key%s%s to %s\n",
3022 sshkey_type(keys[i]),
3023 *ext != '\0' ? " " : "",
3024 *ext != '\0' ? keys[i]->sk_application : "",
3025 path);
3026 }
3027
3028 /* Save public key too */
3029 xasprintf(&pubpath, "%s.pub", path);
3030 free(path);
3031 if ((r = sshkey_save_public(keys[i], pubpath,
3032 keys[i]->sk_application)) != 0) {
3033 free(pubpath);
3034 error("Saving public key \"%s\" failed: %s",
3035 pubpath, ssh_err(r));
3036 break;
3037 }
3038 free(pubpath);
3039 }
3040
3041 if (i >= nkeys)
3042 ok = 0; /* success */
3043 if (pass != NULL)
3044 freezero(pass, strlen(pass));
3045 for (i = 0; i < nkeys; i++)
3046 sshkey_free(keys[i]);
3047 free(keys);
3048 return ok ? 0 : -1;
3049}
3050
2709static void 3051static void
2710usage(void) 3052usage(void)
2711{ 3053{
2712 fprintf(stderr, 3054 fprintf(stderr,
2713 "usage: ssh-keygen [-q] [-b bits] [-C comment] [-f output_keyfile] [-m format]\n" 3055 "usage: ssh-keygen [-q] [-b bits] [-C comment] [-f output_keyfile] [-m format]\n"
2714 " [-N new_passphrase] [-t dsa | ecdsa | ed25519 | rsa]\n" 3056 " [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]\n"
3057 " [-N new_passphrase] [-O option] [-w provider]\n"
2715 " ssh-keygen -p [-f keyfile] [-m format] [-N new_passphrase]\n" 3058 " ssh-keygen -p [-f keyfile] [-m format] [-N new_passphrase]\n"
2716 " [-P old_passphrase]\n" 3059 " [-P old_passphrase]\n"
2717 " ssh-keygen -i [-f input_keyfile] [-m key_format]\n" 3060 " ssh-keygen -i [-f input_keyfile] [-m key_format]\n"
@@ -2727,12 +3070,12 @@ usage(void)
2727 fprintf(stderr, 3070 fprintf(stderr,
2728 " ssh-keygen -F hostname [-lv] [-f known_hosts_file]\n" 3071 " ssh-keygen -F hostname [-lv] [-f known_hosts_file]\n"
2729 " ssh-keygen -H [-f known_hosts_file]\n" 3072 " ssh-keygen -H [-f known_hosts_file]\n"
3073 " ssh-keygen -K [-w provider]\n"
2730 " ssh-keygen -R hostname [-f known_hosts_file]\n" 3074 " ssh-keygen -R hostname [-f known_hosts_file]\n"
2731 " ssh-keygen -r hostname [-g] [-f input_keyfile]\n" 3075 " ssh-keygen -r hostname [-g] [-f input_keyfile]\n"
2732#ifdef WITH_OPENSSL 3076#ifdef WITH_OPENSSL
2733 " ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]\n" 3077 " ssh-keygen -M generate [-O option] output_file\n"
2734 " ssh-keygen -f input_file -T output_file [-v] [-a rounds] [-J num_lines]\n" 3078 " ssh-keygen -M screen [-f input_file] [-O option] output_file\n"
2735 " [-j start_line] [-K checkpt] [-W generator]\n"
2736#endif 3079#endif
2737 " ssh-keygen -I certificate_identity -s ca_key [-hU] [-D pkcs11_provider]\n" 3080 " ssh-keygen -I certificate_identity -s ca_key [-hU] [-D pkcs11_provider]\n"
2738 " [-n principals] [-O option] [-V validity_interval]\n" 3081 " [-n principals] [-O option] [-V validity_interval]\n"
@@ -2742,6 +3085,7 @@ usage(void)
2742 " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n" 3085 " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
2743 " file ...\n" 3086 " file ...\n"
2744 " ssh-keygen -Q -f krl_file file ...\n" 3087 " ssh-keygen -Q -f krl_file file ...\n"
3088 " ssh-keygen -Y find-principals -s signature_file -f allowed_signers_file\n"
2745 " ssh-keygen -Y check-novalidate -n namespace -s signature_file\n" 3089 " ssh-keygen -Y check-novalidate -n namespace -s signature_file\n"
2746 " ssh-keygen -Y sign -f key_file -n namespace file ...\n" 3090 " ssh-keygen -Y sign -f key_file -n namespace file ...\n"
2747 " ssh-keygen -Y verify -f allowed_signers_file -I signer_identity\n" 3091 " ssh-keygen -Y verify -f allowed_signers_file -I signer_identity\n"
@@ -2755,32 +3099,29 @@ usage(void)
2755int 3099int
2756main(int argc, char **argv) 3100main(int argc, char **argv)
2757{ 3101{
2758 char dotsshdir[PATH_MAX], comment[1024], *passphrase1, *passphrase2; 3102 char dotsshdir[PATH_MAX], comment[1024], *passphrase;
2759 char *rr_hostname = NULL, *ep, *fp, *ra; 3103 char *rr_hostname = NULL, *ep, *fp, *ra;
2760 struct sshkey *private, *public; 3104 struct sshkey *private, *public;
2761 struct passwd *pw; 3105 struct passwd *pw;
2762 struct stat st; 3106 struct stat st;
2763 int r, opt, type, fd; 3107 int r, opt, type;
2764 int change_passphrase = 0, change_comment = 0, show_cert = 0; 3108 int change_passphrase = 0, change_comment = 0, show_cert = 0;
2765 int find_host = 0, delete_host = 0, hash_hosts = 0; 3109 int find_host = 0, delete_host = 0, hash_hosts = 0;
2766 int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; 3110 int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
2767 int prefer_agent = 0, convert_to = 0, convert_from = 0; 3111 int prefer_agent = 0, convert_to = 0, convert_from = 0;
2768 int print_public = 0, print_generic = 0, cert_serial_autoinc = 0; 3112 int print_public = 0, print_generic = 0, cert_serial_autoinc = 0;
3113 int do_gen_candidates = 0, do_screen_candidates = 0, download_sk = 0;
2769 unsigned long long cert_serial = 0; 3114 unsigned long long cert_serial = 0;
2770 char *identity_comment = NULL, *ca_key_path = NULL; 3115 char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL;
3116 char *sk_application = NULL, *sk_device = NULL, *sk_user = NULL;
3117 char *sk_attestaion_path = NULL;
3118 struct sshbuf *challenge = NULL, *attest = NULL;
3119 size_t i, nopts = 0;
2771 u_int32_t bits = 0; 3120 u_int32_t bits = 0;
2772 FILE *f; 3121 uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD;
2773 const char *errstr; 3122 const char *errstr;
2774 int log_level = SYSLOG_LEVEL_INFO; 3123 int log_level = SYSLOG_LEVEL_INFO;
2775 char *sign_op = NULL; 3124 char *sign_op = NULL;
2776#ifdef WITH_OPENSSL
2777 /* Moduli generation/screening */
2778 char out_file[PATH_MAX], *checkpoint = NULL;
2779 u_int32_t memory = 0, generator_wanted = 0;
2780 int do_gen_candidates = 0, do_screen_candidates = 0;
2781 unsigned long start_lineno = 0, lines_to_process = 0;
2782 BIGNUM *start = NULL;
2783#endif
2784 3125
2785 extern int optind; 3126 extern int optind;
2786 extern char *optarg; 3127 extern char *optarg;
@@ -2803,10 +3144,12 @@ main(int argc, char **argv)
2803 if (gethostname(hostname, sizeof(hostname)) == -1) 3144 if (gethostname(hostname, sizeof(hostname)) == -1)
2804 fatal("gethostname: %s", strerror(errno)); 3145 fatal("gethostname: %s", strerror(errno));
2805 3146
2806 /* Remaining characters: dw */ 3147 sk_provider = getenv("SSH_SK_PROVIDER");
2807 while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvxy" 3148
2808 "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Y:Z:" 3149 /* Remaining characters: dGjJSTWx */
2809 "a:b:f:g:j:m:n:r:s:t:z:")) != -1) { 3150 while ((opt = getopt(argc, argv, "ABHKLQUXceghiklopquvy"
3151 "C:D:E:F:I:M:N:O:P:R:V:Y:Z:"
3152 "a:b:f:g:m:n:r:s:t:w:z:")) != -1) {
2810 switch (opt) { 3153 switch (opt) {
2811 case 'A': 3154 case 'A':
2812 gen_all_hostkeys = 1; 3155 gen_all_hostkeys = 1;
@@ -2884,6 +3227,9 @@ main(int argc, char **argv)
2884 case 'g': 3227 case 'g':
2885 print_generic = 1; 3228 print_generic = 1;
2886 break; 3229 break;
3230 case 'K':
3231 download_sk = 1;
3232 break;
2887 case 'P': 3233 case 'P':
2888 identity_passphrase = optarg; 3234 identity_passphrase = optarg;
2889 break; 3235 break;
@@ -2894,7 +3240,9 @@ main(int argc, char **argv)
2894 check_krl = 1; 3240 check_krl = 1;
2895 break; 3241 break;
2896 case 'O': 3242 case 'O':
2897 add_cert_option(optarg); 3243 opts = xrecallocarray(opts, nopts, nopts + 1,
3244 sizeof(*opts));
3245 opts[nopts++] = xstrdup(optarg);
2898 break; 3246 break;
2899 case 'Z': 3247 case 'Z':
2900 openssh_format_cipher = optarg; 3248 openssh_format_cipher = optarg;
@@ -2906,7 +3254,6 @@ main(int argc, char **argv)
2906 quiet = 1; 3254 quiet = 1;
2907 break; 3255 break;
2908 case 'e': 3256 case 'e':
2909 case 'x':
2910 /* export key */ 3257 /* export key */
2911 convert_to = 1; 3258 convert_to = 1;
2912 break; 3259 break;
@@ -2964,6 +3311,9 @@ main(int argc, char **argv)
2964 case 'Y': 3311 case 'Y':
2965 sign_op = optarg; 3312 sign_op = optarg;
2966 break; 3313 break;
3314 case 'w':
3315 sk_provider = optarg;
3316 break;
2967 case 'z': 3317 case 'z':
2968 errno = 0; 3318 errno = 0;
2969 if (*optarg == '+') { 3319 if (*optarg == '+') {
@@ -2975,56 +3325,25 @@ main(int argc, char **argv)
2975 (errno == ERANGE && cert_serial == ULLONG_MAX)) 3325 (errno == ERANGE && cert_serial == ULLONG_MAX))
2976 fatal("Invalid serial number \"%s\"", optarg); 3326 fatal("Invalid serial number \"%s\"", optarg);
2977 break; 3327 break;
2978#ifdef WITH_OPENSSL
2979 /* Moduli generation/screening */
2980 case 'G':
2981 do_gen_candidates = 1;
2982 if (strlcpy(out_file, optarg, sizeof(out_file)) >=
2983 sizeof(out_file))
2984 fatal("Output filename too long");
2985 break;
2986 case 'J':
2987 lines_to_process = strtoul(optarg, NULL, 10);
2988 break;
2989 case 'j':
2990 start_lineno = strtoul(optarg, NULL, 10);
2991 break;
2992 case 'K':
2993 if (strlen(optarg) >= PATH_MAX)
2994 fatal("Checkpoint filename too long");
2995 checkpoint = xstrdup(optarg);
2996 break;
2997 case 'M': 3328 case 'M':
2998 memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, 3329 if (strcmp(optarg, "generate") == 0)
2999 &errstr); 3330 do_gen_candidates = 1;
3000 if (errstr) 3331 else if (strcmp(optarg, "screen") == 0)
3001 fatal("Memory limit is %s: %s", errstr, optarg); 3332 do_screen_candidates = 1;
3333 else
3334 fatal("Unsupported moduli option %s", optarg);
3002 break; 3335 break;
3003 case 'S':
3004 /* XXX - also compare length against bits */
3005 if (BN_hex2bn(&start, optarg) == 0)
3006 fatal("Invalid start point.");
3007 break;
3008 case 'T':
3009 do_screen_candidates = 1;
3010 if (strlcpy(out_file, optarg, sizeof(out_file)) >=
3011 sizeof(out_file))
3012 fatal("Output filename too long");
3013 break;
3014 case 'W':
3015 generator_wanted = (u_int32_t)strtonum(optarg, 1,
3016 UINT_MAX, &errstr);
3017 if (errstr != NULL)
3018 fatal("Desired generator invalid: %s (%s)",
3019 optarg, errstr);
3020 break;
3021#endif /* WITH_OPENSSL */
3022 case '?': 3336 case '?':
3023 default: 3337 default:
3024 usage(); 3338 usage();
3025 } 3339 }
3026 } 3340 }
3027 3341
3342#ifdef ENABLE_SK_INTERNAL
3343 if (sk_provider == NULL)
3344 sk_provider = "internal";
3345#endif
3346
3028 /* reinit */ 3347 /* reinit */
3029 log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1); 3348 log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
3030 3349
@@ -3032,27 +3351,47 @@ main(int argc, char **argv)
3032 argc -= optind; 3351 argc -= optind;
3033 3352
3034 if (sign_op != NULL) { 3353 if (sign_op != NULL) {
3035 if (cert_principals == NULL || *cert_principals == '\0') { 3354 if (strncmp(sign_op, "find-principals", 15) == 0) {
3036 error("Too few arguments for sign/verify: " 3355 if (ca_key_path == NULL) {
3037 "missing namespace"); 3356 error("Too few arguments for find-principals:"
3038 exit(1); 3357 "missing signature file");
3039 } 3358 exit(1);
3040 if (strncmp(sign_op, "sign", 4) == 0) { 3359 }
3360 if (!have_identity) {
3361 error("Too few arguments for find-principals:"
3362 "missing allowed keys file");
3363 exit(1);
3364 }
3365 return sig_find_principals(ca_key_path, identity_file);
3366 } else if (strncmp(sign_op, "sign", 4) == 0) {
3367 if (cert_principals == NULL ||
3368 *cert_principals == '\0') {
3369 error("Too few arguments for sign: "
3370 "missing namespace");
3371 exit(1);
3372 }
3041 if (!have_identity) { 3373 if (!have_identity) {
3042 error("Too few arguments for sign: " 3374 error("Too few arguments for sign: "
3043 "missing key"); 3375 "missing key");
3044 exit(1); 3376 exit(1);
3045 } 3377 }
3046 return sign(identity_file, cert_principals, argc, argv); 3378 return sig_sign(identity_file, cert_principals,
3379 argc, argv);
3047 } else if (strncmp(sign_op, "check-novalidate", 16) == 0) { 3380 } else if (strncmp(sign_op, "check-novalidate", 16) == 0) {
3048 if (ca_key_path == NULL) { 3381 if (ca_key_path == NULL) {
3049 error("Too few arguments for check-novalidate: " 3382 error("Too few arguments for check-novalidate: "
3050 "missing signature file"); 3383 "missing signature file");
3051 exit(1); 3384 exit(1);
3052 } 3385 }
3053 return verify(ca_key_path, cert_principals, 3386 return sig_verify(ca_key_path, cert_principals,
3054 NULL, NULL, NULL); 3387 NULL, NULL, NULL);
3055 } else if (strncmp(sign_op, "verify", 6) == 0) { 3388 } else if (strncmp(sign_op, "verify", 6) == 0) {
3389 if (cert_principals == NULL ||
3390 *cert_principals == '\0') {
3391 error("Too few arguments for verify: "
3392 "missing namespace");
3393 exit(1);
3394 }
3056 if (ca_key_path == NULL) { 3395 if (ca_key_path == NULL) {
3057 error("Too few arguments for verify: " 3396 error("Too few arguments for verify: "
3058 "missing signature file"); 3397 "missing signature file");
@@ -3068,9 +3407,10 @@ main(int argc, char **argv)
3068 "missing principal ID"); 3407 "missing principal ID");
3069 exit(1); 3408 exit(1);
3070 } 3409 }
3071 return verify(ca_key_path, cert_principals, 3410 return sig_verify(ca_key_path, cert_principals,
3072 cert_key_id, identity_file, rr_hostname); 3411 cert_key_id, identity_file, rr_hostname);
3073 } 3412 }
3413 error("Unsupported operation for -Y: \"%s\"", sign_op);
3074 usage(); 3414 usage();
3075 /* NOTREACHED */ 3415 /* NOTREACHED */
3076 } 3416 }
@@ -3080,7 +3420,8 @@ main(int argc, char **argv)
3080 error("Too few arguments."); 3420 error("Too few arguments.");
3081 usage(); 3421 usage();
3082 } 3422 }
3083 } else if (argc > 0 && !gen_krl && !check_krl) { 3423 } else if (argc > 0 && !gen_krl && !check_krl &&
3424 !do_gen_candidates && !do_screen_candidates) {
3084 error("Too many arguments."); 3425 error("Too many arguments.");
3085 usage(); 3426 usage();
3086 } 3427 }
@@ -3104,6 +3445,8 @@ main(int argc, char **argv)
3104 if (ca_key_path != NULL) { 3445 if (ca_key_path != NULL) {
3105 if (cert_key_id == NULL) 3446 if (cert_key_id == NULL)
3106 fatal("Must specify key id (-I) when certifying"); 3447 fatal("Must specify key id (-I) when certifying");
3448 for (i = 0; i < nopts; i++)
3449 add_cert_option(opts[i]);
3107 do_ca_sign(pw, ca_key_path, prefer_agent, 3450 do_ca_sign(pw, ca_key_path, prefer_agent,
3108 cert_serial, cert_serial_autoinc, argc, argv); 3451 cert_serial, cert_serial_autoinc, argc, argv);
3109 } 3452 }
@@ -3115,6 +3458,17 @@ main(int argc, char **argv)
3115 } 3458 }
3116 if (pkcs11provider != NULL) 3459 if (pkcs11provider != NULL)
3117 do_download(pw); 3460 do_download(pw);
3461 if (download_sk) {
3462 for (i = 0; i < nopts; i++) {
3463 if (strncasecmp(opts[i], "device=", 7) == 0) {
3464 sk_device = xstrdup(opts[i] + 7);
3465 } else {
3466 fatal("Option \"%s\" is unsupported for "
3467 "FIDO authenticator download", opts[i]);
3468 }
3469 }
3470 return do_download_sk(sk_provider, sk_device);
3471 }
3118 if (print_fingerprint || print_bubblebabble) 3472 if (print_fingerprint || print_bubblebabble)
3119 do_fingerprint(pw); 3473 do_fingerprint(pw);
3120 if (change_passphrase) 3474 if (change_passphrase)
@@ -3164,47 +3518,20 @@ main(int argc, char **argv)
3164 } 3518 }
3165 } 3519 }
3166 3520
3167#ifdef WITH_OPENSSL 3521 if (do_gen_candidates || do_screen_candidates) {
3522 if (argc <= 0)
3523 fatal("No output file specified");
3524 else if (argc > 1)
3525 fatal("Too many output files specified");
3526 }
3168 if (do_gen_candidates) { 3527 if (do_gen_candidates) {
3169 FILE *out = fopen(out_file, "w"); 3528 do_moduli_gen(argv[0], opts, nopts);
3170 3529 return 0;
3171 if (out == NULL) {
3172 error("Couldn't open modulus candidate file \"%s\": %s",
3173 out_file, strerror(errno));
3174 return (1);
3175 }
3176 if (bits == 0)
3177 bits = DEFAULT_BITS;
3178 if (gen_candidates(out, memory, bits, start) != 0)
3179 fatal("modulus candidate generation failed");
3180
3181 return (0);
3182 } 3530 }
3183
3184 if (do_screen_candidates) { 3531 if (do_screen_candidates) {
3185 FILE *in; 3532 do_moduli_screen(argv[0], opts, nopts);
3186 FILE *out = fopen(out_file, "a"); 3533 return 0;
3187
3188 if (have_identity && strcmp(identity_file, "-") != 0) {
3189 if ((in = fopen(identity_file, "r")) == NULL) {
3190 fatal("Couldn't open modulus candidate "
3191 "file \"%s\": %s", identity_file,
3192 strerror(errno));
3193 }
3194 } else
3195 in = stdin;
3196
3197 if (out == NULL) {
3198 fatal("Couldn't open moduli file \"%s\": %s",
3199 out_file, strerror(errno));
3200 }
3201 if (prime_test(in, out, rounds == 0 ? 100 : rounds,
3202 generator_wanted, checkpoint,
3203 start_lineno, lines_to_process) != 0)
3204 fatal("modulus screening failed");
3205 return (0);
3206 } 3534 }
3207#endif
3208 3535
3209 if (gen_all_hostkeys) { 3536 if (gen_all_hostkeys) {
3210 do_gen_all_hostkeys(pw); 3537 do_gen_all_hostkeys(pw);
@@ -3220,8 +3547,78 @@ main(int argc, char **argv)
3220 if (!quiet) 3547 if (!quiet)
3221 printf("Generating public/private %s key pair.\n", 3548 printf("Generating public/private %s key pair.\n",
3222 key_type_name); 3549 key_type_name);
3223 if ((r = sshkey_generate(type, bits, &private)) != 0) 3550 switch (type) {
3224 fatal("sshkey_generate failed"); 3551 case KEY_ECDSA_SK:
3552 case KEY_ED25519_SK:
3553 for (i = 0; i < nopts; i++) {
3554 if (strcasecmp(opts[i], "no-touch-required") == 0) {
3555 sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;
3556 } else if (strcasecmp(opts[i], "resident") == 0) {
3557 sk_flags |= SSH_SK_RESIDENT_KEY;
3558 } else if (strncasecmp(opts[i], "device=", 7) == 0) {
3559 sk_device = xstrdup(opts[i] + 7);
3560 } else if (strncasecmp(opts[i], "user=", 5) == 0) {
3561 sk_user = xstrdup(opts[i] + 5);
3562 } else if (strncasecmp(opts[i], "challenge=", 10) == 0) {
3563 if ((r = sshbuf_load_file(opts[i] + 10,
3564 &challenge)) != 0) {
3565 fatal("Unable to load FIDO enrollment "
3566 "challenge \"%s\": %s",
3567 opts[i] + 10, ssh_err(r));
3568 }
3569 } else if (strncasecmp(opts[i],
3570 "write-attestation=", 18) == 0) {
3571 sk_attestaion_path = opts[i] + 18;
3572 } else if (strncasecmp(opts[i],
3573 "application=", 12) == 0) {
3574 sk_application = xstrdup(opts[i] + 12);
3575 if (strncmp(sk_application, "ssh:", 4) != 0) {
3576 fatal("FIDO application string must "
3577 "begin with \"ssh:\"");
3578 }
3579 } else {
3580 fatal("Option \"%s\" is unsupported for "
3581 "FIDO authenticator enrollment", opts[i]);
3582 }
3583 }
3584 if (!quiet) {
3585 printf("You may need to touch your authenticator "
3586 "to authorize key generation.\n");
3587 }
3588 passphrase = NULL;
3589 if ((attest = sshbuf_new()) == NULL)
3590 fatal("sshbuf_new failed");
3591 for (i = 0 ; ; i++) {
3592 fflush(stdout);
3593 r = sshsk_enroll(type, sk_provider, sk_device,
3594 sk_application == NULL ? "ssh:" : sk_application,
3595 sk_user, sk_flags, passphrase, challenge,
3596 &private, attest);
3597 if (r == 0)
3598 break;
3599 if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
3600 fatal("Key enrollment failed: %s", ssh_err(r));
3601 else if (i > 0)
3602 error("PIN incorrect");
3603 if (passphrase != NULL) {
3604 freezero(passphrase, strlen(passphrase));
3605 passphrase = NULL;
3606 }
3607 if (i >= 3)
3608 fatal("Too many incorrect PINs");
3609 passphrase = read_passphrase("Enter PIN for "
3610 "authenticator: ", RP_ALLOW_STDIN);
3611 }
3612 if (passphrase != NULL) {
3613 freezero(passphrase, strlen(passphrase));
3614 passphrase = NULL;
3615 }
3616 break;
3617 default:
3618 if ((r = sshkey_generate(type, bits, &private)) != 0)
3619 fatal("sshkey_generate failed");
3620 break;
3621 }
3225 if ((r = sshkey_from_private(private, &public)) != 0) 3622 if ((r = sshkey_from_private(private, &public)) != 0)
3226 fatal("sshkey_from_private failed: %s\n", ssh_err(r)); 3623 fatal("sshkey_from_private failed: %s\n", ssh_err(r));
3227 3624
@@ -3246,35 +3643,9 @@ main(int argc, char **argv)
3246 /* If the file already exists, ask the user to confirm. */ 3643 /* If the file already exists, ask the user to confirm. */
3247 if (!confirm_overwrite(identity_file)) 3644 if (!confirm_overwrite(identity_file))
3248 exit(1); 3645 exit(1);
3249 /* Ask for a passphrase (twice). */
3250 if (identity_passphrase)
3251 passphrase1 = xstrdup(identity_passphrase);
3252 else if (identity_new_passphrase)
3253 passphrase1 = xstrdup(identity_new_passphrase);
3254 else {
3255passphrase_again:
3256 passphrase1 =
3257 read_passphrase("Enter passphrase (empty for no "
3258 "passphrase): ", RP_ALLOW_STDIN);
3259 passphrase2 = read_passphrase("Enter same passphrase again: ",
3260 RP_ALLOW_STDIN);
3261 if (strcmp(passphrase1, passphrase2) != 0) {
3262 /*
3263 * The passphrases do not match. Clear them and
3264 * retry.
3265 */
3266 explicit_bzero(passphrase1, strlen(passphrase1));
3267 explicit_bzero(passphrase2, strlen(passphrase2));
3268 free(passphrase1);
3269 free(passphrase2);
3270 printf("Passphrases do not match. Try again.\n");
3271 goto passphrase_again;
3272 }
3273 /* Clear the other copy of the passphrase. */
3274 explicit_bzero(passphrase2, strlen(passphrase2));
3275 free(passphrase2);
3276 }
3277 3646
3647 /* Determine the passphrase for the private key */
3648 passphrase = private_key_passphrase();
3278 if (identity_comment) { 3649 if (identity_comment) {
3279 strlcpy(comment, identity_comment, sizeof(comment)); 3650 strlcpy(comment, identity_comment, sizeof(comment));
3280 } else { 3651 } else {
@@ -3283,35 +3654,26 @@ passphrase_again:
3283 } 3654 }
3284 3655
3285 /* Save the key with the given passphrase and comment. */ 3656 /* Save the key with the given passphrase and comment. */
3286 if ((r = sshkey_save_private(private, identity_file, passphrase1, 3657 if ((r = sshkey_save_private(private, identity_file, passphrase,
3287 comment, private_key_format, openssh_format_cipher, rounds)) != 0) { 3658 comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
3288 error("Saving key \"%s\" failed: %s", 3659 error("Saving key \"%s\" failed: %s",
3289 identity_file, ssh_err(r)); 3660 identity_file, ssh_err(r));
3290 explicit_bzero(passphrase1, strlen(passphrase1)); 3661 freezero(passphrase, strlen(passphrase));
3291 free(passphrase1);
3292 exit(1); 3662 exit(1);
3293 } 3663 }
3294 /* Clear the passphrase. */ 3664 freezero(passphrase, strlen(passphrase));
3295 explicit_bzero(passphrase1, strlen(passphrase1));
3296 free(passphrase1);
3297
3298 /* Clear the private key and the random number generator. */
3299 sshkey_free(private); 3665 sshkey_free(private);
3300 3666
3301 if (!quiet) 3667 if (!quiet) {
3302 printf("Your identification has been saved in %s.\n", identity_file); 3668 printf("Your identification has been saved in %s\n",
3669 identity_file);
3670 }
3303 3671
3304 strlcat(identity_file, ".pub", sizeof(identity_file)); 3672 strlcat(identity_file, ".pub", sizeof(identity_file));
3305 if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) 3673 if ((r = sshkey_save_public(public, identity_file, comment)) != 0) {
3306 fatal("Unable to save public key to %s: %s", 3674 fatal("Unable to save public key to %s: %s",
3307 identity_file, strerror(errno)); 3675 identity_file, strerror(errno));
3308 if ((f = fdopen(fd, "w")) == NULL) 3676 }
3309 fatal("fdopen %s failed: %s", identity_file, strerror(errno));
3310 if ((r = sshkey_write(public, f)) != 0)
3311 error("write key failed: %s", ssh_err(r));
3312 fprintf(f, " %s\n", comment);
3313 if (ferror(f) || fclose(f) != 0)
3314 fatal("write public failed: %s", strerror(errno));
3315 3677
3316 if (!quiet) { 3678 if (!quiet) {
3317 fp = sshkey_fingerprint(public, fingerprint_hash, 3679 fp = sshkey_fingerprint(public, fingerprint_hash,
@@ -3320,7 +3682,7 @@ passphrase_again:
3320 SSH_FP_RANDOMART); 3682 SSH_FP_RANDOMART);
3321 if (fp == NULL || ra == NULL) 3683 if (fp == NULL || ra == NULL)
3322 fatal("sshkey_fingerprint failed"); 3684 fatal("sshkey_fingerprint failed");
3323 printf("Your public key has been saved in %s.\n", 3685 printf("Your public key has been saved in %s\n",
3324 identity_file); 3686 identity_file);
3325 printf("The key fingerprint is:\n"); 3687 printf("The key fingerprint is:\n");
3326 printf("%s %s\n", fp, comment); 3688 printf("%s %s\n", fp, comment);
@@ -3330,6 +3692,22 @@ passphrase_again:
3330 free(fp); 3692 free(fp);
3331 } 3693 }
3332 3694
3695 if (sk_attestaion_path != NULL) {
3696 if (attest == NULL || sshbuf_len(attest) == 0) {
3697 fatal("Enrollment did not return attestation "
3698 "certificate");
3699 }
3700 if ((r = sshbuf_write_file(sk_attestaion_path, attest)) != 0) {
3701 fatal("Unable to write attestation certificate "
3702 "\"%s\": %s", sk_attestaion_path, ssh_err(r));
3703 }
3704 if (!quiet) {
3705 printf("Your FIDO attestation certificate has been "
3706 "saved in %s\n", sk_attestaion_path);
3707 }
3708 }
3709 sshbuf_free(attest);
3333 sshkey_free(public); 3710 sshkey_free(public);
3711
3334 exit(0); 3712 exit(0);
3335} 3713}