summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2017-10-04 11:23:58 +0100
committerColin Watson <cjwatson@debian.org>2017-10-05 23:58:12 +0100
commit0556ea972b15607b7e13ff31bc05840881c91dd3 (patch)
treed6b8d48062d0278b5ae0eeff42d0e9afa9f26860 /ssh-keygen.c
parentdb2122d97eb1ecdd8d99b7bf79b0dd2b5addfd92 (diff)
parent801a62eedaaf47b20dbf4b426dc3e084bf0c8d49 (diff)
New upstream release (7.6p1)
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c292
1 files changed, 203 insertions, 89 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index f17af036b..835f7d016 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.299 2017/03/10 04:26:06 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.307 2017/07/07 03:53:12 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
@@ -41,7 +41,6 @@
41 41
42#include "xmalloc.h" 42#include "xmalloc.h"
43#include "sshkey.h" 43#include "sshkey.h"
44#include "rsa.h"
45#include "authfile.h" 44#include "authfile.h"
46#include "uuencode.h" 45#include "uuencode.h"
47#include "sshbuf.h" 46#include "sshbuf.h"
@@ -59,6 +58,7 @@
59#include "krl.h" 58#include "krl.h"
60#include "digest.h" 59#include "digest.h"
61#include "utf8.h" 60#include "utf8.h"
61#include "authfd.h"
62 62
63#ifdef WITH_OPENSSL 63#ifdef WITH_OPENSSL
64# define DEFAULT_KEY_TYPE_NAME "rsa" 64# define DEFAULT_KEY_TYPE_NAME "rsa"
@@ -121,6 +121,9 @@ char *identity_comment = NULL;
121/* Path to CA key when certifying keys. */ 121/* Path to CA key when certifying keys. */
122char *ca_key_path = NULL; 122char *ca_key_path = NULL;
123 123
124/* Prefer to use agent keys for CA signing */
125int prefer_agent = 0;
126
124/* Certificate serial number */ 127/* Certificate serial number */
125unsigned long long cert_serial = 0; 128unsigned long long cert_serial = 0;
126 129
@@ -149,6 +152,15 @@ u_int32_t certflags_flags = CERTOPT_DEFAULT;
149char *certflags_command = NULL; 152char *certflags_command = NULL;
150char *certflags_src_addr = NULL; 153char *certflags_src_addr = NULL;
151 154
155/* Arbitrary extensions specified by user */
156struct cert_userext {
157 char *key;
158 char *val;
159 int crit;
160};
161struct cert_userext *cert_userext;
162size_t ncert_userext;
163
152/* Conversion to/from various formats */ 164/* Conversion to/from various formats */
153int convert_to = 0; 165int convert_to = 0;
154int convert_from = 0; 166int convert_from = 0;
@@ -217,13 +229,21 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp)
217 OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; 229 OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS;
218 if (*bitsp > maxbits) 230 if (*bitsp > maxbits)
219 fatal("key bits exceeds maximum %d", maxbits); 231 fatal("key bits exceeds maximum %d", maxbits);
220 if (type == KEY_DSA && *bitsp != 1024) 232 switch (type) {
221 fatal("DSA keys must be 1024 bits"); 233 case KEY_DSA:
222 else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 1024) 234 if (*bitsp != 1024)
223 fatal("Key must at least be 1024 bits"); 235 fatal("Invalid DSA key length: must be 1024 bits");
224 else if (type == KEY_ECDSA && sshkey_ecdsa_bits_to_nid(*bitsp) == -1) 236 break;
225 fatal("Invalid ECDSA key length - valid lengths are " 237 case KEY_RSA:
226 "256, 384 or 521 bits"); 238 if (*bitsp < SSH_RSA_MINIMUM_MODULUS_SIZE)
239 fatal("Invalid RSA key length: minimum is %d bits",
240 SSH_RSA_MINIMUM_MODULUS_SIZE);
241 break;
242 case KEY_ECDSA:
243 if (sshkey_ecdsa_bits_to_nid(*bitsp) == -1)
244 fatal("Invalid ECDSA key length: valid lengths are "
245 "256, 384 or 521 bits");
246 }
227#endif 247#endif
228} 248}
229 249
@@ -237,9 +257,6 @@ ask_filename(struct passwd *pw, const char *prompt)
237 name = _PATH_SSH_CLIENT_ID_RSA; 257 name = _PATH_SSH_CLIENT_ID_RSA;
238 else { 258 else {
239 switch (sshkey_type_from_name(key_type_name)) { 259 switch (sshkey_type_from_name(key_type_name)) {
240 case KEY_RSA1:
241 name = _PATH_SSH_CLIENT_IDENTITY;
242 break;
243 case KEY_DSA_CERT: 260 case KEY_DSA_CERT:
244 case KEY_DSA: 261 case KEY_DSA:
245 name = _PATH_SSH_CLIENT_ID_DSA; 262 name = _PATH_SSH_CLIENT_ID_DSA;
@@ -311,8 +328,6 @@ do_convert_to_ssh2(struct passwd *pw, struct sshkey *k)
311 char comment[61]; 328 char comment[61];
312 int r; 329 int r;
313 330
314 if (k->type == KEY_RSA1)
315 fatal("version 1 keys are not supported");
316 if ((r = sshkey_to_blob(k, &blob, &len)) != 0) 331 if ((r = sshkey_to_blob(k, &blob, &len)) != 0)
317 fatal("key_to_blob failed: %s", ssh_err(r)); 332 fatal("key_to_blob failed: %s", ssh_err(r));
318 /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ 333 /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
@@ -334,7 +349,6 @@ static void
334do_convert_to_pkcs8(struct sshkey *k) 349do_convert_to_pkcs8(struct sshkey *k)
335{ 350{
336 switch (sshkey_type_plain(k->type)) { 351 switch (sshkey_type_plain(k->type)) {
337 case KEY_RSA1:
338 case KEY_RSA: 352 case KEY_RSA:
339 if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) 353 if (!PEM_write_RSA_PUBKEY(stdout, k->rsa))
340 fatal("PEM_write_RSA_PUBKEY failed"); 354 fatal("PEM_write_RSA_PUBKEY failed");
@@ -359,7 +373,6 @@ static void
359do_convert_to_pem(struct sshkey *k) 373do_convert_to_pem(struct sshkey *k)
360{ 374{
361 switch (sshkey_type_plain(k->type)) { 375 switch (sshkey_type_plain(k->type)) {
362 case KEY_RSA1:
363 case KEY_RSA: 376 case KEY_RSA:
364 if (!PEM_write_RSAPublicKey(stdout, k->rsa)) 377 if (!PEM_write_RSAPublicKey(stdout, k->rsa))
365 fatal("PEM_write_RSAPublicKey failed"); 378 fatal("PEM_write_RSAPublicKey failed");
@@ -478,7 +491,7 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
478 return NULL; 491 return NULL;
479 } 492 }
480 if ((key = sshkey_new_private(ktype)) == NULL) 493 if ((key = sshkey_new_private(ktype)) == NULL)
481 fatal("key_new_private failed"); 494 fatal("sshkey_new_private failed");
482 free(type); 495 free(type);
483 496
484 switch (key->type) { 497 switch (key->type) {
@@ -514,7 +527,7 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
514 buffer_get_bignum_bits(b, key->rsa->iqmp); 527 buffer_get_bignum_bits(b, key->rsa->iqmp);
515 buffer_get_bignum_bits(b, key->rsa->q); 528 buffer_get_bignum_bits(b, key->rsa->q);
516 buffer_get_bignum_bits(b, key->rsa->p); 529 buffer_get_bignum_bits(b, key->rsa->p);
517 if ((r = rsa_generate_additional_parameters(key->rsa)) != 0) 530 if ((r = ssh_rsa_generate_additional_parameters(key)) != 0)
518 fatal("generate RSA parameters failed: %s", ssh_err(r)); 531 fatal("generate RSA parameters failed: %s", ssh_err(r));
519 break; 532 break;
520 } 533 }
@@ -760,7 +773,7 @@ do_print_public(struct passwd *pw)
760 fatal("%s: %s", identity_file, strerror(errno)); 773 fatal("%s: %s", identity_file, strerror(errno));
761 prv = load_identity(identity_file); 774 prv = load_identity(identity_file);
762 if ((r = sshkey_write(prv, stdout)) != 0) 775 if ((r = sshkey_write(prv, stdout)) != 0)
763 error("key_write failed: %s", ssh_err(r)); 776 error("sshkey_write failed: %s", ssh_err(r));
764 sshkey_free(prv); 777 sshkey_free(prv);
765 fprintf(stdout, "\n"); 778 fprintf(stdout, "\n");
766 exit(0); 779 exit(0);
@@ -816,13 +829,6 @@ try_read_key(char **cpp)
816 struct sshkey *ret; 829 struct sshkey *ret;
817 int r; 830 int r;
818 831
819 if ((ret = sshkey_new(KEY_RSA1)) == NULL)
820 fatal("sshkey_new failed");
821 /* Try RSA1 */
822 if ((r = sshkey_read(ret, cpp)) == 0)
823 return ret;
824 /* Try modern */
825 sshkey_free(ret);
826 if ((ret = sshkey_new(KEY_UNSPEC)) == NULL) 832 if ((ret = sshkey_new(KEY_UNSPEC)) == NULL)
827 fatal("sshkey_new failed"); 833 fatal("sshkey_new failed");
828 if ((r = sshkey_read(ret, cpp)) == 0) 834 if ((r = sshkey_read(ret, cpp)) == 0)
@@ -978,9 +984,6 @@ do_gen_all_hostkeys(struct passwd *pw)
978 char *path; 984 char *path;
979 } key_types[] = { 985 } key_types[] = {
980#ifdef WITH_OPENSSL 986#ifdef WITH_OPENSSL
981#ifdef WITH_SSH1
982 { "rsa1", "RSA1", _PATH_HOST_KEY_FILE },
983#endif /* WITH_SSH1 */
984 { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE }, 987 { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE },
985 { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE }, 988 { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE },
986#ifdef OPENSSL_HAS_ECC 989#ifdef OPENSSL_HAS_ECC
@@ -994,20 +997,38 @@ do_gen_all_hostkeys(struct passwd *pw)
994 int first = 0; 997 int first = 0;
995 struct stat st; 998 struct stat st;
996 struct sshkey *private, *public; 999 struct sshkey *private, *public;
997 char comment[1024]; 1000 char comment[1024], *prv_tmp, *pub_tmp, *prv_file, *pub_file;
998 int i, type, fd, r; 1001 int i, type, fd, r;
999 FILE *f; 1002 FILE *f;
1000 1003
1001 for (i = 0; key_types[i].key_type; i++) { 1004 for (i = 0; key_types[i].key_type; i++) {
1002 if (stat(key_types[i].path, &st) == 0) 1005 public = private = NULL;
1003 continue; 1006 prv_tmp = pub_tmp = prv_file = pub_file = NULL;
1004 if (errno != ENOENT) { 1007
1008 xasprintf(&prv_file, "%s%s",
1009 identity_file, key_types[i].path);
1010
1011 /* Check whether private key exists and is not zero-length */
1012 if (stat(prv_file, &st) == 0) {
1013 if (st.st_size != 0)
1014 goto next;
1015 } else if (errno != ENOENT) {
1005 error("Could not stat %s: %s", key_types[i].path, 1016 error("Could not stat %s: %s", key_types[i].path,
1006 strerror(errno)); 1017 strerror(errno));
1007 first = 0; 1018 goto failnext;
1008 continue;
1009 } 1019 }
1010 1020
1021 /*
1022 * Private key doesn't exist or is invalid; proceed with
1023 * key generation.
1024 */
1025 xasprintf(&prv_tmp, "%s%s.XXXXXXXXXX",
1026 identity_file, key_types[i].path);
1027 xasprintf(&pub_tmp, "%s%s.pub.XXXXXXXXXX",
1028 identity_file, key_types[i].path);
1029 xasprintf(&pub_file, "%s%s.pub",
1030 identity_file, key_types[i].path);
1031
1011 if (first == 0) { 1032 if (first == 0) {
1012 first = 1; 1033 first = 1;
1013 printf("%s: generating new host keys: ", __progname); 1034 printf("%s: generating new host keys: ", __progname);
@@ -1015,56 +1036,76 @@ do_gen_all_hostkeys(struct passwd *pw)
1015 printf("%s ", key_types[i].key_type_display); 1036 printf("%s ", key_types[i].key_type_display);
1016 fflush(stdout); 1037 fflush(stdout);
1017 type = sshkey_type_from_name(key_types[i].key_type); 1038 type = sshkey_type_from_name(key_types[i].key_type);
1018 strlcpy(identity_file, key_types[i].path, sizeof(identity_file)); 1039 if ((fd = mkstemp(prv_tmp)) == -1) {
1040 error("Could not save your public key in %s: %s",
1041 prv_tmp, strerror(errno));
1042 goto failnext;
1043 }
1044 close(fd); /* just using mkstemp() to generate/reserve a name */
1019 bits = 0; 1045 bits = 0;
1020 type_bits_valid(type, NULL, &bits); 1046 type_bits_valid(type, NULL, &bits);
1021 if ((r = sshkey_generate(type, bits, &private)) != 0) { 1047 if ((r = sshkey_generate(type, bits, &private)) != 0) {
1022 error("key_generate failed: %s", ssh_err(r)); 1048 error("sshkey_generate failed: %s", ssh_err(r));
1023 first = 0; 1049 goto failnext;
1024 continue;
1025 } 1050 }
1026 if ((r = sshkey_from_private(private, &public)) != 0) 1051 if ((r = sshkey_from_private(private, &public)) != 0)
1027 fatal("sshkey_from_private failed: %s", ssh_err(r)); 1052 fatal("sshkey_from_private failed: %s", ssh_err(r));
1028 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, 1053 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
1029 hostname); 1054 hostname);
1030 if ((r = sshkey_save_private(private, identity_file, "", 1055 if ((r = sshkey_save_private(private, prv_tmp, "",
1031 comment, use_new_format, new_format_cipher, rounds)) != 0) { 1056 comment, use_new_format, new_format_cipher, rounds)) != 0) {
1032 error("Saving key \"%s\" failed: %s", 1057 error("Saving key \"%s\" failed: %s",
1033 identity_file, ssh_err(r)); 1058 prv_tmp, ssh_err(r));
1034 sshkey_free(private); 1059 goto failnext;
1035 sshkey_free(public);
1036 first = 0;
1037 continue;
1038 } 1060 }
1039 sshkey_free(private); 1061 if ((fd = mkstemp(pub_tmp)) == -1) {
1040 strlcat(identity_file, ".pub", sizeof(identity_file)); 1062 error("Could not save your public key in %s: %s",
1041 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 1063 pub_tmp, strerror(errno));
1042 if (fd == -1) { 1064 goto failnext;
1043 error("Could not save your public key in %s",
1044 identity_file);
1045 sshkey_free(public);
1046 first = 0;
1047 continue;
1048 } 1065 }
1066 (void)fchmod(fd, 0644);
1049 f = fdopen(fd, "w"); 1067 f = fdopen(fd, "w");
1050 if (f == NULL) { 1068 if (f == NULL) {
1051 error("fdopen %s failed", identity_file); 1069 error("fdopen %s failed: %s", pub_tmp, strerror(errno));
1052 close(fd); 1070 close(fd);
1053 sshkey_free(public); 1071 goto failnext;
1054 first = 0;
1055 continue;
1056 } 1072 }
1057 if ((r = sshkey_write(public, f)) != 0) { 1073 if ((r = sshkey_write(public, f)) != 0) {
1058 error("write key failed: %s", ssh_err(r)); 1074 error("write key failed: %s", ssh_err(r));
1059 fclose(f); 1075 fclose(f);
1060 sshkey_free(public); 1076 goto failnext;
1061 first = 0;
1062 continue;
1063 } 1077 }
1064 fprintf(f, " %s\n", comment); 1078 fprintf(f, " %s\n", comment);
1065 fclose(f); 1079 if (ferror(f) != 0) {
1066 sshkey_free(public); 1080 error("write key failed: %s", strerror(errno));
1081 fclose(f);
1082 goto failnext;
1083 }
1084 if (fclose(f) != 0) {
1085 error("key close failed: %s", strerror(errno));
1086 goto failnext;
1087 }
1067 1088
1089 /* Rename temporary files to their permanent locations. */
1090 if (rename(pub_tmp, pub_file) != 0) {
1091 error("Unable to move %s into position: %s",
1092 pub_file, strerror(errno));
1093 goto failnext;
1094 }
1095 if (rename(prv_tmp, prv_file) != 0) {
1096 error("Unable to move %s into position: %s",
1097 key_types[i].path, strerror(errno));
1098 failnext:
1099 first = 0;
1100 goto next;
1101 }
1102 next:
1103 sshkey_free(private);
1104 sshkey_free(public);
1105 free(prv_tmp);
1106 free(pub_tmp);
1107 free(prv_file);
1108 free(pub_file);
1068 } 1109 }
1069 if (first != 0) 1110 if (first != 0)
1070 printf("\n"); 1111 printf("\n");
@@ -1436,9 +1477,8 @@ do_change_comment(struct passwd *pw)
1436 } 1477 }
1437 } 1478 }
1438 1479
1439 if (private->type != KEY_RSA1 && private->type != KEY_ED25519 && 1480 if (private->type != KEY_ED25519 && !use_new_format) {
1440 !use_new_format) { 1481 error("Comments are only supported for keys stored in "
1441 error("Comments are only supported for RSA1 or keys stored in "
1442 "the new format (-o)."); 1482 "the new format (-o).");
1443 explicit_bzero(passphrase, strlen(passphrase)); 1483 explicit_bzero(passphrase, strlen(passphrase));
1444 sshkey_free(private); 1484 sshkey_free(private);
@@ -1476,7 +1516,7 @@ do_change_comment(struct passwd *pw)
1476 explicit_bzero(passphrase, strlen(passphrase)); 1516 explicit_bzero(passphrase, strlen(passphrase));
1477 free(passphrase); 1517 free(passphrase);
1478 if ((r = sshkey_from_private(private, &public)) != 0) 1518 if ((r = sshkey_from_private(private, &public)) != 0)
1479 fatal("key_from_private failed: %s", ssh_err(r)); 1519 fatal("sshkey_from_private failed: %s", ssh_err(r));
1480 sshkey_free(private); 1520 sshkey_free(private);
1481 1521
1482 strlcat(identity_file, ".pub", sizeof(identity_file)); 1522 strlcat(identity_file, ".pub", sizeof(identity_file));
@@ -1531,6 +1571,8 @@ add_string_option(struct sshbuf *c, const char *name, const char *value)
1531static void 1571static void
1532prepare_options_buf(struct sshbuf *c, int which) 1572prepare_options_buf(struct sshbuf *c, int which)
1533{ 1573{
1574 size_t i;
1575
1534 sshbuf_reset(c); 1576 sshbuf_reset(c);
1535 if ((which & OPTIONS_CRITICAL) != 0 && 1577 if ((which & OPTIONS_CRITICAL) != 0 &&
1536 certflags_command != NULL) 1578 certflags_command != NULL)
@@ -1553,6 +1595,17 @@ prepare_options_buf(struct sshbuf *c, int which)
1553 if ((which & OPTIONS_CRITICAL) != 0 && 1595 if ((which & OPTIONS_CRITICAL) != 0 &&
1554 certflags_src_addr != NULL) 1596 certflags_src_addr != NULL)
1555 add_string_option(c, "source-address", certflags_src_addr); 1597 add_string_option(c, "source-address", certflags_src_addr);
1598 for (i = 0; i < ncert_userext; i++) {
1599 if ((cert_userext[i].crit && (which & OPTIONS_EXTENSIONS)) ||
1600 (!cert_userext[i].crit && (which & OPTIONS_CRITICAL)))
1601 continue;
1602 if (cert_userext[i].val == NULL)
1603 add_flag_option(c, cert_userext[i].key);
1604 else {
1605 add_string_option(c, cert_userext[i].key,
1606 cert_userext[i].val);
1607 }
1608 }
1556} 1609}
1557 1610
1558static struct sshkey * 1611static struct sshkey *
@@ -1585,24 +1638,66 @@ load_pkcs11_key(char *path)
1585#endif /* ENABLE_PKCS11 */ 1638#endif /* ENABLE_PKCS11 */
1586} 1639}
1587 1640
1641/* Signer for sshkey_certify_custom that uses the agent */
1642static int
1643agent_signer(const struct sshkey *key, u_char **sigp, size_t *lenp,
1644 const u_char *data, size_t datalen,
1645 const char *alg, u_int compat, void *ctx)
1646{
1647 int *agent_fdp = (int *)ctx;
1648
1649 return ssh_agent_sign(*agent_fdp, key, sigp, lenp,
1650 data, datalen, alg, compat);
1651}
1652
1588static void 1653static void
1589do_ca_sign(struct passwd *pw, int argc, char **argv) 1654do_ca_sign(struct passwd *pw, int argc, char **argv)
1590{ 1655{
1591 int r, i, fd; 1656 int r, i, fd, found, agent_fd = -1;
1592 u_int n; 1657 u_int n;
1593 struct sshkey *ca, *public; 1658 struct sshkey *ca, *public;
1594 char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL; 1659 char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
1595 FILE *f; 1660 FILE *f;
1661 struct ssh_identitylist *agent_ids;
1662 size_t j;
1596 1663
1597#ifdef ENABLE_PKCS11 1664#ifdef ENABLE_PKCS11
1598 pkcs11_init(1); 1665 pkcs11_init(1);
1599#endif 1666#endif
1600 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); 1667 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1601 if (pkcs11provider != NULL) { 1668 if (pkcs11provider != NULL) {
1669 /* If a PKCS#11 token was specified then try to use it */
1602 if ((ca = load_pkcs11_key(tmp)) == NULL) 1670 if ((ca = load_pkcs11_key(tmp)) == NULL)
1603 fatal("No PKCS#11 key matching %s found", ca_key_path); 1671 fatal("No PKCS#11 key matching %s found", ca_key_path);
1604 } else 1672 } else if (prefer_agent) {
1673 /*
1674 * Agent signature requested. Try to use agent after making
1675 * sure the public key specified is actually present in the
1676 * agent.
1677 */
1678 if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
1679 fatal("Cannot load CA public key %s: %s",
1680 tmp, ssh_err(r));
1681 if ((r = ssh_get_authentication_socket(&agent_fd)) != 0)
1682 fatal("Cannot use public key for CA signature: %s",
1683 ssh_err(r));
1684 if ((r = ssh_fetch_identitylist(agent_fd, &agent_ids)) != 0)
1685 fatal("Retrieve agent key list: %s", ssh_err(r));
1686 found = 0;
1687 for (j = 0; j < agent_ids->nkeys; j++) {
1688 if (sshkey_equal(ca, agent_ids->keys[j])) {
1689 found = 1;
1690 break;
1691 }
1692 }
1693 if (!found)
1694 fatal("CA key %s not found in agent", tmp);
1695 ssh_free_identitylist(agent_ids);
1696 ca->flags |= SSHKEY_FLAG_EXT;
1697 } else {
1698 /* CA key is assumed to be a private key on the filesystem */
1605 ca = load_identity(tmp); 1699 ca = load_identity(tmp);
1700 }
1606 free(tmp); 1701 free(tmp);
1607 1702
1608 if (key_type_name != NULL && 1703 if (key_type_name != NULL &&
@@ -1650,10 +1745,18 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1650 OPTIONS_EXTENSIONS); 1745 OPTIONS_EXTENSIONS);
1651 if ((r = sshkey_from_private(ca, 1746 if ((r = sshkey_from_private(ca,
1652 &public->cert->signature_key)) != 0) 1747 &public->cert->signature_key)) != 0)
1653 fatal("key_from_private (ca key): %s", ssh_err(r)); 1748 fatal("sshkey_from_private (ca key): %s", ssh_err(r));
1654 1749
1655 if ((r = sshkey_certify(public, ca, key_type_name)) != 0) 1750 if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) {
1656 fatal("Couldn't certify key %s: %s", tmp, ssh_err(r)); 1751 if ((r = sshkey_certify_custom(public, ca,
1752 key_type_name, agent_signer, &agent_fd)) != 0)
1753 fatal("Couldn't certify key %s via agent: %s",
1754 tmp, ssh_err(r));
1755 } else {
1756 if ((sshkey_certify(public, ca, key_type_name)) != 0)
1757 fatal("Couldn't certify key %s: %s",
1758 tmp, ssh_err(r));
1759 }
1657 1760
1658 if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0) 1761 if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
1659 *cp = '\0'; 1762 *cp = '\0';
@@ -1789,7 +1892,8 @@ parse_cert_times(char *timespec)
1789static void 1892static void
1790add_cert_option(char *opt) 1893add_cert_option(char *opt)
1791{ 1894{
1792 char *val; 1895 char *val, *cp;
1896 int iscrit = 0;
1793 1897
1794 if (strcasecmp(opt, "clear") == 0) 1898 if (strcasecmp(opt, "clear") == 0)
1795 certflags_flags = 0; 1899 certflags_flags = 0;
@@ -1829,6 +1933,18 @@ add_cert_option(char *opt)
1829 if (addr_match_cidr_list(NULL, val) != 0) 1933 if (addr_match_cidr_list(NULL, val) != 0)
1830 fatal("Invalid source-address list"); 1934 fatal("Invalid source-address list");
1831 certflags_src_addr = xstrdup(val); 1935 certflags_src_addr = xstrdup(val);
1936 } else if (strncasecmp(opt, "extension:", 10) == 0 ||
1937 (iscrit = (strncasecmp(opt, "critical:", 9) == 0))) {
1938 val = xstrdup(strchr(opt, ':') + 1);
1939 if ((cp = strchr(val, '=')) != NULL)
1940 *cp++ = '\0';
1941 cert_userext = xreallocarray(cert_userext, ncert_userext + 1,
1942 sizeof(*cert_userext));
1943 cert_userext[ncert_userext].key = val;
1944 cert_userext[ncert_userext].val = cp == NULL ?
1945 NULL : xstrdup(cp);
1946 cert_userext[ncert_userext].crit = iscrit;
1947 ncert_userext++;
1832 } else 1948 } else
1833 fatal("Unsupported certificate option \"%s\"", opt); 1949 fatal("Unsupported certificate option \"%s\"", opt);
1834} 1950}
@@ -1955,7 +2071,7 @@ do_show_cert(struct passwd *pw)
1955 if (*cp == '#' || *cp == '\0') 2071 if (*cp == '#' || *cp == '\0')
1956 continue; 2072 continue;
1957 if ((key = sshkey_new(KEY_UNSPEC)) == NULL) 2073 if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
1958 fatal("key_new"); 2074 fatal("sshkey_new");
1959 if ((r = sshkey_read(key, &cp)) != 0) { 2075 if ((r = sshkey_read(key, &cp)) != 0) {
1960 error("%s:%lu: invalid key: %s", path, 2076 error("%s:%lu: invalid key: %s", path,
1961 lnum, ssh_err(r)); 2077 lnum, ssh_err(r));
@@ -2101,7 +2217,7 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
2101 */ 2217 */
2102 } 2218 }
2103 if ((key = sshkey_new(KEY_UNSPEC)) == NULL) 2219 if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
2104 fatal("key_new"); 2220 fatal("sshkey_new");
2105 if ((r = sshkey_read(key, &cp)) != 0) 2221 if ((r = sshkey_read(key, &cp)) != 0)
2106 fatal("%s:%lu: invalid key: %s", 2222 fatal("%s:%lu: invalid key: %s",
2107 path, lnum, ssh_err(r)); 2223 path, lnum, ssh_err(r));
@@ -2209,17 +2325,11 @@ do_check_krl(struct passwd *pw, int argc, char **argv)
2209 exit(ret); 2325 exit(ret);
2210} 2326}
2211 2327
2212#ifdef WITH_SSH1
2213# define RSA1_USAGE " | rsa1"
2214#else
2215# define RSA1_USAGE ""
2216#endif
2217
2218static void 2328static void
2219usage(void) 2329usage(void)
2220{ 2330{
2221 fprintf(stderr, 2331 fprintf(stderr,
2222 "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa%s]\n" 2332 "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa]\n"
2223 " [-N new_passphrase] [-C comment] [-f output_keyfile]\n" 2333 " [-N new_passphrase] [-C comment] [-f output_keyfile]\n"
2224 " ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]\n" 2334 " ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]\n"
2225 " ssh-keygen -i [-m key_format] [-f input_keyfile]\n" 2335 " ssh-keygen -i [-m key_format] [-f input_keyfile]\n"
@@ -2227,7 +2337,7 @@ usage(void)
2227 " ssh-keygen -y [-f input_keyfile]\n" 2337 " ssh-keygen -y [-f input_keyfile]\n"
2228 " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n" 2338 " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n"
2229 " ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n" 2339 " ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n"
2230 " ssh-keygen -B [-f input_keyfile]\n", RSA1_USAGE); 2340 " ssh-keygen -B [-f input_keyfile]\n");
2231#ifdef ENABLE_PKCS11 2341#ifdef ENABLE_PKCS11
2232 fprintf(stderr, 2342 fprintf(stderr,
2233 " ssh-keygen -D pkcs11\n"); 2343 " ssh-keygen -D pkcs11\n");
@@ -2242,8 +2352,9 @@ usage(void)
2242 " ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n" 2352 " ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n"
2243 " [-j start_line] [-K checkpt] [-W generator]\n" 2353 " [-j start_line] [-K checkpt] [-W generator]\n"
2244#endif 2354#endif
2245 " ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals]\n" 2355 " ssh-keygen -s ca_key -I certificate_identity [-h] [-U]\n"
2246 " [-O option] [-V validity_interval] [-z serial_number] file ...\n" 2356 " [-D pkcs11_provider] [-n principals] [-O option]\n"
2357 " [-V validity_interval] [-z serial_number] file ...\n"
2247 " ssh-keygen -L [-f input_keyfile]\n" 2358 " ssh-keygen -L [-f input_keyfile]\n"
2248 " ssh-keygen -A\n" 2359 " ssh-keygen -A\n"
2249 " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n" 2360 " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
@@ -2301,8 +2412,8 @@ main(int argc, char **argv)
2301 if (gethostname(hostname, sizeof(hostname)) < 0) 2412 if (gethostname(hostname, sizeof(hostname)) < 0)
2302 fatal("gethostname: %s", strerror(errno)); 2413 fatal("gethostname: %s", strerror(errno));
2303 2414
2304 /* Remaining characters: UYdw */ 2415 /* Remaining characters: Ydw */
2305 while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy" 2416 while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvxy"
2306 "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:" 2417 "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:"
2307 "a:b:f:g:j:m:n:r:s:t:z:")) != -1) { 2418 "a:b:f:g:j:m:n:r:s:t:z:")) != -1) {
2308 switch (opt) { 2419 switch (opt) {
@@ -2429,6 +2540,9 @@ main(int argc, char **argv)
2429 case 'D': 2540 case 'D':
2430 pkcs11provider = optarg; 2541 pkcs11provider = optarg;
2431 break; 2542 break;
2543 case 'U':
2544 prefer_agent = 1;
2545 break;
2432 case 'u': 2546 case 'u':
2433 update_krl = 1; 2547 update_krl = 1;
2434 break; 2548 break;
@@ -2648,9 +2762,9 @@ main(int argc, char **argv)
2648 printf("Generating public/private %s key pair.\n", 2762 printf("Generating public/private %s key pair.\n",
2649 key_type_name); 2763 key_type_name);
2650 if ((r = sshkey_generate(type, bits, &private)) != 0) 2764 if ((r = sshkey_generate(type, bits, &private)) != 0)
2651 fatal("key_generate failed"); 2765 fatal("sshkey_generate failed");
2652 if ((r = sshkey_from_private(private, &public)) != 0) 2766 if ((r = sshkey_from_private(private, &public)) != 0)
2653 fatal("key_from_private failed: %s\n", ssh_err(r)); 2767 fatal("sshkey_from_private failed: %s\n", ssh_err(r));
2654 2768
2655 if (!have_identity) 2769 if (!have_identity)
2656 ask_filename(pw, "Enter file in which to save the key"); 2770 ask_filename(pw, "Enter file in which to save the key");