summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2015-08-19 17:00:17 +0100
committerColin Watson <cjwatson@debian.org>2015-08-19 17:40:32 +0100
commit927d0032b865f05679d3cc052bc13cb0e6490283 (patch)
tree69f782deb79182f26069ff41e9539f17e6e44912 /ssh-keygen.c
parentd35c65e77ab6a6a95fefa2c852827ba08e507f0b (diff)
parent810eecd6b2e03770f21e46b5cb8ce8c7fcd46da8 (diff)
New upstream release (6.9p1).
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c349
1 files changed, 159 insertions, 190 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index a3c2362a2..8259d87e7 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.266 2015/02/26 20:45:47 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.274 2015/05/28 07:37:31 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
@@ -58,6 +58,12 @@
58#include "krl.h" 58#include "krl.h"
59#include "digest.h" 59#include "digest.h"
60 60
61#ifdef WITH_OPENSSL
62# define DEFAULT_KEY_TYPE_NAME "rsa"
63#else
64# define DEFAULT_KEY_TYPE_NAME "ed25519"
65#endif
66
61/* Number of bits in the RSA/DSA key. This value can be set on the command line. */ 67/* Number of bits in the RSA/DSA key. This value can be set on the command line. */
62#define DEFAULT_BITS 2048 68#define DEFAULT_BITS 2048
63#define DEFAULT_BITS_DSA 1024 69#define DEFAULT_BITS_DSA 1024
@@ -174,23 +180,22 @@ extern char *__progname;
174 180
175char hostname[NI_MAXHOST]; 181char hostname[NI_MAXHOST];
176 182
183#ifdef WITH_OPENSSL
177/* moduli.c */ 184/* moduli.c */
178int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); 185int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
179int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long, 186int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long,
180 unsigned long); 187 unsigned long);
188#endif
181 189
182static void 190static void
183type_bits_valid(int type, const char *name, u_int32_t *bitsp) 191type_bits_valid(int type, const char *name, u_int32_t *bitsp)
184{ 192{
185#ifdef WITH_OPENSSL 193#ifdef WITH_OPENSSL
186 u_int maxbits; 194 u_int maxbits, nid;
187 int nid;
188#endif 195#endif
189 196
190 if (type == KEY_UNSPEC) { 197 if (type == KEY_UNSPEC)
191 fprintf(stderr, "unknown key type %s\n", key_type_name); 198 fatal("unknown key type %s", key_type_name);
192 exit(1);
193 }
194 if (*bitsp == 0) { 199 if (*bitsp == 0) {
195#ifdef WITH_OPENSSL 200#ifdef WITH_OPENSSL
196 if (type == KEY_DSA) 201 if (type == KEY_DSA)
@@ -208,10 +213,8 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp)
208#ifdef WITH_OPENSSL 213#ifdef WITH_OPENSSL
209 maxbits = (type == KEY_DSA) ? 214 maxbits = (type == KEY_DSA) ?
210 OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; 215 OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS;
211 if (*bitsp > maxbits) { 216 if (*bitsp > maxbits)
212 fprintf(stderr, "key bits exceeds maximum %d\n", maxbits); 217 fatal("key bits exceeds maximum %d", maxbits);
213 exit(1);
214 }
215 if (type == KEY_DSA && *bitsp != 1024) 218 if (type == KEY_DSA && *bitsp != 1024)
216 fatal("DSA keys must be 1024 bits"); 219 fatal("DSA keys must be 1024 bits");
217 else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768) 220 else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768)
@@ -256,13 +259,13 @@ ask_filename(struct passwd *pw, const char *prompt)
256 name = _PATH_SSH_CLIENT_ID_ED25519; 259 name = _PATH_SSH_CLIENT_ID_ED25519;
257 break; 260 break;
258 default: 261 default:
259 fprintf(stderr, "bad key type\n"); 262 fatal("bad key type");
260 exit(1);
261 break;
262 } 263 }
263 } 264 }
264 snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name); 265 snprintf(identity_file, sizeof(identity_file),
265 fprintf(stderr, "%s (%s): ", prompt, identity_file); 266 "%s/%s", pw->pw_dir, name);
267 printf("%s (%s): ", prompt, identity_file);
268 fflush(stdout);
266 if (fgets(buf, sizeof(buf), stdin) == NULL) 269 if (fgets(buf, sizeof(buf), stdin) == NULL)
267 exit(1); 270 exit(1);
268 buf[strcspn(buf, "\n")] = '\0'; 271 buf[strcspn(buf, "\n")] = '\0';
@@ -308,14 +311,10 @@ do_convert_to_ssh2(struct passwd *pw, struct sshkey *k)
308 char comment[61]; 311 char comment[61];
309 int r; 312 int r;
310 313
311 if (k->type == KEY_RSA1) { 314 if (k->type == KEY_RSA1)
312 fprintf(stderr, "version 1 keys are not supported\n"); 315 fatal("version 1 keys are not supported");
313 exit(1); 316 if ((r = sshkey_to_blob(k, &blob, &len)) != 0)
314 } 317 fatal("key_to_blob failed: %s", ssh_err(r));
315 if ((r = sshkey_to_blob(k, &blob, &len)) != 0) {
316 fprintf(stderr, "key_to_blob failed: %s\n", ssh_err(r));
317 exit(1);
318 }
319 /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ 318 /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
320 snprintf(comment, sizeof(comment), 319 snprintf(comment, sizeof(comment),
321 "%u-bit %s, converted by %s@%s from OpenSSH", 320 "%u-bit %s, converted by %s@%s from OpenSSH",
@@ -544,17 +543,13 @@ get_line(FILE *fp, char *line, size_t len)
544 543
545 line[0] = '\0'; 544 line[0] = '\0';
546 while ((c = fgetc(fp)) != EOF) { 545 while ((c = fgetc(fp)) != EOF) {
547 if (pos >= len - 1) { 546 if (pos >= len - 1)
548 fprintf(stderr, "input line too long.\n"); 547 fatal("input line too long.");
549 exit(1);
550 }
551 switch (c) { 548 switch (c) {
552 case '\r': 549 case '\r':
553 c = fgetc(fp); 550 c = fgetc(fp);
554 if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) { 551 if (c != EOF && c != '\n' && ungetc(c, fp) == EOF)
555 fprintf(stderr, "unget: %s\n", strerror(errno)); 552 fatal("unget: %s", strerror(errno));
556 exit(1);
557 }
558 return pos; 553 return pos;
559 case '\n': 554 case '\n':
560 return pos; 555 return pos;
@@ -606,16 +601,12 @@ do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private)
606 (encoded[len-3] == '=')) 601 (encoded[len-3] == '='))
607 encoded[len-3] = '\0'; 602 encoded[len-3] = '\0';
608 blen = uudecode(encoded, blob, sizeof(blob)); 603 blen = uudecode(encoded, blob, sizeof(blob));
609 if (blen < 0) { 604 if (blen < 0)
610 fprintf(stderr, "uudecode failed.\n"); 605 fatal("uudecode failed.");
611 exit(1);
612 }
613 if (*private) 606 if (*private)
614 *k = do_convert_private_ssh2_from_blob(blob, blen); 607 *k = do_convert_private_ssh2_from_blob(blob, blen);
615 else if ((r = sshkey_from_blob(blob, blen, k)) != 0) { 608 else if ((r = sshkey_from_blob(blob, blen, k)) != 0)
616 fprintf(stderr, "decode blob failed: %s\n", ssh_err(r)); 609 fatal("decode blob failed: %s", ssh_err(r));
617 exit(1);
618 }
619 fclose(fp); 610 fclose(fp);
620} 611}
621 612
@@ -749,10 +740,8 @@ do_convert_from(struct passwd *pw)
749 } 740 }
750 } 741 }
751 742
752 if (!ok) { 743 if (!ok)
753 fprintf(stderr, "key write failed\n"); 744 fatal("key write failed");
754 exit(1);
755 }
756 sshkey_free(k); 745 sshkey_free(k);
757 exit(0); 746 exit(0);
758} 747}
@@ -767,13 +756,11 @@ do_print_public(struct passwd *pw)
767 756
768 if (!have_identity) 757 if (!have_identity)
769 ask_filename(pw, "Enter file in which the key is"); 758 ask_filename(pw, "Enter file in which the key is");
770 if (stat(identity_file, &st) < 0) { 759 if (stat(identity_file, &st) < 0)
771 perror(identity_file); 760 fatal("%s: %s", identity_file, strerror(errno));
772 exit(1);
773 }
774 prv = load_identity(identity_file); 761 prv = load_identity(identity_file);
775 if ((r = sshkey_write(prv, stdout)) != 0) 762 if ((r = sshkey_write(prv, stdout)) != 0)
776 fprintf(stderr, "key_write failed: %s", ssh_err(r)); 763 error("key_write failed: %s", ssh_err(r));
777 sshkey_free(prv); 764 sshkey_free(prv);
778 fprintf(stdout, "\n"); 765 fprintf(stdout, "\n");
779 exit(0); 766 exit(0);
@@ -838,10 +825,8 @@ do_fingerprint(struct passwd *pw)
838 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; 825 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
839 if (!have_identity) 826 if (!have_identity)
840 ask_filename(pw, "Enter file in which the key is"); 827 ask_filename(pw, "Enter file in which the key is");
841 if (stat(identity_file, &st) < 0) { 828 if (stat(identity_file, &st) < 0)
842 perror(identity_file); 829 fatal("%s: %s", identity_file, strerror(errno));
843 exit(1);
844 }
845 if ((r = sshkey_load_public(identity_file, &public, &comment)) != 0) 830 if ((r = sshkey_load_public(identity_file, &public, &comment)) != 0)
846 debug2("Error loading public key \"%s\": %s", 831 debug2("Error loading public key \"%s\": %s",
847 identity_file, ssh_err(r)); 832 identity_file, ssh_err(r));
@@ -933,10 +918,8 @@ do_fingerprint(struct passwd *pw)
933 } 918 }
934 fclose(f); 919 fclose(f);
935 920
936 if (invalid) { 921 if (invalid)
937 printf("%s is not a public key file.\n", identity_file); 922 fatal("%s is not a public key file.", identity_file);
938 exit(1);
939 }
940 exit(0); 923 exit(0);
941} 924}
942 925
@@ -948,12 +931,16 @@ do_gen_all_hostkeys(struct passwd *pw)
948 char *key_type_display; 931 char *key_type_display;
949 char *path; 932 char *path;
950 } key_types[] = { 933 } key_types[] = {
934#ifdef WITH_OPENSSL
935#ifdef WITH_SSH1
951 { "rsa1", "RSA1", _PATH_HOST_KEY_FILE }, 936 { "rsa1", "RSA1", _PATH_HOST_KEY_FILE },
937#endif /* WITH_SSH1 */
952 { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE }, 938 { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE },
953 { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE }, 939 { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE },
954#ifdef OPENSSL_HAS_ECC 940#ifdef OPENSSL_HAS_ECC
955 { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE }, 941 { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE },
956#endif 942#endif /* OPENSSL_HAS_ECC */
943#endif /* WITH_OPENSSL */
957 { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE }, 944 { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE },
958 { NULL, NULL, NULL } 945 { NULL, NULL, NULL }
959 }; 946 };
@@ -969,7 +956,7 @@ do_gen_all_hostkeys(struct passwd *pw)
969 if (stat(key_types[i].path, &st) == 0) 956 if (stat(key_types[i].path, &st) == 0)
970 continue; 957 continue;
971 if (errno != ENOENT) { 958 if (errno != ENOENT) {
972 printf("Could not stat %s: %s", key_types[i].path, 959 error("Could not stat %s: %s", key_types[i].path,
973 strerror(errno)); 960 strerror(errno));
974 first = 0; 961 first = 0;
975 continue; 962 continue;
@@ -986,8 +973,7 @@ do_gen_all_hostkeys(struct passwd *pw)
986 bits = 0; 973 bits = 0;
987 type_bits_valid(type, NULL, &bits); 974 type_bits_valid(type, NULL, &bits);
988 if ((r = sshkey_generate(type, bits, &private)) != 0) { 975 if ((r = sshkey_generate(type, bits, &private)) != 0) {
989 fprintf(stderr, "key_generate failed: %s\n", 976 error("key_generate failed: %s", ssh_err(r));
990 ssh_err(r));
991 first = 0; 977 first = 0;
992 continue; 978 continue;
993 } 979 }
@@ -997,8 +983,8 @@ do_gen_all_hostkeys(struct passwd *pw)
997 hostname); 983 hostname);
998 if ((r = sshkey_save_private(private, identity_file, "", 984 if ((r = sshkey_save_private(private, identity_file, "",
999 comment, use_new_format, new_format_cipher, rounds)) != 0) { 985 comment, use_new_format, new_format_cipher, rounds)) != 0) {
1000 printf("Saving key \"%s\" failed: %s\n", identity_file, 986 error("Saving key \"%s\" failed: %s",
1001 ssh_err(r)); 987 identity_file, ssh_err(r));
1002 sshkey_free(private); 988 sshkey_free(private);
1003 sshkey_free(public); 989 sshkey_free(public);
1004 first = 0; 990 first = 0;
@@ -1008,7 +994,7 @@ do_gen_all_hostkeys(struct passwd *pw)
1008 strlcat(identity_file, ".pub", sizeof(identity_file)); 994 strlcat(identity_file, ".pub", sizeof(identity_file));
1009 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 995 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1010 if (fd == -1) { 996 if (fd == -1) {
1011 printf("Could not save your public key in %s\n", 997 error("Could not save your public key in %s",
1012 identity_file); 998 identity_file);
1013 sshkey_free(public); 999 sshkey_free(public);
1014 first = 0; 1000 first = 0;
@@ -1016,14 +1002,14 @@ do_gen_all_hostkeys(struct passwd *pw)
1016 } 1002 }
1017 f = fdopen(fd, "w"); 1003 f = fdopen(fd, "w");
1018 if (f == NULL) { 1004 if (f == NULL) {
1019 printf("fdopen %s failed\n", identity_file); 1005 error("fdopen %s failed", identity_file);
1020 close(fd); 1006 close(fd);
1021 sshkey_free(public); 1007 sshkey_free(public);
1022 first = 0; 1008 first = 0;
1023 continue; 1009 continue;
1024 } 1010 }
1025 if ((r = sshkey_write(public, f)) != 0) { 1011 if ((r = sshkey_write(public, f)) != 0) {
1026 fprintf(stderr, "write key failed: %s\n", ssh_err(r)); 1012 error("write key failed: %s", ssh_err(r));
1027 fclose(f); 1013 fclose(f);
1028 sshkey_free(public); 1014 sshkey_free(public);
1029 first = 0; 1015 first = 0;
@@ -1064,8 +1050,8 @@ known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx)
1064 has_wild || l->marker != MRK_NONE) { 1050 has_wild || l->marker != MRK_NONE) {
1065 fprintf(ctx->out, "%s\n", l->line); 1051 fprintf(ctx->out, "%s\n", l->line);
1066 if (has_wild && !find_host) { 1052 if (has_wild && !find_host) {
1067 fprintf(stderr, "%s:%ld: ignoring host name " 1053 logit("%s:%ld: ignoring host name "
1068 "with wildcard: %.64s\n", l->path, 1054 "with wildcard: %.64s", l->path,
1069 l->linenum, l->hosts); 1055 l->linenum, l->hosts);
1070 } 1056 }
1071 return 0; 1057 return 0;
@@ -1086,7 +1072,7 @@ known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx)
1086 case HKF_STATUS_INVALID: 1072 case HKF_STATUS_INVALID:
1087 /* Retain invalid lines, but mark file as invalid. */ 1073 /* Retain invalid lines, but mark file as invalid. */
1088 ctx->invalid = 1; 1074 ctx->invalid = 1;
1089 fprintf(stderr, "%s:%ld: invalid line\n", l->path, l->linenum); 1075 logit("%s:%ld: invalid line", l->path, l->linenum);
1090 /* FALLTHROUGH */ 1076 /* FALLTHROUGH */
1091 default: 1077 default:
1092 fprintf(ctx->out, "%s\n", l->line); 1078 fprintf(ctx->out, "%s\n", l->line);
@@ -1100,6 +1086,12 @@ static int
1100known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx) 1086known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
1101{ 1087{
1102 struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx; 1088 struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx;
1089 enum sshkey_fp_rep rep;
1090 int fptype;
1091 char *fp;
1092
1093 fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
1094 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
1103 1095
1104 if (l->status == HKF_STATUS_MATCHED) { 1096 if (l->status == HKF_STATUS_MATCHED) {
1105 if (delete_host) { 1097 if (delete_host) {
@@ -1128,7 +1120,12 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
1128 } 1120 }
1129 if (hash_hosts) 1121 if (hash_hosts)
1130 known_hosts_hash(l, ctx); 1122 known_hosts_hash(l, ctx);
1131 else 1123 else if (print_fingerprint) {
1124 fp = sshkey_fingerprint(l->key, fptype, rep);
1125 printf("%s %s %s %s\n", ctx->host,
1126 sshkey_type(l->key), fp, l->comment);
1127 free(fp);
1128 } else
1132 fprintf(ctx->out, "%s\n", l->line); 1129 fprintf(ctx->out, "%s\n", l->line);
1133 return 0; 1130 return 0;
1134 } 1131 }
@@ -1136,8 +1133,7 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
1136 /* Retain non-matching hosts when deleting */ 1133 /* Retain non-matching hosts when deleting */
1137 if (l->status == HKF_STATUS_INVALID) { 1134 if (l->status == HKF_STATUS_INVALID) {
1138 ctx->invalid = 1; 1135 ctx->invalid = 1;
1139 fprintf(stderr, "%s:%ld: invalid line\n", 1136 logit("%s:%ld: invalid line", l->path, l->linenum);
1140 l->path, l->linenum);
1141 } 1137 }
1142 fprintf(ctx->out, "%s\n", l->line); 1138 fprintf(ctx->out, "%s\n", l->line);
1143 } 1139 }
@@ -1150,6 +1146,7 @@ do_known_hosts(struct passwd *pw, const char *name)
1150 char *cp, tmp[PATH_MAX], old[PATH_MAX]; 1146 char *cp, tmp[PATH_MAX], old[PATH_MAX];
1151 int r, fd, oerrno, inplace = 0; 1147 int r, fd, oerrno, inplace = 0;
1152 struct known_hosts_ctx ctx; 1148 struct known_hosts_ctx ctx;
1149 u_int foreach_options;
1153 1150
1154 if (!have_identity) { 1151 if (!have_identity) {
1155 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); 1152 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
@@ -1186,26 +1183,26 @@ do_known_hosts(struct passwd *pw, const char *name)
1186 } 1183 }
1187 1184
1188 /* XXX support identity_file == "-" for stdin */ 1185 /* XXX support identity_file == "-" for stdin */
1186 foreach_options = find_host ? HKF_WANT_MATCH : 0;
1187 foreach_options |= print_fingerprint ? HKF_WANT_PARSE_KEY : 0;
1189 if ((r = hostkeys_foreach(identity_file, 1188 if ((r = hostkeys_foreach(identity_file,
1190 hash_hosts ? known_hosts_hash : known_hosts_find_delete, &ctx, 1189 hash_hosts ? known_hosts_hash : known_hosts_find_delete, &ctx,
1191 name, NULL, find_host ? HKF_WANT_MATCH : 0)) != 0) 1190 name, NULL, foreach_options)) != 0)
1192 fatal("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); 1191 fatal("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r));
1193 1192
1194 if (inplace) 1193 if (inplace)
1195 fclose(ctx.out); 1194 fclose(ctx.out);
1196 1195
1197 if (ctx.invalid) { 1196 if (ctx.invalid) {
1198 fprintf(stderr, "%s is not a valid known_hosts file.\n", 1197 error("%s is not a valid known_hosts file.", identity_file);
1199 identity_file);
1200 if (inplace) { 1198 if (inplace) {
1201 fprintf(stderr, "Not replacing existing known_hosts " 1199 error("Not replacing existing known_hosts "
1202 "file because of errors\n"); 1200 "file because of errors");
1203 unlink(tmp); 1201 unlink(tmp);
1204 } 1202 }
1205 exit(1); 1203 exit(1);
1206 } else if (delete_host && !ctx.found_key) { 1204 } else if (delete_host && !ctx.found_key) {
1207 fprintf(stderr, "Host %s not found in %s\n", 1205 logit("Host %s not found in %s", name, identity_file);
1208 name, identity_file);
1209 unlink(tmp); 1206 unlink(tmp);
1210 } else if (inplace) { 1207 } else if (inplace) {
1211 /* Backup existing file */ 1208 /* Backup existing file */
@@ -1223,13 +1220,12 @@ do_known_hosts(struct passwd *pw, const char *name)
1223 exit(1); 1220 exit(1);
1224 } 1221 }
1225 1222
1226 fprintf(stderr, "%s updated.\n", identity_file); 1223 printf("%s updated.\n", identity_file);
1227 fprintf(stderr, "Original contents retained as %s\n", old); 1224 printf("Original contents retained as %s\n", old);
1228 if (ctx.has_unhashed) { 1225 if (ctx.has_unhashed) {
1229 fprintf(stderr, "WARNING: %s contains unhashed " 1226 logit("WARNING: %s contains unhashed entries", old);
1230 "entries\n", old); 1227 logit("Delete this file to ensure privacy "
1231 fprintf(stderr, "Delete this file to ensure privacy " 1228 "of hostnames");
1232 "of hostnames\n");
1233 } 1229 }
1234 } 1230 }
1235 1231
@@ -1251,10 +1247,8 @@ do_change_passphrase(struct passwd *pw)
1251 1247
1252 if (!have_identity) 1248 if (!have_identity)
1253 ask_filename(pw, "Enter file in which the key is"); 1249 ask_filename(pw, "Enter file in which the key is");
1254 if (stat(identity_file, &st) < 0) { 1250 if (stat(identity_file, &st) < 0)
1255 perror(identity_file); 1251 fatal("%s: %s", identity_file, strerror(errno));
1256 exit(1);
1257 }
1258 /* Try to load the file with empty passphrase. */ 1252 /* Try to load the file with empty passphrase. */
1259 r = sshkey_load_private(identity_file, "", &private, &comment); 1253 r = sshkey_load_private(identity_file, "", &private, &comment);
1260 if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) { 1254 if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) {
@@ -1272,9 +1266,7 @@ do_change_passphrase(struct passwd *pw)
1272 goto badkey; 1266 goto badkey;
1273 } else if (r != 0) { 1267 } else if (r != 0) {
1274 badkey: 1268 badkey:
1275 fprintf(stderr, "Failed to load key \"%s\": %s\n", 1269 fatal("Failed to load key %s: %s", identity_file, ssh_err(r));
1276 identity_file, ssh_err(r));
1277 exit(1);
1278 } 1270 }
1279 if (comment) 1271 if (comment)
1280 printf("Key has comment '%s'\n", comment); 1272 printf("Key has comment '%s'\n", comment);
@@ -1307,7 +1299,7 @@ do_change_passphrase(struct passwd *pw)
1307 /* Save the file using the new passphrase. */ 1299 /* Save the file using the new passphrase. */
1308 if ((r = sshkey_save_private(private, identity_file, passphrase1, 1300 if ((r = sshkey_save_private(private, identity_file, passphrase1,
1309 comment, use_new_format, new_format_cipher, rounds)) != 0) { 1301 comment, use_new_format, new_format_cipher, rounds)) != 0) {
1310 printf("Saving key \"%s\" failed: %s.\n", 1302 error("Saving key \"%s\" failed: %s.",
1311 identity_file, ssh_err(r)); 1303 identity_file, ssh_err(r));
1312 explicit_bzero(passphrase1, strlen(passphrase1)); 1304 explicit_bzero(passphrase1, strlen(passphrase1));
1313 free(passphrase1); 1305 free(passphrase1);
@@ -1341,14 +1333,11 @@ do_print_resource_record(struct passwd *pw, char *fname, char *hname)
1341 if (stat(fname, &st) < 0) { 1333 if (stat(fname, &st) < 0) {
1342 if (errno == ENOENT) 1334 if (errno == ENOENT)
1343 return 0; 1335 return 0;
1344 perror(fname); 1336 fatal("%s: %s", fname, strerror(errno));
1345 exit(1);
1346 } 1337 }
1347 if ((r = sshkey_load_public(fname, &public, &comment)) != 0) { 1338 if ((r = sshkey_load_public(fname, &public, &comment)) != 0)
1348 printf("Failed to read v2 public key from \"%s\": %s.\n", 1339 fatal("Failed to read v2 public key from \"%s\": %s.",
1349 fname, ssh_err(r)); 1340 fname, ssh_err(r));
1350 exit(1);
1351 }
1352 export_dns_rr(hname, public, stdout, print_generic); 1341 export_dns_rr(hname, public, stdout, print_generic);
1353 sshkey_free(public); 1342 sshkey_free(public);
1354 free(comment); 1343 free(comment);
@@ -1370,18 +1359,15 @@ do_change_comment(struct passwd *pw)
1370 1359
1371 if (!have_identity) 1360 if (!have_identity)
1372 ask_filename(pw, "Enter file in which the key is"); 1361 ask_filename(pw, "Enter file in which the key is");
1373 if (stat(identity_file, &st) < 0) { 1362 if (stat(identity_file, &st) < 0)
1374 perror(identity_file); 1363 fatal("%s: %s", identity_file, strerror(errno));
1375 exit(1);
1376 }
1377 if ((r = sshkey_load_private(identity_file, "", 1364 if ((r = sshkey_load_private(identity_file, "",
1378 &private, &comment)) == 0) 1365 &private, &comment)) == 0)
1379 passphrase = xstrdup(""); 1366 passphrase = xstrdup("");
1380 else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) { 1367 else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
1381 printf("Cannot load private key \"%s\": %s.\n", 1368 fatal("Cannot load private key \"%s\": %s.",
1382 identity_file, ssh_err(r)); 1369 identity_file, ssh_err(r));
1383 exit(1); 1370 else {
1384 } else {
1385 if (identity_passphrase) 1371 if (identity_passphrase)
1386 passphrase = xstrdup(identity_passphrase); 1372 passphrase = xstrdup(identity_passphrase);
1387 else if (identity_new_passphrase) 1373 else if (identity_new_passphrase)
@@ -1394,13 +1380,14 @@ do_change_comment(struct passwd *pw)
1394 &private, &comment)) != 0) { 1380 &private, &comment)) != 0) {
1395 explicit_bzero(passphrase, strlen(passphrase)); 1381 explicit_bzero(passphrase, strlen(passphrase));
1396 free(passphrase); 1382 free(passphrase);
1397 printf("Cannot load private key \"%s\": %s.\n", 1383 fatal("Cannot load private key \"%s\": %s.",
1398 identity_file, ssh_err(r)); 1384 identity_file, ssh_err(r));
1399 exit(1);
1400 } 1385 }
1401 } 1386 }
1387 /* XXX what about new-format keys? */
1402 if (private->type != KEY_RSA1) { 1388 if (private->type != KEY_RSA1) {
1403 fprintf(stderr, "Comments are only supported for RSA1 keys.\n"); 1389 error("Comments are only supported for RSA1 keys.");
1390 explicit_bzero(passphrase, strlen(passphrase));
1404 sshkey_free(private); 1391 sshkey_free(private);
1405 exit(1); 1392 exit(1);
1406 } 1393 }
@@ -1422,7 +1409,7 @@ do_change_comment(struct passwd *pw)
1422 /* Save the file using the new passphrase. */ 1409 /* Save the file using the new passphrase. */
1423 if ((r = sshkey_save_private(private, identity_file, passphrase, 1410 if ((r = sshkey_save_private(private, identity_file, passphrase,
1424 new_comment, use_new_format, new_format_cipher, rounds)) != 0) { 1411 new_comment, use_new_format, new_format_cipher, rounds)) != 0) {
1425 printf("Saving key \"%s\" failed: %s\n", 1412 error("Saving key \"%s\" failed: %s",
1426 identity_file, ssh_err(r)); 1413 identity_file, ssh_err(r));
1427 explicit_bzero(passphrase, strlen(passphrase)); 1414 explicit_bzero(passphrase, strlen(passphrase));
1428 free(passphrase); 1415 free(passphrase);
@@ -1438,17 +1425,13 @@ do_change_comment(struct passwd *pw)
1438 1425
1439 strlcat(identity_file, ".pub", sizeof(identity_file)); 1426 strlcat(identity_file, ".pub", sizeof(identity_file));
1440 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 1427 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1441 if (fd == -1) { 1428 if (fd == -1)
1442 printf("Could not save your public key in %s\n", identity_file); 1429 fatal("Could not save your public key in %s", identity_file);
1443 exit(1);
1444 }
1445 f = fdopen(fd, "w"); 1430 f = fdopen(fd, "w");
1446 if (f == NULL) { 1431 if (f == NULL)
1447 printf("fdopen %s failed\n", identity_file); 1432 fatal("fdopen %s failed: %s", identity_file, strerror(errno));
1448 exit(1);
1449 }
1450 if ((r = sshkey_write(public, f)) != 0) 1433 if ((r = sshkey_write(public, f)) != 0)
1451 fprintf(stderr, "write key failed: %s\n", ssh_err(r)); 1434 fatal("write key failed: %s", ssh_err(r));
1452 sshkey_free(public); 1435 sshkey_free(public);
1453 fprintf(f, " %s\n", new_comment); 1436 fprintf(f, " %s\n", new_comment);
1454 fclose(f); 1437 fclose(f);
@@ -1608,8 +1591,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1608 break; 1591 break;
1609 /* FALLTHROUGH */ 1592 /* FALLTHROUGH */
1610 default: 1593 default:
1611 fprintf(stderr, "unknown key type %s\n", key_type_name); 1594 fatal("unknown key type %s", key_type_name);
1612 exit(1);
1613 } 1595 }
1614 } 1596 }
1615 1597
@@ -1631,7 +1613,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1631 otmp = tmp = xstrdup(cert_principals); 1613 otmp = tmp = xstrdup(cert_principals);
1632 plist = NULL; 1614 plist = NULL;
1633 for (; (cp = strsep(&tmp, ",")) != NULL; n++) { 1615 for (; (cp = strsep(&tmp, ",")) != NULL; n++) {
1634 plist = xrealloc(plist, n + 1, sizeof(*plist)); 1616 plist = xreallocarray(plist, n + 1, sizeof(*plist));
1635 if (*(plist[n] = xstrdup(cp)) == '\0') 1617 if (*(plist[n] = xstrdup(cp)) == '\0')
1636 fatal("Empty principal name"); 1618 fatal("Empty principal name");
1637 } 1619 }
@@ -2216,9 +2198,11 @@ usage(void)
2216 " ssh-keygen -H [-f known_hosts_file]\n" 2198 " ssh-keygen -H [-f known_hosts_file]\n"
2217 " ssh-keygen -R hostname [-f known_hosts_file]\n" 2199 " ssh-keygen -R hostname [-f known_hosts_file]\n"
2218 " ssh-keygen -r hostname [-f input_keyfile] [-g]\n" 2200 " ssh-keygen -r hostname [-f input_keyfile] [-g]\n"
2201#ifdef WITH_OPENSSL
2219 " ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]\n" 2202 " ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]\n"
2220 " ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n" 2203 " ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n"
2221 " [-j start_line] [-K checkpt] [-W generator]\n" 2204 " [-j start_line] [-K checkpt] [-W generator]\n"
2205#endif
2222 " ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals]\n" 2206 " ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals]\n"
2223 " [-O option] [-V validity_interval] [-z serial_number] file ...\n" 2207 " [-O option] [-V validity_interval] [-z serial_number] file ...\n"
2224 " ssh-keygen -L [-f input_keyfile]\n" 2208 " ssh-keygen -L [-f input_keyfile]\n"
@@ -2236,19 +2220,22 @@ int
2236main(int argc, char **argv) 2220main(int argc, char **argv)
2237{ 2221{
2238 char dotsshdir[PATH_MAX], comment[1024], *passphrase1, *passphrase2; 2222 char dotsshdir[PATH_MAX], comment[1024], *passphrase1, *passphrase2;
2239 char *checkpoint = NULL; 2223 char *rr_hostname = NULL, *ep, *fp, *ra;
2240 char out_file[PATH_MAX], *rr_hostname = NULL, *ep, *fp, *ra;
2241 struct sshkey *private, *public; 2224 struct sshkey *private, *public;
2242 struct passwd *pw; 2225 struct passwd *pw;
2243 struct stat st; 2226 struct stat st;
2244 int r, opt, type, fd; 2227 int r, opt, type, fd;
2228 int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
2229 FILE *f;
2230 const char *errstr;
2231#ifdef WITH_OPENSSL
2232 /* Moduli generation/screening */
2233 char out_file[PATH_MAX], *checkpoint = NULL;
2245 u_int32_t memory = 0, generator_wanted = 0; 2234 u_int32_t memory = 0, generator_wanted = 0;
2246 int do_gen_candidates = 0, do_screen_candidates = 0; 2235 int do_gen_candidates = 0, do_screen_candidates = 0;
2247 int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
2248 unsigned long start_lineno = 0, lines_to_process = 0; 2236 unsigned long start_lineno = 0, lines_to_process = 0;
2249 BIGNUM *start = NULL; 2237 BIGNUM *start = NULL;
2250 FILE *f; 2238#endif
2251 const char *errstr;
2252 2239
2253 extern int optind; 2240 extern int optind;
2254 extern char *optarg; 2241 extern char *optarg;
@@ -2267,14 +2254,10 @@ main(int argc, char **argv)
2267 2254
2268 /* we need this for the home * directory. */ 2255 /* we need this for the home * directory. */
2269 pw = getpwuid(getuid()); 2256 pw = getpwuid(getuid());
2270 if (!pw) { 2257 if (!pw)
2271 printf("No user exists for uid %lu\n", (u_long)getuid()); 2258 fatal("No user exists for uid %lu", (u_long)getuid());
2272 exit(1); 2259 if (gethostname(hostname, sizeof(hostname)) < 0)
2273 } 2260 fatal("gethostname: %s", strerror(errno));
2274 if (gethostname(hostname, sizeof(hostname)) < 0) {
2275 perror("gethostname");
2276 exit(1);
2277 }
2278 2261
2279 /* Remaining characters: UYdw */ 2262 /* Remaining characters: UYdw */
2280 while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy" 2263 while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy"
@@ -2305,12 +2288,6 @@ main(int argc, char **argv)
2305 case 'I': 2288 case 'I':
2306 cert_key_id = optarg; 2289 cert_key_id = optarg;
2307 break; 2290 break;
2308 case 'J':
2309 lines_to_process = strtoul(optarg, NULL, 10);
2310 break;
2311 case 'j':
2312 start_lineno = strtoul(optarg, NULL, 10);
2313 break;
2314 case 'R': 2291 case 'R':
2315 delete_host = 1; 2292 delete_host = 1;
2316 rr_hostname = optarg; 2293 rr_hostname = optarg;
@@ -2352,8 +2329,8 @@ main(int argc, char **argv)
2352 change_comment = 1; 2329 change_comment = 1;
2353 break; 2330 break;
2354 case 'f': 2331 case 'f':
2355 if (strlcpy(identity_file, optarg, sizeof(identity_file)) >= 2332 if (strlcpy(identity_file, optarg,
2356 sizeof(identity_file)) 2333 sizeof(identity_file)) >= sizeof(identity_file))
2357 fatal("Identity filename too long"); 2334 fatal("Identity filename too long");
2358 have_identity = 1; 2335 have_identity = 1;
2359 break; 2336 break;
@@ -2425,20 +2402,31 @@ main(int argc, char **argv)
2425 case 'r': 2402 case 'r':
2426 rr_hostname = optarg; 2403 rr_hostname = optarg;
2427 break; 2404 break;
2428 case 'W':
2429 generator_wanted = (u_int32_t)strtonum(optarg, 1,
2430 UINT_MAX, &errstr);
2431 if (errstr)
2432 fatal("Desired generator has bad value: %s (%s)",
2433 optarg, errstr);
2434 break;
2435 case 'a': 2405 case 'a':
2436 rounds = (int)strtonum(optarg, 1, INT_MAX, &errstr); 2406 rounds = (int)strtonum(optarg, 1, INT_MAX, &errstr);
2437 if (errstr) 2407 if (errstr)
2438 fatal("Invalid number: %s (%s)", 2408 fatal("Invalid number: %s (%s)",
2439 optarg, errstr); 2409 optarg, errstr);
2440 break; 2410 break;
2411 case 'V':
2412 parse_cert_times(optarg);
2413 break;
2414 case 'z':
2415 errno = 0;
2416 cert_serial = strtoull(optarg, &ep, 10);
2417 if (*optarg < '0' || *optarg > '9' || *ep != '\0' ||
2418 (errno == ERANGE && cert_serial == ULLONG_MAX))
2419 fatal("Invalid serial number \"%s\"", optarg);
2420 break;
2441#ifdef WITH_OPENSSL 2421#ifdef WITH_OPENSSL
2422 /* Moduli generation/screening */
2423 case 'W':
2424 generator_wanted = (u_int32_t)strtonum(optarg, 1,
2425 UINT_MAX, &errstr);
2426 if (errstr)
2427 fatal("Desired generator has bad value: %s (%s)",
2428 optarg, errstr);
2429 break;
2442 case 'M': 2430 case 'M':
2443 memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); 2431 memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
2444 if (errstr) 2432 if (errstr)
@@ -2467,16 +2455,6 @@ main(int argc, char **argv)
2467 fatal("Invalid start point."); 2455 fatal("Invalid start point.");
2468 break; 2456 break;
2469#endif /* WITH_OPENSSL */ 2457#endif /* WITH_OPENSSL */
2470 case 'V':
2471 parse_cert_times(optarg);
2472 break;
2473 case 'z':
2474 errno = 0;
2475 cert_serial = strtoull(optarg, &ep, 10);
2476 if (*optarg < '0' || *optarg > '9' || *ep != '\0' ||
2477 (errno == ERANGE && cert_serial == ULLONG_MAX))
2478 fatal("Invalid serial number \"%s\"", optarg);
2479 break;
2480 case '?': 2458 case '?':
2481 default: 2459 default:
2482 usage(); 2460 usage();
@@ -2491,19 +2469,19 @@ main(int argc, char **argv)
2491 2469
2492 if (ca_key_path != NULL) { 2470 if (ca_key_path != NULL) {
2493 if (argc < 1 && !gen_krl) { 2471 if (argc < 1 && !gen_krl) {
2494 printf("Too few arguments.\n"); 2472 error("Too few arguments.");
2495 usage(); 2473 usage();
2496 } 2474 }
2497 } else if (argc > 0 && !gen_krl && !check_krl) { 2475 } else if (argc > 0 && !gen_krl && !check_krl) {
2498 printf("Too many arguments.\n"); 2476 error("Too many arguments.");
2499 usage(); 2477 usage();
2500 } 2478 }
2501 if (change_passphrase && change_comment) { 2479 if (change_passphrase && change_comment) {
2502 printf("Can only have one of -p and -c.\n"); 2480 error("Can only have one of -p and -c.");
2503 usage(); 2481 usage();
2504 } 2482 }
2505 if (print_fingerprint && (delete_host || hash_hosts)) { 2483 if (print_fingerprint && (delete_host || hash_hosts)) {
2506 printf("Cannot use -l with -H or -R.\n"); 2484 error("Cannot use -l with -H or -R.");
2507 usage(); 2485 usage();
2508 } 2486 }
2509 if (gen_krl) { 2487 if (gen_krl) {
@@ -2545,10 +2523,8 @@ main(int argc, char **argv)
2545 if (have_identity) { 2523 if (have_identity) {
2546 n = do_print_resource_record(pw, 2524 n = do_print_resource_record(pw,
2547 identity_file, rr_hostname); 2525 identity_file, rr_hostname);
2548 if (n == 0) { 2526 if (n == 0)
2549 perror(identity_file); 2527 fatal("%s: %s", identity_file, strerror(errno));
2550 exit(1);
2551 }
2552 exit(0); 2528 exit(0);
2553 } else { 2529 } else {
2554 2530
@@ -2566,6 +2542,7 @@ main(int argc, char **argv)
2566 } 2542 }
2567 } 2543 }
2568 2544
2545#ifdef WITH_OPENSSL
2569 if (do_gen_candidates) { 2546 if (do_gen_candidates) {
2570 FILE *out = fopen(out_file, "w"); 2547 FILE *out = fopen(out_file, "w");
2571 2548
@@ -2605,6 +2582,7 @@ main(int argc, char **argv)
2605 fatal("modulus screening failed"); 2582 fatal("modulus screening failed");
2606 return (0); 2583 return (0);
2607 } 2584 }
2585#endif
2608 2586
2609 if (gen_all_hostkeys) { 2587 if (gen_all_hostkeys) {
2610 do_gen_all_hostkeys(pw); 2588 do_gen_all_hostkeys(pw);
@@ -2612,7 +2590,7 @@ main(int argc, char **argv)
2612 } 2590 }
2613 2591
2614 if (key_type_name == NULL) 2592 if (key_type_name == NULL)
2615 key_type_name = "rsa"; 2593 key_type_name = DEFAULT_KEY_TYPE_NAME;
2616 2594
2617 type = sshkey_type_from_name(key_type_name); 2595 type = sshkey_type_from_name(key_type_name);
2618 type_bits_valid(type, key_type_name, &bits); 2596 type_bits_valid(type, key_type_name, &bits);
@@ -2620,14 +2598,10 @@ main(int argc, char **argv)
2620 if (!quiet) 2598 if (!quiet)
2621 printf("Generating public/private %s key pair.\n", 2599 printf("Generating public/private %s key pair.\n",
2622 key_type_name); 2600 key_type_name);
2623 if ((r = sshkey_generate(type, bits, &private)) != 0) { 2601 if ((r = sshkey_generate(type, bits, &private)) != 0)
2624 fprintf(stderr, "key_generate failed\n"); 2602 fatal("key_generate failed");
2625 exit(1); 2603 if ((r = sshkey_from_private(private, &public)) != 0)
2626 } 2604 fatal("key_from_private failed: %s\n", ssh_err(r));
2627 if ((r = sshkey_from_private(private, &public)) != 0) {
2628 fprintf(stderr, "key_from_private failed: %s\n", ssh_err(r));
2629 exit(1);
2630 }
2631 2605
2632 if (!have_identity) 2606 if (!have_identity)
2633 ask_filename(pw, "Enter file in which to save the key"); 2607 ask_filename(pw, "Enter file in which to save the key");
@@ -2697,7 +2671,7 @@ passphrase_again:
2697 /* Save the key with the given passphrase and comment. */ 2671 /* Save the key with the given passphrase and comment. */
2698 if ((r = sshkey_save_private(private, identity_file, passphrase1, 2672 if ((r = sshkey_save_private(private, identity_file, passphrase1,
2699 comment, use_new_format, new_format_cipher, rounds)) != 0) { 2673 comment, use_new_format, new_format_cipher, rounds)) != 0) {
2700 printf("Saving key \"%s\" failed: %s\n", 2674 error("Saving key \"%s\" failed: %s",
2701 identity_file, ssh_err(r)); 2675 identity_file, ssh_err(r));
2702 explicit_bzero(passphrase1, strlen(passphrase1)); 2676 explicit_bzero(passphrase1, strlen(passphrase1));
2703 free(passphrase1); 2677 free(passphrase1);
@@ -2714,18 +2688,13 @@ passphrase_again:
2714 printf("Your identification has been saved in %s.\n", identity_file); 2688 printf("Your identification has been saved in %s.\n", identity_file);
2715 2689
2716 strlcat(identity_file, ".pub", sizeof(identity_file)); 2690 strlcat(identity_file, ".pub", sizeof(identity_file));
2717 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 2691 if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
2718 if (fd == -1) { 2692 fatal("Unable to save public key to %s: %s",
2719 printf("Could not save your public key in %s\n", identity_file); 2693 identity_file, strerror(errno));
2720 exit(1); 2694 if ((f = fdopen(fd, "w")) == NULL)
2721 } 2695 fatal("fdopen %s failed: %s", identity_file, strerror(errno));
2722 f = fdopen(fd, "w");
2723 if (f == NULL) {
2724 printf("fdopen %s failed\n", identity_file);
2725 exit(1);
2726 }
2727 if ((r = sshkey_write(public, f)) != 0) 2696 if ((r = sshkey_write(public, f)) != 0)
2728 fprintf(stderr, "write key failed: %s\n", ssh_err(r)); 2697 error("write key failed: %s", ssh_err(r));
2729 fprintf(f, " %s\n", comment); 2698 fprintf(f, " %s\n", comment);
2730 fclose(f); 2699 fclose(f);
2731 2700