summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c1157
1 files changed, 595 insertions, 562 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 23058ee99..a3c2362a2 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.249 2014/07/03 03:47:27 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.266 2015/02/26 20:45:47 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
@@ -17,11 +17,12 @@
17#include <sys/types.h> 17#include <sys/types.h>
18#include <sys/socket.h> 18#include <sys/socket.h>
19#include <sys/stat.h> 19#include <sys/stat.h>
20#include <sys/param.h>
21 20
21#ifdef WITH_OPENSSL
22#include <openssl/evp.h> 22#include <openssl/evp.h>
23#include <openssl/pem.h> 23#include <openssl/pem.h>
24#include "openbsd-compat/openssl-compat.h" 24#include "openbsd-compat/openssl-compat.h"
25#endif
25 26
26#include <errno.h> 27#include <errno.h>
27#include <fcntl.h> 28#include <fcntl.h>
@@ -35,13 +36,14 @@
35#include <stdlib.h> 36#include <stdlib.h>
36#include <string.h> 37#include <string.h>
37#include <unistd.h> 38#include <unistd.h>
39#include <limits.h>
38 40
39#include "xmalloc.h" 41#include "xmalloc.h"
40#include "key.h" 42#include "sshkey.h"
41#include "rsa.h" 43#include "rsa.h"
42#include "authfile.h" 44#include "authfile.h"
43#include "uuencode.h" 45#include "uuencode.h"
44#include "buffer.h" 46#include "sshbuf.h"
45#include "pathnames.h" 47#include "pathnames.h"
46#include "log.h" 48#include "log.h"
47#include "misc.h" 49#include "misc.h"
@@ -50,9 +52,11 @@
50#include "dns.h" 52#include "dns.h"
51#include "ssh.h" 53#include "ssh.h"
52#include "ssh2.h" 54#include "ssh2.h"
55#include "ssherr.h"
53#include "ssh-pkcs11.h" 56#include "ssh-pkcs11.h"
54#include "atomicio.h" 57#include "atomicio.h"
55#include "krl.h" 58#include "krl.h"
59#include "digest.h"
56 60
57/* Number of bits in the RSA/DSA key. This value can be set on the command line. */ 61/* Number of bits in the RSA/DSA key. This value can be set on the command line. */
58#define DEFAULT_BITS 2048 62#define DEFAULT_BITS 2048
@@ -90,6 +94,9 @@ int show_cert = 0;
90int print_fingerprint = 0; 94int print_fingerprint = 0;
91int print_bubblebabble = 0; 95int print_bubblebabble = 0;
92 96
97/* Hash algorithm to use for fingerprints. */
98int fingerprint_hash = SSH_FP_HASH_DEFAULT;
99
93/* The identity file name, given on the command line or entered by the user. */ 100/* The identity file name, given on the command line or entered by the user. */
94char identity_file[1024]; 101char identity_file[1024];
95int have_identity = 0; 102int have_identity = 0;
@@ -173,34 +180,43 @@ int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long,
173 unsigned long); 180 unsigned long);
174 181
175static void 182static void
176type_bits_valid(int type, u_int32_t *bitsp) 183type_bits_valid(int type, const char *name, u_int32_t *bitsp)
177{ 184{
185#ifdef WITH_OPENSSL
178 u_int maxbits; 186 u_int maxbits;
187 int nid;
188#endif
179 189
180 if (type == KEY_UNSPEC) { 190 if (type == KEY_UNSPEC) {
181 fprintf(stderr, "unknown key type %s\n", key_type_name); 191 fprintf(stderr, "unknown key type %s\n", key_type_name);
182 exit(1); 192 exit(1);
183 } 193 }
184 if (*bitsp == 0) { 194 if (*bitsp == 0) {
195#ifdef WITH_OPENSSL
185 if (type == KEY_DSA) 196 if (type == KEY_DSA)
186 *bitsp = DEFAULT_BITS_DSA; 197 *bitsp = DEFAULT_BITS_DSA;
187 else if (type == KEY_ECDSA) 198 else if (type == KEY_ECDSA) {
188 *bitsp = DEFAULT_BITS_ECDSA; 199 if (name != NULL &&
189 else 200 (nid = sshkey_ecdsa_nid_from_name(name)) > 0)
201 *bitsp = sshkey_curve_nid_to_bits(nid);
202 if (*bitsp == 0)
203 *bitsp = DEFAULT_BITS_ECDSA;
204 } else
205#endif
190 *bitsp = DEFAULT_BITS; 206 *bitsp = DEFAULT_BITS;
191 } 207 }
208#ifdef WITH_OPENSSL
192 maxbits = (type == KEY_DSA) ? 209 maxbits = (type == KEY_DSA) ?
193 OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; 210 OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS;
194 if (*bitsp > maxbits) { 211 if (*bitsp > maxbits) {
195 fprintf(stderr, "key bits exceeds maximum %d\n", maxbits); 212 fprintf(stderr, "key bits exceeds maximum %d\n", maxbits);
196 exit(1); 213 exit(1);
197 } 214 }
198#ifdef WITH_OPENSSL
199 if (type == KEY_DSA && *bitsp != 1024) 215 if (type == KEY_DSA && *bitsp != 1024)
200 fatal("DSA keys must be 1024 bits"); 216 fatal("DSA keys must be 1024 bits");
201 else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768) 217 else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768)
202 fatal("Key must at least be 768 bits"); 218 fatal("Key must at least be 768 bits");
203 else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(*bitsp) == -1) 219 else if (type == KEY_ECDSA && sshkey_ecdsa_bits_to_nid(*bitsp) == -1)
204 fatal("Invalid ECDSA key length - valid lengths are " 220 fatal("Invalid ECDSA key length - valid lengths are "
205 "256, 384 or 521 bits"); 221 "256, 384 or 521 bits");
206#endif 222#endif
@@ -215,7 +231,7 @@ ask_filename(struct passwd *pw, const char *prompt)
215 if (key_type_name == NULL) 231 if (key_type_name == NULL)
216 name = _PATH_SSH_CLIENT_ID_RSA; 232 name = _PATH_SSH_CLIENT_ID_RSA;
217 else { 233 else {
218 switch (key_type_from_name(key_type_name)) { 234 switch (sshkey_type_from_name(key_type_name)) {
219 case KEY_RSA1: 235 case KEY_RSA1:
220 name = _PATH_SSH_CLIENT_IDENTITY; 236 name = _PATH_SSH_CLIENT_IDENTITY;
221 break; 237 break;
@@ -255,23 +271,26 @@ ask_filename(struct passwd *pw, const char *prompt)
255 have_identity = 1; 271 have_identity = 1;
256} 272}
257 273
258static Key * 274static struct sshkey *
259load_identity(char *filename) 275load_identity(char *filename)
260{ 276{
261 char *pass; 277 char *pass;
262 Key *prv; 278 struct sshkey *prv;
279 int r;
263 280
264 prv = key_load_private(filename, "", NULL); 281 if ((r = sshkey_load_private(filename, "", &prv, NULL)) == 0)
265 if (prv == NULL) { 282 return prv;
266 if (identity_passphrase) 283 if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
267 pass = xstrdup(identity_passphrase); 284 fatal("Load key \"%s\": %s", filename, ssh_err(r));
268 else 285 if (identity_passphrase)
269 pass = read_passphrase("Enter passphrase: ", 286 pass = xstrdup(identity_passphrase);
270 RP_ALLOW_STDIN); 287 else
271 prv = key_load_private(filename, pass, NULL); 288 pass = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN);
272 explicit_bzero(pass, strlen(pass)); 289 r = sshkey_load_private(filename, pass, &prv, NULL);
273 free(pass); 290 explicit_bzero(pass, strlen(pass));
274 } 291 free(pass);
292 if (r != 0)
293 fatal("Load key \"%s\": %s", filename, ssh_err(r));
275 return prv; 294 return prv;
276} 295}
277 296
@@ -282,39 +301,40 @@ load_identity(char *filename)
282 301
283#ifdef WITH_OPENSSL 302#ifdef WITH_OPENSSL
284static void 303static void
285do_convert_to_ssh2(struct passwd *pw, Key *k) 304do_convert_to_ssh2(struct passwd *pw, struct sshkey *k)
286{ 305{
287 u_int len; 306 size_t len;
288 u_char *blob; 307 u_char *blob;
289 char comment[61]; 308 char comment[61];
309 int r;
290 310
291 if (k->type == KEY_RSA1) { 311 if (k->type == KEY_RSA1) {
292 fprintf(stderr, "version 1 keys are not supported\n"); 312 fprintf(stderr, "version 1 keys are not supported\n");
293 exit(1); 313 exit(1);
294 } 314 }
295 if (key_to_blob(k, &blob, &len) <= 0) { 315 if ((r = sshkey_to_blob(k, &blob, &len)) != 0) {
296 fprintf(stderr, "key_to_blob failed\n"); 316 fprintf(stderr, "key_to_blob failed: %s\n", ssh_err(r));
297 exit(1); 317 exit(1);
298 } 318 }
299 /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ 319 /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
300 snprintf(comment, sizeof(comment), 320 snprintf(comment, sizeof(comment),
301 "%u-bit %s, converted by %s@%s from OpenSSH", 321 "%u-bit %s, converted by %s@%s from OpenSSH",
302 key_size(k), key_type(k), 322 sshkey_size(k), sshkey_type(k),
303 pw->pw_name, hostname); 323 pw->pw_name, hostname);
304 324
305 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); 325 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
306 fprintf(stdout, "Comment: \"%s\"\n", comment); 326 fprintf(stdout, "Comment: \"%s\"\n", comment);
307 dump_base64(stdout, blob, len); 327 dump_base64(stdout, blob, len);
308 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); 328 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
309 key_free(k); 329 sshkey_free(k);
310 free(blob); 330 free(blob);
311 exit(0); 331 exit(0);
312} 332}
313 333
314static void 334static void
315do_convert_to_pkcs8(Key *k) 335do_convert_to_pkcs8(struct sshkey *k)
316{ 336{
317 switch (key_type_plain(k->type)) { 337 switch (sshkey_type_plain(k->type)) {
318 case KEY_RSA1: 338 case KEY_RSA1:
319 case KEY_RSA: 339 case KEY_RSA:
320 if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) 340 if (!PEM_write_RSA_PUBKEY(stdout, k->rsa))
@@ -331,15 +351,15 @@ do_convert_to_pkcs8(Key *k)
331 break; 351 break;
332#endif 352#endif
333 default: 353 default:
334 fatal("%s: unsupported key type %s", __func__, key_type(k)); 354 fatal("%s: unsupported key type %s", __func__, sshkey_type(k));
335 } 355 }
336 exit(0); 356 exit(0);
337} 357}
338 358
339static void 359static void
340do_convert_to_pem(Key *k) 360do_convert_to_pem(struct sshkey *k)
341{ 361{
342 switch (key_type_plain(k->type)) { 362 switch (sshkey_type_plain(k->type)) {
343 case KEY_RSA1: 363 case KEY_RSA1:
344 case KEY_RSA: 364 case KEY_RSA:
345 if (!PEM_write_RSAPublicKey(stdout, k->rsa)) 365 if (!PEM_write_RSAPublicKey(stdout, k->rsa))
@@ -353,7 +373,7 @@ do_convert_to_pem(Key *k)
353#endif 373#endif
354 /* XXX ECDSA? */ 374 /* XXX ECDSA? */
355 default: 375 default:
356 fatal("%s: unsupported key type %s", __func__, key_type(k)); 376 fatal("%s: unsupported key type %s", __func__, sshkey_type(k));
357 } 377 }
358 exit(0); 378 exit(0);
359} 379}
@@ -361,20 +381,16 @@ do_convert_to_pem(Key *k)
361static void 381static void
362do_convert_to(struct passwd *pw) 382do_convert_to(struct passwd *pw)
363{ 383{
364 Key *k; 384 struct sshkey *k;
365 struct stat st; 385 struct stat st;
386 int r;
366 387
367 if (!have_identity) 388 if (!have_identity)
368 ask_filename(pw, "Enter file in which the key is"); 389 ask_filename(pw, "Enter file in which the key is");
369 if (stat(identity_file, &st) < 0) 390 if (stat(identity_file, &st) < 0)
370 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 391 fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
371 if ((k = key_load_public(identity_file, NULL)) == NULL) { 392 if ((r = sshkey_load_public(identity_file, &k, NULL)) != 0)
372 if ((k = load_identity(identity_file)) == NULL) { 393 k = load_identity(identity_file);
373 fprintf(stderr, "load failed\n");
374 exit(1);
375 }
376 }
377
378 switch (convert_format) { 394 switch (convert_format) {
379 case FMT_RFC4716: 395 case FMT_RFC4716:
380 do_convert_to_ssh2(pw, k); 396 do_convert_to_ssh2(pw, k);
@@ -391,51 +407,63 @@ do_convert_to(struct passwd *pw)
391 exit(0); 407 exit(0);
392} 408}
393 409
410/*
411 * This is almost exactly the bignum1 encoding, but with 32 bit for length
412 * instead of 16.
413 */
394static void 414static void
395buffer_get_bignum_bits(Buffer *b, BIGNUM *value) 415buffer_get_bignum_bits(struct sshbuf *b, BIGNUM *value)
396{ 416{
397 u_int bignum_bits = buffer_get_int(b); 417 u_int bytes, bignum_bits;
398 u_int bytes = (bignum_bits + 7) / 8; 418 int r;
399 419
400 if (buffer_len(b) < bytes) 420 if ((r = sshbuf_get_u32(b, &bignum_bits)) != 0)
401 fatal("buffer_get_bignum_bits: input buffer too small: " 421 fatal("%s: buffer error: %s", __func__, ssh_err(r));
402 "need %d have %d", bytes, buffer_len(b)); 422 bytes = (bignum_bits + 7) / 8;
403 if (BN_bin2bn(buffer_ptr(b), bytes, value) == NULL) 423 if (sshbuf_len(b) < bytes)
404 fatal("buffer_get_bignum_bits: BN_bin2bn failed"); 424 fatal("%s: input buffer too small: need %d have %zu",
405 buffer_consume(b, bytes); 425 __func__, bytes, sshbuf_len(b));
426 if (BN_bin2bn(sshbuf_ptr(b), bytes, value) == NULL)
427 fatal("%s: BN_bin2bn failed", __func__);
428 if ((r = sshbuf_consume(b, bytes)) != 0)
429 fatal("%s: buffer error: %s", __func__, ssh_err(r));
406} 430}
407 431
408static Key * 432static struct sshkey *
409do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) 433do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
410{ 434{
411 Buffer b; 435 struct sshbuf *b;
412 Key *key = NULL; 436 struct sshkey *key = NULL;
413 char *type, *cipher; 437 char *type, *cipher;
414 u_char *sig = NULL, data[] = "abcde12345"; 438 u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345";
415 int magic, rlen, ktype, i1, i2, i3, i4; 439 int r, rlen, ktype;
416 u_int slen; 440 u_int magic, i1, i2, i3, i4;
441 size_t slen;
417 u_long e; 442 u_long e;
418 443
419 buffer_init(&b); 444 if ((b = sshbuf_from(blob, blen)) == NULL)
420 buffer_append(&b, blob, blen); 445 fatal("%s: sshbuf_from failed", __func__);
446 if ((r = sshbuf_get_u32(b, &magic)) != 0)
447 fatal("%s: buffer error: %s", __func__, ssh_err(r));
421 448
422 magic = buffer_get_int(&b);
423 if (magic != SSH_COM_PRIVATE_KEY_MAGIC) { 449 if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {
424 error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC); 450 error("bad magic 0x%x != 0x%x", magic,
425 buffer_free(&b); 451 SSH_COM_PRIVATE_KEY_MAGIC);
452 sshbuf_free(b);
426 return NULL; 453 return NULL;
427 } 454 }
428 i1 = buffer_get_int(&b); 455 if ((r = sshbuf_get_u32(b, &i1)) != 0 ||
429 type = buffer_get_string(&b, NULL); 456 (r = sshbuf_get_cstring(b, &type, NULL)) != 0 ||
430 cipher = buffer_get_string(&b, NULL); 457 (r = sshbuf_get_cstring(b, &cipher, NULL)) != 0 ||
431 i2 = buffer_get_int(&b); 458 (r = sshbuf_get_u32(b, &i2)) != 0 ||
432 i3 = buffer_get_int(&b); 459 (r = sshbuf_get_u32(b, &i3)) != 0 ||
433 i4 = buffer_get_int(&b); 460 (r = sshbuf_get_u32(b, &i4)) != 0)
461 fatal("%s: buffer error: %s", __func__, ssh_err(r));
434 debug("ignore (%d %d %d %d)", i1, i2, i3, i4); 462 debug("ignore (%d %d %d %d)", i1, i2, i3, i4);
435 if (strcmp(cipher, "none") != 0) { 463 if (strcmp(cipher, "none") != 0) {
436 error("unsupported cipher %s", cipher); 464 error("unsupported cipher %s", cipher);
437 free(cipher); 465 free(cipher);
438 buffer_free(&b); 466 sshbuf_free(b);
439 free(type); 467 free(type);
440 return NULL; 468 return NULL;
441 } 469 }
@@ -446,56 +474,64 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
446 } else if (strstr(type, "rsa")) { 474 } else if (strstr(type, "rsa")) {
447 ktype = KEY_RSA; 475 ktype = KEY_RSA;
448 } else { 476 } else {
449 buffer_free(&b); 477 sshbuf_free(b);
450 free(type); 478 free(type);
451 return NULL; 479 return NULL;
452 } 480 }
453 key = key_new_private(ktype); 481 if ((key = sshkey_new_private(ktype)) == NULL)
482 fatal("key_new_private failed");
454 free(type); 483 free(type);
455 484
456 switch (key->type) { 485 switch (key->type) {
457 case KEY_DSA: 486 case KEY_DSA:
458 buffer_get_bignum_bits(&b, key->dsa->p); 487 buffer_get_bignum_bits(b, key->dsa->p);
459 buffer_get_bignum_bits(&b, key->dsa->g); 488 buffer_get_bignum_bits(b, key->dsa->g);
460 buffer_get_bignum_bits(&b, key->dsa->q); 489 buffer_get_bignum_bits(b, key->dsa->q);
461 buffer_get_bignum_bits(&b, key->dsa->pub_key); 490 buffer_get_bignum_bits(b, key->dsa->pub_key);
462 buffer_get_bignum_bits(&b, key->dsa->priv_key); 491 buffer_get_bignum_bits(b, key->dsa->priv_key);
463 break; 492 break;
464 case KEY_RSA: 493 case KEY_RSA:
465 e = buffer_get_char(&b); 494 if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
495 (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) ||
496 (e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0))
497 fatal("%s: buffer error: %s", __func__, ssh_err(r));
498 e = e1;
466 debug("e %lx", e); 499 debug("e %lx", e);
467 if (e < 30) { 500 if (e < 30) {
468 e <<= 8; 501 e <<= 8;
469 e += buffer_get_char(&b); 502 e += e2;
470 debug("e %lx", e); 503 debug("e %lx", e);
471 e <<= 8; 504 e <<= 8;
472 e += buffer_get_char(&b); 505 e += e3;
473 debug("e %lx", e); 506 debug("e %lx", e);
474 } 507 }
475 if (!BN_set_word(key->rsa->e, e)) { 508 if (!BN_set_word(key->rsa->e, e)) {
476 buffer_free(&b); 509 sshbuf_free(b);
477 key_free(key); 510 sshkey_free(key);
478 return NULL; 511 return NULL;
479 } 512 }
480 buffer_get_bignum_bits(&b, key->rsa->d); 513 buffer_get_bignum_bits(b, key->rsa->d);
481 buffer_get_bignum_bits(&b, key->rsa->n); 514 buffer_get_bignum_bits(b, key->rsa->n);
482 buffer_get_bignum_bits(&b, key->rsa->iqmp); 515 buffer_get_bignum_bits(b, key->rsa->iqmp);
483 buffer_get_bignum_bits(&b, key->rsa->q); 516 buffer_get_bignum_bits(b, key->rsa->q);
484 buffer_get_bignum_bits(&b, key->rsa->p); 517 buffer_get_bignum_bits(b, key->rsa->p);
485 if (rsa_generate_additional_parameters(key->rsa) != 0) 518 if ((r = rsa_generate_additional_parameters(key->rsa)) != 0)
486 fatal("%s: rsa_generate_additional_parameters " 519 fatal("generate RSA parameters failed: %s", ssh_err(r));
487 "error", __func__);
488 break; 520 break;
489 } 521 }
490 rlen = buffer_len(&b); 522 rlen = sshbuf_len(b);
491 if (rlen != 0) 523 if (rlen != 0)
492 error("do_convert_private_ssh2_from_blob: " 524 error("do_convert_private_ssh2_from_blob: "
493 "remaining bytes in key blob %d", rlen); 525 "remaining bytes in key blob %d", rlen);
494 buffer_free(&b); 526 sshbuf_free(b);
495 527
496 /* try the key */ 528 /* try the key */
497 key_sign(key, &sig, &slen, data, sizeof(data)); 529 if (sshkey_sign(key, &sig, &slen, data, sizeof(data), 0) != 0 ||
498 key_verify(key, sig, slen, data, sizeof(data)); 530 sshkey_verify(key, sig, slen, data, sizeof(data), 0) != 0) {
531 sshkey_free(key);
532 free(sig);
533 return NULL;
534 }
499 free(sig); 535 free(sig);
500 return key; 536 return key;
501} 537}
@@ -531,14 +567,13 @@ get_line(FILE *fp, char *line, size_t len)
531} 567}
532 568
533static void 569static void
534do_convert_from_ssh2(struct passwd *pw, Key **k, int *private) 570do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private)
535{ 571{
536 int blen; 572 int r, blen, escaped = 0;
537 u_int len; 573 u_int len;
538 char line[1024]; 574 char line[1024];
539 u_char blob[8096]; 575 u_char blob[8096];
540 char encoded[8096]; 576 char encoded[8096];
541 int escaped = 0;
542 FILE *fp; 577 FILE *fp;
543 578
544 if ((fp = fopen(identity_file, "r")) == NULL) 579 if ((fp = fopen(identity_file, "r")) == NULL)
@@ -575,18 +610,17 @@ do_convert_from_ssh2(struct passwd *pw, Key **k, int *private)
575 fprintf(stderr, "uudecode failed.\n"); 610 fprintf(stderr, "uudecode failed.\n");
576 exit(1); 611 exit(1);
577 } 612 }
578 *k = *private ? 613 if (*private)
579 do_convert_private_ssh2_from_blob(blob, blen) : 614 *k = do_convert_private_ssh2_from_blob(blob, blen);
580 key_from_blob(blob, blen); 615 else if ((r = sshkey_from_blob(blob, blen, k)) != 0) {
581 if (*k == NULL) { 616 fprintf(stderr, "decode blob failed: %s\n", ssh_err(r));
582 fprintf(stderr, "decode blob failed.\n");
583 exit(1); 617 exit(1);
584 } 618 }
585 fclose(fp); 619 fclose(fp);
586} 620}
587 621
588static void 622static void
589do_convert_from_pkcs8(Key **k, int *private) 623do_convert_from_pkcs8(struct sshkey **k, int *private)
590{ 624{
591 EVP_PKEY *pubkey; 625 EVP_PKEY *pubkey;
592 FILE *fp; 626 FILE *fp;
@@ -600,21 +634,24 @@ do_convert_from_pkcs8(Key **k, int *private)
600 fclose(fp); 634 fclose(fp);
601 switch (EVP_PKEY_type(pubkey->type)) { 635 switch (EVP_PKEY_type(pubkey->type)) {
602 case EVP_PKEY_RSA: 636 case EVP_PKEY_RSA:
603 *k = key_new(KEY_UNSPEC); 637 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
638 fatal("sshkey_new failed");
604 (*k)->type = KEY_RSA; 639 (*k)->type = KEY_RSA;
605 (*k)->rsa = EVP_PKEY_get1_RSA(pubkey); 640 (*k)->rsa = EVP_PKEY_get1_RSA(pubkey);
606 break; 641 break;
607 case EVP_PKEY_DSA: 642 case EVP_PKEY_DSA:
608 *k = key_new(KEY_UNSPEC); 643 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
644 fatal("sshkey_new failed");
609 (*k)->type = KEY_DSA; 645 (*k)->type = KEY_DSA;
610 (*k)->dsa = EVP_PKEY_get1_DSA(pubkey); 646 (*k)->dsa = EVP_PKEY_get1_DSA(pubkey);
611 break; 647 break;
612#ifdef OPENSSL_HAS_ECC 648#ifdef OPENSSL_HAS_ECC
613 case EVP_PKEY_EC: 649 case EVP_PKEY_EC:
614 *k = key_new(KEY_UNSPEC); 650 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
651 fatal("sshkey_new failed");
615 (*k)->type = KEY_ECDSA; 652 (*k)->type = KEY_ECDSA;
616 (*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey); 653 (*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey);
617 (*k)->ecdsa_nid = key_ecdsa_key_to_nid((*k)->ecdsa); 654 (*k)->ecdsa_nid = sshkey_ecdsa_key_to_nid((*k)->ecdsa);
618 break; 655 break;
619#endif 656#endif
620 default: 657 default:
@@ -626,7 +663,7 @@ do_convert_from_pkcs8(Key **k, int *private)
626} 663}
627 664
628static void 665static void
629do_convert_from_pem(Key **k, int *private) 666do_convert_from_pem(struct sshkey **k, int *private)
630{ 667{
631 FILE *fp; 668 FILE *fp;
632 RSA *rsa; 669 RSA *rsa;
@@ -637,7 +674,8 @@ do_convert_from_pem(Key **k, int *private)
637 if ((fp = fopen(identity_file, "r")) == NULL) 674 if ((fp = fopen(identity_file, "r")) == NULL)
638 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 675 fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
639 if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { 676 if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) {
640 *k = key_new(KEY_UNSPEC); 677 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
678 fatal("sshkey_new failed");
641 (*k)->type = KEY_RSA; 679 (*k)->type = KEY_RSA;
642 (*k)->rsa = rsa; 680 (*k)->rsa = rsa;
643 fclose(fp); 681 fclose(fp);
@@ -646,7 +684,8 @@ do_convert_from_pem(Key **k, int *private)
646#if notyet /* OpenSSH 0.9.8 lacks this function */ 684#if notyet /* OpenSSH 0.9.8 lacks this function */
647 rewind(fp); 685 rewind(fp);
648 if ((dsa = PEM_read_DSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { 686 if ((dsa = PEM_read_DSAPublicKey(fp, NULL, NULL, NULL)) != NULL) {
649 *k = key_new(KEY_UNSPEC); 687 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
688 fatal("sshkey_new failed");
650 (*k)->type = KEY_DSA; 689 (*k)->type = KEY_DSA;
651 (*k)->dsa = dsa; 690 (*k)->dsa = dsa;
652 fclose(fp); 691 fclose(fp);
@@ -660,8 +699,8 @@ do_convert_from_pem(Key **k, int *private)
660static void 699static void
661do_convert_from(struct passwd *pw) 700do_convert_from(struct passwd *pw)
662{ 701{
663 Key *k = NULL; 702 struct sshkey *k = NULL;
664 int private = 0, ok = 0; 703 int r, private = 0, ok = 0;
665 struct stat st; 704 struct stat st;
666 705
667 if (!have_identity) 706 if (!have_identity)
@@ -683,11 +722,12 @@ do_convert_from(struct passwd *pw)
683 fatal("%s: unknown key format %d", __func__, convert_format); 722 fatal("%s: unknown key format %d", __func__, convert_format);
684 } 723 }
685 724
686 if (!private) 725 if (!private) {
687 ok = key_write(k, stdout); 726 if ((r = sshkey_write(k, stdout)) == 0)
727 ok = 1;
688 if (ok) 728 if (ok)
689 fprintf(stdout, "\n"); 729 fprintf(stdout, "\n");
690 else { 730 } else {
691 switch (k->type) { 731 switch (k->type) {
692 case KEY_DSA: 732 case KEY_DSA:
693 ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, 733 ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL,
@@ -705,7 +745,7 @@ do_convert_from(struct passwd *pw)
705 break; 745 break;
706 default: 746 default:
707 fatal("%s: unsupported key type %s", __func__, 747 fatal("%s: unsupported key type %s", __func__,
708 key_type(k)); 748 sshkey_type(k));
709 } 749 }
710 } 750 }
711 751
@@ -713,7 +753,7 @@ do_convert_from(struct passwd *pw)
713 fprintf(stderr, "key write failed\n"); 753 fprintf(stderr, "key write failed\n");
714 exit(1); 754 exit(1);
715 } 755 }
716 key_free(k); 756 sshkey_free(k);
717 exit(0); 757 exit(0);
718} 758}
719#endif 759#endif
@@ -721,8 +761,9 @@ do_convert_from(struct passwd *pw)
721static void 761static void
722do_print_public(struct passwd *pw) 762do_print_public(struct passwd *pw)
723{ 763{
724 Key *prv; 764 struct sshkey *prv;
725 struct stat st; 765 struct stat st;
766 int r;
726 767
727 if (!have_identity) 768 if (!have_identity)
728 ask_filename(pw, "Enter file in which the key is"); 769 ask_filename(pw, "Enter file in which the key is");
@@ -731,13 +772,9 @@ do_print_public(struct passwd *pw)
731 exit(1); 772 exit(1);
732 } 773 }
733 prv = load_identity(identity_file); 774 prv = load_identity(identity_file);
734 if (prv == NULL) { 775 if ((r = sshkey_write(prv, stdout)) != 0)
735 fprintf(stderr, "load failed\n"); 776 fprintf(stderr, "key_write failed: %s", ssh_err(r));
736 exit(1); 777 sshkey_free(prv);
737 }
738 if (!key_write(prv, stdout))
739 fprintf(stderr, "key_write failed");
740 key_free(prv);
741 fprintf(stdout, "\n"); 778 fprintf(stdout, "\n");
742 exit(0); 779 exit(0);
743} 780}
@@ -746,14 +783,14 @@ static void
746do_download(struct passwd *pw) 783do_download(struct passwd *pw)
747{ 784{
748#ifdef ENABLE_PKCS11 785#ifdef ENABLE_PKCS11
749 Key **keys = NULL; 786 struct sshkey **keys = NULL;
750 int i, nkeys; 787 int i, nkeys;
751 enum fp_rep rep; 788 enum sshkey_fp_rep rep;
752 enum fp_type fptype; 789 int fptype;
753 char *fp, *ra; 790 char *fp, *ra;
754 791
755 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; 792 fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
756 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; 793 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
757 794
758 pkcs11_init(0); 795 pkcs11_init(0);
759 nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); 796 nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys);
@@ -761,20 +798,22 @@ do_download(struct passwd *pw)
761 fatal("cannot read public key from pkcs11"); 798 fatal("cannot read public key from pkcs11");
762 for (i = 0; i < nkeys; i++) { 799 for (i = 0; i < nkeys; i++) {
763 if (print_fingerprint) { 800 if (print_fingerprint) {
764 fp = key_fingerprint(keys[i], fptype, rep); 801 fp = sshkey_fingerprint(keys[i], fptype, rep);
765 ra = key_fingerprint(keys[i], SSH_FP_MD5, 802 ra = sshkey_fingerprint(keys[i], fingerprint_hash,
766 SSH_FP_RANDOMART); 803 SSH_FP_RANDOMART);
767 printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), 804 if (fp == NULL || ra == NULL)
768 fp, key_type(keys[i])); 805 fatal("%s: sshkey_fingerprint fail", __func__);
806 printf("%u %s %s (PKCS11 key)\n", sshkey_size(keys[i]),
807 fp, sshkey_type(keys[i]));
769 if (log_level >= SYSLOG_LEVEL_VERBOSE) 808 if (log_level >= SYSLOG_LEVEL_VERBOSE)
770 printf("%s\n", ra); 809 printf("%s\n", ra);
771 free(ra); 810 free(ra);
772 free(fp); 811 free(fp);
773 } else { 812 } else {
774 key_write(keys[i], stdout); 813 (void) sshkey_write(keys[i], stdout); /* XXX check */
775 fprintf(stdout, "\n"); 814 fprintf(stdout, "\n");
776 } 815 }
777 key_free(keys[i]); 816 sshkey_free(keys[i]);
778 } 817 }
779 free(keys); 818 free(keys);
780 pkcs11_terminate(); 819 pkcs11_terminate();
@@ -788,31 +827,35 @@ static void
788do_fingerprint(struct passwd *pw) 827do_fingerprint(struct passwd *pw)
789{ 828{
790 FILE *f; 829 FILE *f;
791 Key *public; 830 struct sshkey *public;
792 char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; 831 char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;
793 int i, skip = 0, num = 0, invalid = 1; 832 int r, i, skip = 0, num = 0, invalid = 1;
794 enum fp_rep rep; 833 enum sshkey_fp_rep rep;
795 enum fp_type fptype; 834 int fptype;
796 struct stat st; 835 struct stat st;
797 836
798 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; 837 fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
799 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; 838 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
800
801 if (!have_identity) 839 if (!have_identity)
802 ask_filename(pw, "Enter file in which the key is"); 840 ask_filename(pw, "Enter file in which the key is");
803 if (stat(identity_file, &st) < 0) { 841 if (stat(identity_file, &st) < 0) {
804 perror(identity_file); 842 perror(identity_file);
805 exit(1); 843 exit(1);
806 } 844 }
807 public = key_load_public(identity_file, &comment); 845 if ((r = sshkey_load_public(identity_file, &public, &comment)) != 0)
808 if (public != NULL) { 846 debug2("Error loading public key \"%s\": %s",
809 fp = key_fingerprint(public, fptype, rep); 847 identity_file, ssh_err(r));
810 ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); 848 else {
811 printf("%u %s %s (%s)\n", key_size(public), fp, comment, 849 fp = sshkey_fingerprint(public, fptype, rep);
812 key_type(public)); 850 ra = sshkey_fingerprint(public, fingerprint_hash,
851 SSH_FP_RANDOMART);
852 if (fp == NULL || ra == NULL)
853 fatal("%s: sshkey_fingerprint fail", __func__);
854 printf("%u %s %s (%s)\n", sshkey_size(public), fp, comment,
855 sshkey_type(public));
813 if (log_level >= SYSLOG_LEVEL_VERBOSE) 856 if (log_level >= SYSLOG_LEVEL_VERBOSE)
814 printf("%s\n", ra); 857 printf("%s\n", ra);
815 key_free(public); 858 sshkey_free(public);
816 free(comment); 859 free(comment);
817 free(ra); 860 free(ra);
818 free(fp); 861 free(fp);
@@ -861,26 +904,31 @@ do_fingerprint(struct passwd *pw)
861 *cp++ = '\0'; 904 *cp++ = '\0';
862 } 905 }
863 ep = cp; 906 ep = cp;
864 public = key_new(KEY_RSA1); 907 if ((public = sshkey_new(KEY_RSA1)) == NULL)
865 if (key_read(public, &cp) != 1) { 908 fatal("sshkey_new failed");
909 if ((r = sshkey_read(public, &cp)) != 0) {
866 cp = ep; 910 cp = ep;
867 key_free(public); 911 sshkey_free(public);
868 public = key_new(KEY_UNSPEC); 912 if ((public = sshkey_new(KEY_UNSPEC)) == NULL)
869 if (key_read(public, &cp) != 1) { 913 fatal("sshkey_new failed");
870 key_free(public); 914 if ((r = sshkey_read(public, &cp)) != 0) {
915 sshkey_free(public);
871 continue; 916 continue;
872 } 917 }
873 } 918 }
874 comment = *cp ? cp : comment; 919 comment = *cp ? cp : comment;
875 fp = key_fingerprint(public, fptype, rep); 920 fp = sshkey_fingerprint(public, fptype, rep);
876 ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); 921 ra = sshkey_fingerprint(public, fingerprint_hash,
877 printf("%u %s %s (%s)\n", key_size(public), fp, 922 SSH_FP_RANDOMART);
878 comment ? comment : "no comment", key_type(public)); 923 if (fp == NULL || ra == NULL)
924 fatal("%s: sshkey_fingerprint fail", __func__);
925 printf("%u %s %s (%s)\n", sshkey_size(public), fp,
926 comment ? comment : "no comment", sshkey_type(public));
879 if (log_level >= SYSLOG_LEVEL_VERBOSE) 927 if (log_level >= SYSLOG_LEVEL_VERBOSE)
880 printf("%s\n", ra); 928 printf("%s\n", ra);
881 free(ra); 929 free(ra);
882 free(fp); 930 free(fp);
883 key_free(public); 931 sshkey_free(public);
884 invalid = 0; 932 invalid = 0;
885 } 933 }
886 fclose(f); 934 fclose(f);
@@ -912,9 +960,9 @@ do_gen_all_hostkeys(struct passwd *pw)
912 960
913 int first = 0; 961 int first = 0;
914 struct stat st; 962 struct stat st;
915 Key *private, *public; 963 struct sshkey *private, *public;
916 char comment[1024]; 964 char comment[1024];
917 int i, type, fd; 965 int i, type, fd, r;
918 FILE *f; 966 FILE *f;
919 967
920 for (i = 0; key_types[i].key_type; i++) { 968 for (i = 0; key_types[i].key_type; i++) {
@@ -933,98 +981,175 @@ do_gen_all_hostkeys(struct passwd *pw)
933 } 981 }
934 printf("%s ", key_types[i].key_type_display); 982 printf("%s ", key_types[i].key_type_display);
935 fflush(stdout); 983 fflush(stdout);
936 type = key_type_from_name(key_types[i].key_type); 984 type = sshkey_type_from_name(key_types[i].key_type);
937 strlcpy(identity_file, key_types[i].path, sizeof(identity_file)); 985 strlcpy(identity_file, key_types[i].path, sizeof(identity_file));
938 bits = 0; 986 bits = 0;
939 type_bits_valid(type, &bits); 987 type_bits_valid(type, NULL, &bits);
940 private = key_generate(type, bits); 988 if ((r = sshkey_generate(type, bits, &private)) != 0) {
941 if (private == NULL) { 989 fprintf(stderr, "key_generate failed: %s\n",
942 fprintf(stderr, "key_generate failed\n"); 990 ssh_err(r));
943 first = 0; 991 first = 0;
944 continue; 992 continue;
945 } 993 }
946 public = key_from_private(private); 994 if ((r = sshkey_from_private(private, &public)) != 0)
995 fatal("sshkey_from_private failed: %s", ssh_err(r));
947 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, 996 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
948 hostname); 997 hostname);
949 if (!key_save_private(private, identity_file, "", comment, 998 if ((r = sshkey_save_private(private, identity_file, "",
950 use_new_format, new_format_cipher, rounds)) { 999 comment, use_new_format, new_format_cipher, rounds)) != 0) {
951 printf("Saving the key failed: %s.\n", identity_file); 1000 printf("Saving key \"%s\" failed: %s\n", identity_file,
952 key_free(private); 1001 ssh_err(r));
953 key_free(public); 1002 sshkey_free(private);
1003 sshkey_free(public);
954 first = 0; 1004 first = 0;
955 continue; 1005 continue;
956 } 1006 }
957 key_free(private); 1007 sshkey_free(private);
958 strlcat(identity_file, ".pub", sizeof(identity_file)); 1008 strlcat(identity_file, ".pub", sizeof(identity_file));
959 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 1009 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
960 if (fd == -1) { 1010 if (fd == -1) {
961 printf("Could not save your public key in %s\n", 1011 printf("Could not save your public key in %s\n",
962 identity_file); 1012 identity_file);
963 key_free(public); 1013 sshkey_free(public);
964 first = 0; 1014 first = 0;
965 continue; 1015 continue;
966 } 1016 }
967 f = fdopen(fd, "w"); 1017 f = fdopen(fd, "w");
968 if (f == NULL) { 1018 if (f == NULL) {
969 printf("fdopen %s failed\n", identity_file); 1019 printf("fdopen %s failed\n", identity_file);
970 key_free(public); 1020 close(fd);
1021 sshkey_free(public);
971 first = 0; 1022 first = 0;
972 continue; 1023 continue;
973 } 1024 }
974 if (!key_write(public, f)) { 1025 if ((r = sshkey_write(public, f)) != 0) {
975 fprintf(stderr, "write key failed\n"); 1026 fprintf(stderr, "write key failed: %s\n", ssh_err(r));
976 key_free(public); 1027 fclose(f);
1028 sshkey_free(public);
977 first = 0; 1029 first = 0;
978 continue; 1030 continue;
979 } 1031 }
980 fprintf(f, " %s\n", comment); 1032 fprintf(f, " %s\n", comment);
981 fclose(f); 1033 fclose(f);
982 key_free(public); 1034 sshkey_free(public);
983 1035
984 } 1036 }
985 if (first != 0) 1037 if (first != 0)
986 printf("\n"); 1038 printf("\n");
987} 1039}
988 1040
989static void 1041struct known_hosts_ctx {
990printhost(FILE *f, const char *name, Key *public, int ca, int revoked, int hash) 1042 const char *host; /* Hostname searched for in find/delete case */
1043 FILE *out; /* Output file, stdout for find_hosts case */
1044 int has_unhashed; /* When hashing, original had unhashed hosts */
1045 int found_key; /* For find/delete, host was found */
1046 int invalid; /* File contained invalid items; don't delete */
1047};
1048
1049static int
1050known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx)
991{ 1051{
992 if (print_fingerprint) { 1052 struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx;
993 enum fp_rep rep; 1053 char *hashed, *cp, *hosts, *ohosts;
994 enum fp_type fptype; 1054 int has_wild = l->hosts && strcspn(l->hosts, "*?!") != strlen(l->hosts);
995 char *fp, *ra; 1055
996 1056 switch (l->status) {
997 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; 1057 case HKF_STATUS_OK:
998 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; 1058 case HKF_STATUS_MATCHED:
999 fp = key_fingerprint(public, fptype, rep); 1059 /*
1000 ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); 1060 * Don't hash hosts already already hashed, with wildcard
1001 printf("%u %s %s (%s)\n", key_size(public), fp, name, 1061 * characters or a CA/revocation marker.
1002 key_type(public)); 1062 */
1003 if (log_level >= SYSLOG_LEVEL_VERBOSE) 1063 if ((l->match & HKF_MATCH_HOST_HASHED) != 0 ||
1004 printf("%s\n", ra); 1064 has_wild || l->marker != MRK_NONE) {
1005 free(ra); 1065 fprintf(ctx->out, "%s\n", l->line);
1006 free(fp); 1066 if (has_wild && !find_host) {
1007 } else { 1067 fprintf(stderr, "%s:%ld: ignoring host name "
1008 if (hash && (name = host_hash(name, NULL, 0)) == NULL) 1068 "with wildcard: %.64s\n", l->path,
1009 fatal("hash_host failed"); 1069 l->linenum, l->hosts);
1010 fprintf(f, "%s%s%s ", ca ? CA_MARKER " " : "", 1070 }
1011 revoked ? REVOKE_MARKER " " : "" , name); 1071 return 0;
1012 if (!key_write(public, f)) 1072 }
1013 fatal("key_write failed"); 1073 /*
1014 fprintf(f, "\n"); 1074 * Split any comma-separated hostnames from the host list,
1075 * hash and store separately.
1076 */
1077 ohosts = hosts = xstrdup(l->hosts);
1078 while ((cp = strsep(&hosts, ",")) != NULL && *cp != '\0') {
1079 if ((hashed = host_hash(cp, NULL, 0)) == NULL)
1080 fatal("hash_host failed");
1081 fprintf(ctx->out, "%s %s\n", hashed, l->rawkey);
1082 ctx->has_unhashed = 1;
1083 }
1084 free(ohosts);
1085 return 0;
1086 case HKF_STATUS_INVALID:
1087 /* Retain invalid lines, but mark file as invalid. */
1088 ctx->invalid = 1;
1089 fprintf(stderr, "%s:%ld: invalid line\n", l->path, l->linenum);
1090 /* FALLTHROUGH */
1091 default:
1092 fprintf(ctx->out, "%s\n", l->line);
1093 return 0;
1015 } 1094 }
1095 /* NOTREACHED */
1096 return -1;
1097}
1098
1099static int
1100known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
1101{
1102 struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx;
1103
1104 if (l->status == HKF_STATUS_MATCHED) {
1105 if (delete_host) {
1106 if (l->marker != MRK_NONE) {
1107 /* Don't remove CA and revocation lines */
1108 fprintf(ctx->out, "%s\n", l->line);
1109 } else {
1110 /*
1111 * Hostname matches and has no CA/revoke
1112 * marker, delete it by *not* writing the
1113 * line to ctx->out.
1114 */
1115 ctx->found_key = 1;
1116 if (!quiet)
1117 printf("# Host %s found: line %ld\n",
1118 ctx->host, l->linenum);
1119 }
1120 return 0;
1121 } else if (find_host) {
1122 ctx->found_key = 1;
1123 if (!quiet) {
1124 printf("# Host %s found: line %ld %s\n",
1125 ctx->host,
1126 l->linenum, l->marker == MRK_CA ? "CA" :
1127 (l->marker == MRK_REVOKE ? "REVOKED" : ""));
1128 }
1129 if (hash_hosts)
1130 known_hosts_hash(l, ctx);
1131 else
1132 fprintf(ctx->out, "%s\n", l->line);
1133 return 0;
1134 }
1135 } else if (delete_host) {
1136 /* Retain non-matching hosts when deleting */
1137 if (l->status == HKF_STATUS_INVALID) {
1138 ctx->invalid = 1;
1139 fprintf(stderr, "%s:%ld: invalid line\n",
1140 l->path, l->linenum);
1141 }
1142 fprintf(ctx->out, "%s\n", l->line);
1143 }
1144 return 0;
1016} 1145}
1017 1146
1018static void 1147static void
1019do_known_hosts(struct passwd *pw, const char *name) 1148do_known_hosts(struct passwd *pw, const char *name)
1020{ 1149{
1021 FILE *in, *out = stdout; 1150 char *cp, tmp[PATH_MAX], old[PATH_MAX];
1022 Key *pub; 1151 int r, fd, oerrno, inplace = 0;
1023 char *cp, *cp2, *kp, *kp2; 1152 struct known_hosts_ctx ctx;
1024 char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN];
1025 int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0;
1026 int ca, revoked;
1027 int found_key = 0;
1028 1153
1029 if (!have_identity) { 1154 if (!have_identity) {
1030 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); 1155 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
@@ -1034,10 +1159,11 @@ do_known_hosts(struct passwd *pw, const char *name)
1034 free(cp); 1159 free(cp);
1035 have_identity = 1; 1160 have_identity = 1;
1036 } 1161 }
1037 if ((in = fopen(identity_file, "r")) == NULL)
1038 fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
1039 1162
1040 /* XXX this code is a mess; refactor -djm */ 1163 memset(&ctx, 0, sizeof(ctx));
1164 ctx.out = stdout;
1165 ctx.host = name;
1166
1041 /* 1167 /*
1042 * Find hosts goes to stdout, hash and deletions happen in-place 1168 * Find hosts goes to stdout, hash and deletions happen in-place
1043 * A corner case is ssh-keygen -HF foo, which should go to stdout 1169 * A corner case is ssh-keygen -HF foo, which should go to stdout
@@ -1049,182 +1175,39 @@ do_known_hosts(struct passwd *pw, const char *name)
1049 strlcat(old, ".old", sizeof(old)) >= sizeof(old)) 1175 strlcat(old, ".old", sizeof(old)) >= sizeof(old))
1050 fatal("known_hosts path too long"); 1176 fatal("known_hosts path too long");
1051 umask(077); 1177 umask(077);
1052 if ((c = mkstemp(tmp)) == -1) 1178 if ((fd = mkstemp(tmp)) == -1)
1053 fatal("mkstemp: %s", strerror(errno)); 1179 fatal("mkstemp: %s", strerror(errno));
1054 if ((out = fdopen(c, "w")) == NULL) { 1180 if ((ctx.out = fdopen(fd, "w")) == NULL) {
1055 c = errno; 1181 oerrno = errno;
1056 unlink(tmp); 1182 unlink(tmp);
1057 fatal("fdopen: %s", strerror(c)); 1183 fatal("fdopen: %s", strerror(oerrno));
1058 } 1184 }
1059 inplace = 1; 1185 inplace = 1;
1060 } 1186 }
1061 1187
1062 while (fgets(line, sizeof(line), in)) { 1188 /* XXX support identity_file == "-" for stdin */
1063 if ((cp = strchr(line, '\n')) == NULL) { 1189 if ((r = hostkeys_foreach(identity_file,
1064 error("line %d too long: %.40s...", num + 1, line); 1190 hash_hosts ? known_hosts_hash : known_hosts_find_delete, &ctx,
1065 skip = 1; 1191 name, NULL, find_host ? HKF_WANT_MATCH : 0)) != 0)
1066 invalid = 1; 1192 fatal("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r));
1067 continue;
1068 }
1069 num++;
1070 if (skip) {
1071 skip = 0;
1072 continue;
1073 }
1074 *cp = '\0';
1075 1193
1076 /* Skip leading whitespace, empty and comment lines. */ 1194 if (inplace)
1077 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 1195 fclose(ctx.out);
1078 ;
1079 if (!*cp || *cp == '\n' || *cp == '#') {
1080 if (inplace)
1081 fprintf(out, "%s\n", cp);
1082 continue;
1083 }
1084 /* Check whether this is a CA key or revocation marker */
1085 if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 &&
1086 (cp[sizeof(CA_MARKER) - 1] == ' ' ||
1087 cp[sizeof(CA_MARKER) - 1] == '\t')) {
1088 ca = 1;
1089 cp += sizeof(CA_MARKER);
1090 } else
1091 ca = 0;
1092 if (strncasecmp(cp, REVOKE_MARKER,
1093 sizeof(REVOKE_MARKER) - 1) == 0 &&
1094 (cp[sizeof(REVOKE_MARKER) - 1] == ' ' ||
1095 cp[sizeof(REVOKE_MARKER) - 1] == '\t')) {
1096 revoked = 1;
1097 cp += sizeof(REVOKE_MARKER);
1098 } else
1099 revoked = 0;
1100 1196
1101 /* Find the end of the host name portion. */ 1197 if (ctx.invalid) {
1102 for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++)
1103 ;
1104
1105 if (*kp == '\0' || *(kp + 1) == '\0') {
1106 error("line %d missing key: %.40s...",
1107 num, line);
1108 invalid = 1;
1109 continue;
1110 }
1111 *kp++ = '\0';
1112 kp2 = kp;
1113
1114 pub = key_new(KEY_RSA1);
1115 if (key_read(pub, &kp) != 1) {
1116 kp = kp2;
1117 key_free(pub);
1118 pub = key_new(KEY_UNSPEC);
1119 if (key_read(pub, &kp) != 1) {
1120 error("line %d invalid key: %.40s...",
1121 num, line);
1122 key_free(pub);
1123 invalid = 1;
1124 continue;
1125 }
1126 }
1127
1128 if (*cp == HASH_DELIM) {
1129 if (find_host || delete_host) {
1130 cp2 = host_hash(name, cp, strlen(cp));
1131 if (cp2 == NULL) {
1132 error("line %d: invalid hashed "
1133 "name: %.64s...", num, line);
1134 invalid = 1;
1135 continue;
1136 }
1137 c = (strcmp(cp2, cp) == 0);
1138 if (find_host && c) {
1139 if (!quiet)
1140 printf("# Host %s found: "
1141 "line %d type %s%s\n", name,
1142 num, key_type(pub),
1143 ca ? " (CA key)" :
1144 revoked? " (revoked)" : "");
1145 printhost(out, cp, pub, ca, revoked, 0);
1146 found_key = 1;
1147 }
1148 if (delete_host) {
1149 if (!c || ca || revoked) {
1150 printhost(out, cp, pub,
1151 ca, revoked, 0);
1152 } else {
1153 printf("# Host %s found: "
1154 "line %d type %s\n", name,
1155 num, key_type(pub));
1156 }
1157 }
1158 } else if (hash_hosts)
1159 printhost(out, cp, pub, ca, revoked, 0);
1160 } else {
1161 if (find_host || delete_host) {
1162 c = (match_hostname(name, cp,
1163 strlen(cp)) == 1);
1164 if (find_host && c) {
1165 if (!quiet)
1166 printf("# Host %s found: "
1167 "line %d type %s%s\n", name,
1168 num, key_type(pub),
1169 ca ? " (CA key)" : "");
1170 printhost(out, name, pub, ca, revoked,
1171 hash_hosts && !(ca || revoked));
1172 found_key = 1;
1173 }
1174 if (delete_host) {
1175 if (!c || ca || revoked) {
1176 printhost(out, cp, pub,
1177 ca, revoked, 0);
1178 } else {
1179 printf("# Host %s found: "
1180 "line %d type %s\n", name,
1181 num, key_type(pub));
1182 }
1183 }
1184 } else if (hash_hosts && (ca || revoked)) {
1185 /* Don't hash CA and revoked keys' hostnames */
1186 printhost(out, cp, pub, ca, revoked, 0);
1187 has_unhashed = 1;
1188 } else if (hash_hosts) {
1189 /* Hash each hostname separately */
1190 for (cp2 = strsep(&cp, ",");
1191 cp2 != NULL && *cp2 != '\0';
1192 cp2 = strsep(&cp, ",")) {
1193 if (strcspn(cp2, "*?!") !=
1194 strlen(cp2)) {
1195 fprintf(stderr, "Warning: "
1196 "ignoring host name with "
1197 "metacharacters: %.64s\n",
1198 cp2);
1199 printhost(out, cp2, pub, ca,
1200 revoked, 0);
1201 has_unhashed = 1;
1202 } else {
1203 printhost(out, cp2, pub, ca,
1204 revoked, 1);
1205 }
1206 }
1207 }
1208 }
1209 key_free(pub);
1210 }
1211 fclose(in);
1212
1213 if (invalid) {
1214 fprintf(stderr, "%s is not a valid known_hosts file.\n", 1198 fprintf(stderr, "%s is not a valid known_hosts file.\n",
1215 identity_file); 1199 identity_file);
1216 if (inplace) { 1200 if (inplace) {
1217 fprintf(stderr, "Not replacing existing known_hosts " 1201 fprintf(stderr, "Not replacing existing known_hosts "
1218 "file because of errors\n"); 1202 "file because of errors\n");
1219 fclose(out);
1220 unlink(tmp); 1203 unlink(tmp);
1221 } 1204 }
1222 exit(1); 1205 exit(1);
1223 } 1206 } else if (delete_host && !ctx.found_key) {
1224 1207 fprintf(stderr, "Host %s not found in %s\n",
1225 if (inplace) { 1208 name, identity_file);
1226 fclose(out); 1209 unlink(tmp);
1227 1210 } else if (inplace) {
1228 /* Backup existing file */ 1211 /* Backup existing file */
1229 if (unlink(old) == -1 && errno != ENOENT) 1212 if (unlink(old) == -1 && errno != ENOENT)
1230 fatal("unlink %.100s: %s", old, strerror(errno)); 1213 fatal("unlink %.100s: %s", old, strerror(errno));
@@ -1242,7 +1225,7 @@ do_known_hosts(struct passwd *pw, const char *name)
1242 1225
1243 fprintf(stderr, "%s updated.\n", identity_file); 1226 fprintf(stderr, "%s updated.\n", identity_file);
1244 fprintf(stderr, "Original contents retained as %s\n", old); 1227 fprintf(stderr, "Original contents retained as %s\n", old);
1245 if (has_unhashed) { 1228 if (ctx.has_unhashed) {
1246 fprintf(stderr, "WARNING: %s contains unhashed " 1229 fprintf(stderr, "WARNING: %s contains unhashed "
1247 "entries\n", old); 1230 "entries\n", old);
1248 fprintf(stderr, "Delete this file to ensure privacy " 1231 fprintf(stderr, "Delete this file to ensure privacy "
@@ -1250,7 +1233,7 @@ do_known_hosts(struct passwd *pw, const char *name)
1250 } 1233 }
1251 } 1234 }
1252 1235
1253 exit (find_host && !found_key); 1236 exit (find_host && !ctx.found_key);
1254} 1237}
1255 1238
1256/* 1239/*
@@ -1263,7 +1246,8 @@ do_change_passphrase(struct passwd *pw)
1263 char *comment; 1246 char *comment;
1264 char *old_passphrase, *passphrase1, *passphrase2; 1247 char *old_passphrase, *passphrase1, *passphrase2;
1265 struct stat st; 1248 struct stat st;
1266 Key *private; 1249 struct sshkey *private;
1250 int r;
1267 1251
1268 if (!have_identity) 1252 if (!have_identity)
1269 ask_filename(pw, "Enter file in which the key is"); 1253 ask_filename(pw, "Enter file in which the key is");
@@ -1272,24 +1256,28 @@ do_change_passphrase(struct passwd *pw)
1272 exit(1); 1256 exit(1);
1273 } 1257 }
1274 /* Try to load the file with empty passphrase. */ 1258 /* Try to load the file with empty passphrase. */
1275 private = key_load_private(identity_file, "", &comment); 1259 r = sshkey_load_private(identity_file, "", &private, &comment);
1276 if (private == NULL) { 1260 if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) {
1277 if (identity_passphrase) 1261 if (identity_passphrase)
1278 old_passphrase = xstrdup(identity_passphrase); 1262 old_passphrase = xstrdup(identity_passphrase);
1279 else 1263 else
1280 old_passphrase = 1264 old_passphrase =
1281 read_passphrase("Enter old passphrase: ", 1265 read_passphrase("Enter old passphrase: ",
1282 RP_ALLOW_STDIN); 1266 RP_ALLOW_STDIN);
1283 private = key_load_private(identity_file, old_passphrase, 1267 r = sshkey_load_private(identity_file, old_passphrase,
1284 &comment); 1268 &private, &comment);
1285 explicit_bzero(old_passphrase, strlen(old_passphrase)); 1269 explicit_bzero(old_passphrase, strlen(old_passphrase));
1286 free(old_passphrase); 1270 free(old_passphrase);
1287 if (private == NULL) { 1271 if (r != 0)
1288 printf("Bad passphrase.\n"); 1272 goto badkey;
1289 exit(1); 1273 } else if (r != 0) {
1290 } 1274 badkey:
1275 fprintf(stderr, "Failed to load key \"%s\": %s\n",
1276 identity_file, ssh_err(r));
1277 exit(1);
1291 } 1278 }
1292 printf("Key has comment '%s'\n", comment); 1279 if (comment)
1280 printf("Key has comment '%s'\n", comment);
1293 1281
1294 /* Ask the new passphrase (twice). */ 1282 /* Ask the new passphrase (twice). */
1295 if (identity_new_passphrase) { 1283 if (identity_new_passphrase) {
@@ -1317,19 +1305,20 @@ do_change_passphrase(struct passwd *pw)
1317 } 1305 }
1318 1306
1319 /* Save the file using the new passphrase. */ 1307 /* Save the file using the new passphrase. */
1320 if (!key_save_private(private, identity_file, passphrase1, comment, 1308 if ((r = sshkey_save_private(private, identity_file, passphrase1,
1321 use_new_format, new_format_cipher, rounds)) { 1309 comment, use_new_format, new_format_cipher, rounds)) != 0) {
1322 printf("Saving the key failed: %s.\n", identity_file); 1310 printf("Saving key \"%s\" failed: %s.\n",
1311 identity_file, ssh_err(r));
1323 explicit_bzero(passphrase1, strlen(passphrase1)); 1312 explicit_bzero(passphrase1, strlen(passphrase1));
1324 free(passphrase1); 1313 free(passphrase1);
1325 key_free(private); 1314 sshkey_free(private);
1326 free(comment); 1315 free(comment);
1327 exit(1); 1316 exit(1);
1328 } 1317 }
1329 /* Destroy the passphrase and the copy of the key in memory. */ 1318 /* Destroy the passphrase and the copy of the key in memory. */
1330 explicit_bzero(passphrase1, strlen(passphrase1)); 1319 explicit_bzero(passphrase1, strlen(passphrase1));
1331 free(passphrase1); 1320 free(passphrase1);
1332 key_free(private); /* Destroys contents */ 1321 sshkey_free(private); /* Destroys contents */
1333 free(comment); 1322 free(comment);
1334 1323
1335 printf("Your identification has been saved with the new passphrase.\n"); 1324 printf("Your identification has been saved with the new passphrase.\n");
@@ -1342,9 +1331,10 @@ do_change_passphrase(struct passwd *pw)
1342static int 1331static int
1343do_print_resource_record(struct passwd *pw, char *fname, char *hname) 1332do_print_resource_record(struct passwd *pw, char *fname, char *hname)
1344{ 1333{
1345 Key *public; 1334 struct sshkey *public;
1346 char *comment = NULL; 1335 char *comment = NULL;
1347 struct stat st; 1336 struct stat st;
1337 int r;
1348 1338
1349 if (fname == NULL) 1339 if (fname == NULL)
1350 fatal("%s: no filename", __func__); 1340 fatal("%s: no filename", __func__);
@@ -1354,18 +1344,15 @@ do_print_resource_record(struct passwd *pw, char *fname, char *hname)
1354 perror(fname); 1344 perror(fname);
1355 exit(1); 1345 exit(1);
1356 } 1346 }
1357 public = key_load_public(fname, &comment); 1347 if ((r = sshkey_load_public(fname, &public, &comment)) != 0) {
1358 if (public != NULL) { 1348 printf("Failed to read v2 public key from \"%s\": %s.\n",
1359 export_dns_rr(hname, public, stdout, print_generic); 1349 fname, ssh_err(r));
1360 key_free(public); 1350 exit(1);
1361 free(comment);
1362 return 1;
1363 } 1351 }
1364 if (comment) 1352 export_dns_rr(hname, public, stdout, print_generic);
1365 free(comment); 1353 sshkey_free(public);
1366 1354 free(comment);
1367 printf("failed to read v2 public key from %s.\n", fname); 1355 return 1;
1368 exit(1);
1369} 1356}
1370 1357
1371/* 1358/*
@@ -1375,11 +1362,11 @@ static void
1375do_change_comment(struct passwd *pw) 1362do_change_comment(struct passwd *pw)
1376{ 1363{
1377 char new_comment[1024], *comment, *passphrase; 1364 char new_comment[1024], *comment, *passphrase;
1378 Key *private; 1365 struct sshkey *private;
1379 Key *public; 1366 struct sshkey *public;
1380 struct stat st; 1367 struct stat st;
1381 FILE *f; 1368 FILE *f;
1382 int fd; 1369 int r, fd;
1383 1370
1384 if (!have_identity) 1371 if (!have_identity)
1385 ask_filename(pw, "Enter file in which the key is"); 1372 ask_filename(pw, "Enter file in which the key is");
@@ -1387,8 +1374,14 @@ do_change_comment(struct passwd *pw)
1387 perror(identity_file); 1374 perror(identity_file);
1388 exit(1); 1375 exit(1);
1389 } 1376 }
1390 private = key_load_private(identity_file, "", &comment); 1377 if ((r = sshkey_load_private(identity_file, "",
1391 if (private == NULL) { 1378 &private, &comment)) == 0)
1379 passphrase = xstrdup("");
1380 else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) {
1381 printf("Cannot load private key \"%s\": %s.\n",
1382 identity_file, ssh_err(r));
1383 exit(1);
1384 } else {
1392 if (identity_passphrase) 1385 if (identity_passphrase)
1393 passphrase = xstrdup(identity_passphrase); 1386 passphrase = xstrdup(identity_passphrase);
1394 else if (identity_new_passphrase) 1387 else if (identity_new_passphrase)
@@ -1397,19 +1390,18 @@ do_change_comment(struct passwd *pw)
1397 passphrase = read_passphrase("Enter passphrase: ", 1390 passphrase = read_passphrase("Enter passphrase: ",
1398 RP_ALLOW_STDIN); 1391 RP_ALLOW_STDIN);
1399 /* Try to load using the passphrase. */ 1392 /* Try to load using the passphrase. */
1400 private = key_load_private(identity_file, passphrase, &comment); 1393 if ((r = sshkey_load_private(identity_file, passphrase,
1401 if (private == NULL) { 1394 &private, &comment)) != 0) {
1402 explicit_bzero(passphrase, strlen(passphrase)); 1395 explicit_bzero(passphrase, strlen(passphrase));
1403 free(passphrase); 1396 free(passphrase);
1404 printf("Bad passphrase.\n"); 1397 printf("Cannot load private key \"%s\": %s.\n",
1398 identity_file, ssh_err(r));
1405 exit(1); 1399 exit(1);
1406 } 1400 }
1407 } else {
1408 passphrase = xstrdup("");
1409 } 1401 }
1410 if (private->type != KEY_RSA1) { 1402 if (private->type != KEY_RSA1) {
1411 fprintf(stderr, "Comments are only supported for RSA1 keys.\n"); 1403 fprintf(stderr, "Comments are only supported for RSA1 keys.\n");
1412 key_free(private); 1404 sshkey_free(private);
1413 exit(1); 1405 exit(1);
1414 } 1406 }
1415 printf("Key now has comment '%s'\n", comment); 1407 printf("Key now has comment '%s'\n", comment);
@@ -1421,26 +1413,28 @@ do_change_comment(struct passwd *pw)
1421 fflush(stdout); 1413 fflush(stdout);
1422 if (!fgets(new_comment, sizeof(new_comment), stdin)) { 1414 if (!fgets(new_comment, sizeof(new_comment), stdin)) {
1423 explicit_bzero(passphrase, strlen(passphrase)); 1415 explicit_bzero(passphrase, strlen(passphrase));
1424 key_free(private); 1416 sshkey_free(private);
1425 exit(1); 1417 exit(1);
1426 } 1418 }
1427 new_comment[strcspn(new_comment, "\n")] = '\0'; 1419 new_comment[strcspn(new_comment, "\n")] = '\0';
1428 } 1420 }
1429 1421
1430 /* Save the file using the new passphrase. */ 1422 /* Save the file using the new passphrase. */
1431 if (!key_save_private(private, identity_file, passphrase, new_comment, 1423 if ((r = sshkey_save_private(private, identity_file, passphrase,
1432 use_new_format, new_format_cipher, rounds)) { 1424 new_comment, use_new_format, new_format_cipher, rounds)) != 0) {
1433 printf("Saving the key failed: %s.\n", identity_file); 1425 printf("Saving key \"%s\" failed: %s\n",
1426 identity_file, ssh_err(r));
1434 explicit_bzero(passphrase, strlen(passphrase)); 1427 explicit_bzero(passphrase, strlen(passphrase));
1435 free(passphrase); 1428 free(passphrase);
1436 key_free(private); 1429 sshkey_free(private);
1437 free(comment); 1430 free(comment);
1438 exit(1); 1431 exit(1);
1439 } 1432 }
1440 explicit_bzero(passphrase, strlen(passphrase)); 1433 explicit_bzero(passphrase, strlen(passphrase));
1441 free(passphrase); 1434 free(passphrase);
1442 public = key_from_private(private); 1435 if ((r = sshkey_from_private(private, &public)) != 0)
1443 key_free(private); 1436 fatal("key_from_private failed: %s", ssh_err(r));
1437 sshkey_free(private);
1444 1438
1445 strlcat(identity_file, ".pub", sizeof(identity_file)); 1439 strlcat(identity_file, ".pub", sizeof(identity_file));
1446 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 1440 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
@@ -1453,9 +1447,9 @@ do_change_comment(struct passwd *pw)
1453 printf("fdopen %s failed\n", identity_file); 1447 printf("fdopen %s failed\n", identity_file);
1454 exit(1); 1448 exit(1);
1455 } 1449 }
1456 if (!key_write(public, f)) 1450 if ((r = sshkey_write(public, f)) != 0)
1457 fprintf(stderr, "write key failed\n"); 1451 fprintf(stderr, "write key failed: %s\n", ssh_err(r));
1458 key_free(public); 1452 sshkey_free(public);
1459 fprintf(f, " %s\n", new_comment); 1453 fprintf(f, " %s\n", new_comment);
1460 fclose(f); 1454 fclose(f);
1461 1455
@@ -1504,34 +1498,39 @@ fmt_validity(u_int64_t valid_from, u_int64_t valid_to)
1504} 1498}
1505 1499
1506static void 1500static void
1507add_flag_option(Buffer *c, const char *name) 1501add_flag_option(struct sshbuf *c, const char *name)
1508{ 1502{
1503 int r;
1504
1509 debug3("%s: %s", __func__, name); 1505 debug3("%s: %s", __func__, name);
1510 buffer_put_cstring(c, name); 1506 if ((r = sshbuf_put_cstring(c, name)) != 0 ||
1511 buffer_put_string(c, NULL, 0); 1507 (r = sshbuf_put_string(c, NULL, 0)) != 0)
1508 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1512} 1509}
1513 1510
1514static void 1511static void
1515add_string_option(Buffer *c, const char *name, const char *value) 1512add_string_option(struct sshbuf *c, const char *name, const char *value)
1516{ 1513{
1517 Buffer b; 1514 struct sshbuf *b;
1515 int r;
1518 1516
1519 debug3("%s: %s=%s", __func__, name, value); 1517 debug3("%s: %s=%s", __func__, name, value);
1520 buffer_init(&b); 1518 if ((b = sshbuf_new()) == NULL)
1521 buffer_put_cstring(&b, value); 1519 fatal("%s: sshbuf_new failed", __func__);
1522 1520 if ((r = sshbuf_put_cstring(b, value)) != 0 ||
1523 buffer_put_cstring(c, name); 1521 (r = sshbuf_put_cstring(c, name)) != 0 ||
1524 buffer_put_string(c, buffer_ptr(&b), buffer_len(&b)); 1522 (r = sshbuf_put_stringb(c, b)) != 0)
1525 1523 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1526 buffer_free(&b); 1524
1525 sshbuf_free(b);
1527} 1526}
1528 1527
1529#define OPTIONS_CRITICAL 1 1528#define OPTIONS_CRITICAL 1
1530#define OPTIONS_EXTENSIONS 2 1529#define OPTIONS_EXTENSIONS 2
1531static void 1530static void
1532prepare_options_buf(Buffer *c, int which) 1531prepare_options_buf(struct sshbuf *c, int which)
1533{ 1532{
1534 buffer_clear(c); 1533 sshbuf_reset(c);
1535 if ((which & OPTIONS_CRITICAL) != 0 && 1534 if ((which & OPTIONS_CRITICAL) != 0 &&
1536 certflags_command != NULL) 1535 certflags_command != NULL)
1537 add_string_option(c, "force-command", certflags_command); 1536 add_string_option(c, "force-command", certflags_command);
@@ -1555,29 +1554,30 @@ prepare_options_buf(Buffer *c, int which)
1555 add_string_option(c, "source-address", certflags_src_addr); 1554 add_string_option(c, "source-address", certflags_src_addr);
1556} 1555}
1557 1556
1558static Key * 1557static struct sshkey *
1559load_pkcs11_key(char *path) 1558load_pkcs11_key(char *path)
1560{ 1559{
1561#ifdef ENABLE_PKCS11 1560#ifdef ENABLE_PKCS11
1562 Key **keys = NULL, *public, *private = NULL; 1561 struct sshkey **keys = NULL, *public, *private = NULL;
1563 int i, nkeys; 1562 int r, i, nkeys;
1564 1563
1565 if ((public = key_load_public(path, NULL)) == NULL) 1564 if ((r = sshkey_load_public(path, &public, NULL)) != 0)
1566 fatal("Couldn't load CA public key \"%s\"", path); 1565 fatal("Couldn't load CA public key \"%s\": %s",
1566 path, ssh_err(r));
1567 1567
1568 nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys); 1568 nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys);
1569 debug3("%s: %d keys", __func__, nkeys); 1569 debug3("%s: %d keys", __func__, nkeys);
1570 if (nkeys <= 0) 1570 if (nkeys <= 0)
1571 fatal("cannot read public key from pkcs11"); 1571 fatal("cannot read public key from pkcs11");
1572 for (i = 0; i < nkeys; i++) { 1572 for (i = 0; i < nkeys; i++) {
1573 if (key_equal_public(public, keys[i])) { 1573 if (sshkey_equal_public(public, keys[i])) {
1574 private = keys[i]; 1574 private = keys[i];
1575 continue; 1575 continue;
1576 } 1576 }
1577 key_free(keys[i]); 1577 sshkey_free(keys[i]);
1578 } 1578 }
1579 free(keys); 1579 free(keys);
1580 key_free(public); 1580 sshkey_free(public);
1581 return private; 1581 return private;
1582#else 1582#else
1583 fatal("no pkcs11 support"); 1583 fatal("no pkcs11 support");
@@ -1587,15 +1587,15 @@ load_pkcs11_key(char *path)
1587static void 1587static void
1588do_ca_sign(struct passwd *pw, int argc, char **argv) 1588do_ca_sign(struct passwd *pw, int argc, char **argv)
1589{ 1589{
1590 int i, fd; 1590 int r, i, fd;
1591 u_int n; 1591 u_int n;
1592 Key *ca, *public; 1592 struct sshkey *ca, *public;
1593 char *otmp, *tmp, *cp, *out, *comment, **plist = NULL; 1593 char *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
1594 FILE *f; 1594 FILE *f;
1595 int v00 = 0; /* legacy keys */ 1595 int v00 = 0; /* legacy keys */
1596 1596
1597 if (key_type_name != NULL) { 1597 if (key_type_name != NULL) {
1598 switch (key_type_from_name(key_type_name)) { 1598 switch (sshkey_type_from_name(key_type_name)) {
1599 case KEY_RSA_CERT_V00: 1599 case KEY_RSA_CERT_V00:
1600 case KEY_DSA_CERT_V00: 1600 case KEY_DSA_CERT_V00:
1601 v00 = 1; 1601 v00 = 1;
@@ -1620,8 +1620,8 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1620 if (pkcs11provider != NULL) { 1620 if (pkcs11provider != NULL) {
1621 if ((ca = load_pkcs11_key(tmp)) == NULL) 1621 if ((ca = load_pkcs11_key(tmp)) == NULL)
1622 fatal("No PKCS#11 key matching %s found", ca_key_path); 1622 fatal("No PKCS#11 key matching %s found", ca_key_path);
1623 } else if ((ca = load_identity(tmp)) == NULL) 1623 } else
1624 fatal("Couldn't load CA key \"%s\"", tmp); 1624 ca = load_identity(tmp);
1625 free(tmp); 1625 free(tmp);
1626 1626
1627 for (i = 0; i < argc; i++) { 1627 for (i = 0; i < argc; i++) {
@@ -1639,16 +1639,18 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1639 } 1639 }
1640 1640
1641 tmp = tilde_expand_filename(argv[i], pw->pw_uid); 1641 tmp = tilde_expand_filename(argv[i], pw->pw_uid);
1642 if ((public = key_load_public(tmp, &comment)) == NULL) 1642 if ((r = sshkey_load_public(tmp, &public, &comment)) != 0)
1643 fatal("%s: unable to open \"%s\"", __func__, tmp); 1643 fatal("%s: unable to open \"%s\": %s",
1644 __func__, tmp, ssh_err(r));
1644 if (public->type != KEY_RSA && public->type != KEY_DSA && 1645 if (public->type != KEY_RSA && public->type != KEY_DSA &&
1645 public->type != KEY_ECDSA && public->type != KEY_ED25519) 1646 public->type != KEY_ECDSA && public->type != KEY_ED25519)
1646 fatal("%s: key \"%s\" type %s cannot be certified", 1647 fatal("%s: key \"%s\" type %s cannot be certified",
1647 __func__, tmp, key_type(public)); 1648 __func__, tmp, sshkey_type(public));
1648 1649
1649 /* Prepare certificate to sign */ 1650 /* Prepare certificate to sign */
1650 if (key_to_certified(public, v00) != 0) 1651 if ((r = sshkey_to_certified(public, v00)) != 0)
1651 fatal("Could not upgrade key %s to certificate", tmp); 1652 fatal("Could not upgrade key %s to certificate: %s",
1653 tmp, ssh_err(r));
1652 public->cert->type = cert_key_type; 1654 public->cert->type = cert_key_type;
1653 public->cert->serial = (u_int64_t)cert_serial; 1655 public->cert->serial = (u_int64_t)cert_serial;
1654 public->cert->key_id = xstrdup(cert_key_id); 1656 public->cert->key_id = xstrdup(cert_key_id);
@@ -1665,9 +1667,11 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1665 prepare_options_buf(public->cert->extensions, 1667 prepare_options_buf(public->cert->extensions,
1666 OPTIONS_EXTENSIONS); 1668 OPTIONS_EXTENSIONS);
1667 } 1669 }
1668 public->cert->signature_key = key_from_private(ca); 1670 if ((r = sshkey_from_private(ca,
1671 &public->cert->signature_key)) != 0)
1672 fatal("key_from_private (ca key): %s", ssh_err(r));
1669 1673
1670 if (key_certify(public, ca) != 0) 1674 if (sshkey_certify(public, ca) != 0)
1671 fatal("Couldn't not certify key %s", tmp); 1675 fatal("Couldn't not certify key %s", tmp);
1672 1676
1673 if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0) 1677 if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
@@ -1680,14 +1684,15 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1680 strerror(errno)); 1684 strerror(errno));
1681 if ((f = fdopen(fd, "w")) == NULL) 1685 if ((f = fdopen(fd, "w")) == NULL)
1682 fatal("%s: fdopen: %s", __func__, strerror(errno)); 1686 fatal("%s: fdopen: %s", __func__, strerror(errno));
1683 if (!key_write(public, f)) 1687 if ((r = sshkey_write(public, f)) != 0)
1684 fatal("Could not write certified key to %s", out); 1688 fatal("Could not write certified key to %s: %s",
1689 out, ssh_err(r));
1685 fprintf(f, " %s\n", comment); 1690 fprintf(f, " %s\n", comment);
1686 fclose(f); 1691 fclose(f);
1687 1692
1688 if (!quiet) { 1693 if (!quiet) {
1689 logit("Signed %s key %s: id \"%s\" serial %llu%s%s " 1694 logit("Signed %s key %s: id \"%s\" serial %llu%s%s "
1690 "valid %s", key_cert_type(public), 1695 "valid %s", sshkey_cert_type(public),
1691 out, public->cert->key_id, 1696 out, public->cert->key_id,
1692 (unsigned long long)public->cert->serial, 1697 (unsigned long long)public->cert->serial,
1693 cert_principals != NULL ? " for " : "", 1698 cert_principals != NULL ? " for " : "",
@@ -1695,7 +1700,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1695 fmt_validity(cert_valid_from, cert_valid_to)); 1700 fmt_validity(cert_valid_from, cert_valid_to));
1696 } 1701 }
1697 1702
1698 key_free(public); 1703 sshkey_free(public);
1699 free(out); 1704 free(out);
1700 } 1705 }
1701#ifdef ENABLE_PKCS11 1706#ifdef ENABLE_PKCS11
@@ -1846,21 +1851,20 @@ add_cert_option(char *opt)
1846} 1851}
1847 1852
1848static void 1853static void
1849show_options(const Buffer *optbuf, int v00, int in_critical) 1854show_options(struct sshbuf *optbuf, int v00, int in_critical)
1850{ 1855{
1851 char *name, *arg; 1856 char *name, *arg;
1852 const u_char *data; 1857 struct sshbuf *options, *option = NULL;
1853 u_int dlen; 1858 int r;
1854 Buffer options, option; 1859
1855 1860 if ((options = sshbuf_fromb(optbuf)) == NULL)
1856 buffer_init(&options); 1861 fatal("%s: sshbuf_fromb failed", __func__);
1857 buffer_append(&options, buffer_ptr(optbuf), buffer_len(optbuf)); 1862 while (sshbuf_len(options) != 0) {
1858 1863 sshbuf_free(option);
1859 buffer_init(&option); 1864 option = NULL;
1860 while (buffer_len(&options) != 0) { 1865 if ((r = sshbuf_get_cstring(options, &name, NULL)) != 0 ||
1861 name = buffer_get_string(&options, NULL); 1866 (r = sshbuf_froms(options, &option)) != 0)
1862 data = buffer_get_string_ptr(&options, &dlen); 1867 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1863 buffer_append(&option, data, dlen);
1864 printf(" %s", name); 1868 printf(" %s", name);
1865 if ((v00 || !in_critical) && 1869 if ((v00 || !in_critical) &&
1866 (strcmp(name, "permit-X11-forwarding") == 0 || 1870 (strcmp(name, "permit-X11-forwarding") == 0 ||
@@ -1872,50 +1876,56 @@ show_options(const Buffer *optbuf, int v00, int in_critical)
1872 else if ((v00 || in_critical) && 1876 else if ((v00 || in_critical) &&
1873 (strcmp(name, "force-command") == 0 || 1877 (strcmp(name, "force-command") == 0 ||
1874 strcmp(name, "source-address") == 0)) { 1878 strcmp(name, "source-address") == 0)) {
1875 arg = buffer_get_cstring(&option, NULL); 1879 if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0)
1880 fatal("%s: buffer error: %s",
1881 __func__, ssh_err(r));
1876 printf(" %s\n", arg); 1882 printf(" %s\n", arg);
1877 free(arg); 1883 free(arg);
1878 } else { 1884 } else {
1879 printf(" UNKNOWN OPTION (len %u)\n", 1885 printf(" UNKNOWN OPTION (len %zu)\n",
1880 buffer_len(&option)); 1886 sshbuf_len(option));
1881 buffer_clear(&option); 1887 sshbuf_reset(option);
1882 } 1888 }
1883 free(name); 1889 free(name);
1884 if (buffer_len(&option) != 0) 1890 if (sshbuf_len(option) != 0)
1885 fatal("Option corrupt: extra data at end"); 1891 fatal("Option corrupt: extra data at end");
1886 } 1892 }
1887 buffer_free(&option); 1893 sshbuf_free(option);
1888 buffer_free(&options); 1894 sshbuf_free(options);
1889} 1895}
1890 1896
1891static void 1897static void
1892do_show_cert(struct passwd *pw) 1898do_show_cert(struct passwd *pw)
1893{ 1899{
1894 Key *key; 1900 struct sshkey *key;
1895 struct stat st; 1901 struct stat st;
1896 char *key_fp, *ca_fp; 1902 char *key_fp, *ca_fp;
1897 u_int i, v00; 1903 u_int i, v00;
1904 int r;
1898 1905
1899 if (!have_identity) 1906 if (!have_identity)
1900 ask_filename(pw, "Enter file in which the key is"); 1907 ask_filename(pw, "Enter file in which the key is");
1901 if (stat(identity_file, &st) < 0) 1908 if (stat(identity_file, &st) < 0)
1902 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 1909 fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
1903 if ((key = key_load_public(identity_file, NULL)) == NULL) 1910 if ((r = sshkey_load_public(identity_file, &key, NULL)) != 0)
1904 fatal("%s is not a public key", identity_file); 1911 fatal("Cannot load public key \"%s\": %s",
1905 if (!key_is_cert(key)) 1912 identity_file, ssh_err(r));
1913 if (!sshkey_is_cert(key))
1906 fatal("%s is not a certificate", identity_file); 1914 fatal("%s is not a certificate", identity_file);
1907 v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00; 1915 v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00;
1908 1916
1909 key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); 1917 key_fp = sshkey_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT);
1910 ca_fp = key_fingerprint(key->cert->signature_key, 1918 ca_fp = sshkey_fingerprint(key->cert->signature_key,
1911 SSH_FP_MD5, SSH_FP_HEX); 1919 fingerprint_hash, SSH_FP_DEFAULT);
1920 if (key_fp == NULL || ca_fp == NULL)
1921 fatal("%s: sshkey_fingerprint fail", __func__);
1912 1922
1913 printf("%s:\n", identity_file); 1923 printf("%s:\n", identity_file);
1914 printf(" Type: %s %s certificate\n", key_ssh_name(key), 1924 printf(" Type: %s %s certificate\n", sshkey_ssh_name(key),
1915 key_cert_type(key)); 1925 sshkey_cert_type(key));
1916 printf(" Public key: %s %s\n", key_type(key), key_fp); 1926 printf(" Public key: %s %s\n", sshkey_type(key), key_fp);
1917 printf(" Signing CA: %s %s\n", 1927 printf(" Signing CA: %s %s\n",
1918 key_type(key->cert->signature_key), ca_fp); 1928 sshkey_type(key->cert->signature_key), ca_fp);
1919 printf(" Key ID: \"%s\"\n", key->cert->key_id); 1929 printf(" Key ID: \"%s\"\n", key->cert->key_id);
1920 if (!v00) { 1930 if (!v00) {
1921 printf(" Serial: %llu\n", 1931 printf(" Serial: %llu\n",
@@ -1933,7 +1943,7 @@ do_show_cert(struct passwd *pw)
1933 printf("\n"); 1943 printf("\n");
1934 } 1944 }
1935 printf(" Critical Options: "); 1945 printf(" Critical Options: ");
1936 if (buffer_len(key->cert->critical) == 0) 1946 if (sshbuf_len(key->cert->critical) == 0)
1937 printf("(none)\n"); 1947 printf("(none)\n");
1938 else { 1948 else {
1939 printf("\n"); 1949 printf("\n");
@@ -1941,7 +1951,7 @@ do_show_cert(struct passwd *pw)
1941 } 1951 }
1942 if (!v00) { 1952 if (!v00) {
1943 printf(" Extensions: "); 1953 printf(" Extensions: ");
1944 if (buffer_len(key->cert->extensions) == 0) 1954 if (sshbuf_len(key->cert->extensions) == 0)
1945 printf("(none)\n"); 1955 printf("(none)\n");
1946 else { 1956 else {
1947 printf("\n"); 1957 printf("\n");
@@ -1951,31 +1961,31 @@ do_show_cert(struct passwd *pw)
1951 exit(0); 1961 exit(0);
1952} 1962}
1953 1963
1954#ifdef WITH_OPENSSL
1955static void 1964static void
1956load_krl(const char *path, struct ssh_krl **krlp) 1965load_krl(const char *path, struct ssh_krl **krlp)
1957{ 1966{
1958 Buffer krlbuf; 1967 struct sshbuf *krlbuf;
1959 int fd; 1968 int r, fd;
1960 1969
1961 buffer_init(&krlbuf); 1970 if ((krlbuf = sshbuf_new()) == NULL)
1971 fatal("sshbuf_new failed");
1962 if ((fd = open(path, O_RDONLY)) == -1) 1972 if ((fd = open(path, O_RDONLY)) == -1)
1963 fatal("open %s: %s", path, strerror(errno)); 1973 fatal("open %s: %s", path, strerror(errno));
1964 if (!key_load_file(fd, path, &krlbuf)) 1974 if ((r = sshkey_load_file(fd, krlbuf)) != 0)
1965 fatal("Unable to load KRL"); 1975 fatal("Unable to load KRL: %s", ssh_err(r));
1966 close(fd); 1976 close(fd);
1967 /* XXX check sigs */ 1977 /* XXX check sigs */
1968 if (ssh_krl_from_blob(&krlbuf, krlp, NULL, 0) != 0 || 1978 if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 ||
1969 *krlp == NULL) 1979 *krlp == NULL)
1970 fatal("Invalid KRL file"); 1980 fatal("Invalid KRL file: %s", ssh_err(r));
1971 buffer_free(&krlbuf); 1981 sshbuf_free(krlbuf);
1972} 1982}
1973 1983
1974static void 1984static void
1975update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, 1985update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
1976 struct ssh_krl *krl) 1986 const struct sshkey *ca, struct ssh_krl *krl)
1977{ 1987{
1978 Key *key = NULL; 1988 struct sshkey *key = NULL;
1979 u_long lnum = 0; 1989 u_long lnum = 0;
1980 char *path, *cp, *ep, line[SSH_MAX_PUBKEY_BYTES]; 1990 char *path, *cp, *ep, line[SSH_MAX_PUBKEY_BYTES];
1981 unsigned long long serial, serial2; 1991 unsigned long long serial, serial2;
@@ -2014,7 +2024,7 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca,
2014 if (*cp == '\0') 2024 if (*cp == '\0')
2015 continue; 2025 continue;
2016 if (strncasecmp(cp, "serial:", 7) == 0) { 2026 if (strncasecmp(cp, "serial:", 7) == 0) {
2017 if (ca == NULL) { 2027 if (ca == NULL && !wild_ca) {
2018 fatal("revoking certificates by serial number " 2028 fatal("revoking certificates by serial number "
2019 "requires specification of a CA key"); 2029 "requires specification of a CA key");
2020 } 2030 }
@@ -2051,7 +2061,7 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca,
2051 __func__); 2061 __func__);
2052 } 2062 }
2053 } else if (strncasecmp(cp, "id:", 3) == 0) { 2063 } else if (strncasecmp(cp, "id:", 3) == 0) {
2054 if (ca == NULL) { 2064 if (ca == NULL && !wild_ca) {
2055 fatal("revoking certificates by key ID " 2065 fatal("revoking certificates by key ID "
2056 "requires specification of a CA key"); 2066 "requires specification of a CA key");
2057 } 2067 }
@@ -2074,10 +2084,11 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca,
2074 * Parsing will fail if it isn't. 2084 * Parsing will fail if it isn't.
2075 */ 2085 */
2076 } 2086 }
2077 if ((key = key_new(KEY_UNSPEC)) == NULL) 2087 if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
2078 fatal("key_new"); 2088 fatal("key_new");
2079 if (key_read(key, &cp) != 1) 2089 if ((r = sshkey_read(key, &cp)) != 0)
2080 fatal("%s:%lu: invalid key", path, lnum); 2090 fatal("%s:%lu: invalid key: %s",
2091 path, lnum, ssh_err(r));
2081 if (was_explicit_key) 2092 if (was_explicit_key)
2082 r = ssh_krl_revoke_key_explicit(krl, key); 2093 r = ssh_krl_revoke_key_explicit(krl, key);
2083 else if (was_sha1) 2094 else if (was_sha1)
@@ -2085,8 +2096,9 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca,
2085 else 2096 else
2086 r = ssh_krl_revoke_key(krl, key); 2097 r = ssh_krl_revoke_key(krl, key);
2087 if (r != 0) 2098 if (r != 0)
2088 fatal("%s: revoke key failed", __func__); 2099 fatal("%s: revoke key failed: %s",
2089 key_free(key); 2100 __func__, ssh_err(r));
2101 sshkey_free(key);
2090 } 2102 }
2091 } 2103 }
2092 if (strcmp(path, "-") != 0) 2104 if (strcmp(path, "-") != 0)
@@ -2099,10 +2111,10 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
2099{ 2111{
2100 struct ssh_krl *krl; 2112 struct ssh_krl *krl;
2101 struct stat sb; 2113 struct stat sb;
2102 Key *ca = NULL; 2114 struct sshkey *ca = NULL;
2103 int fd, i; 2115 int fd, i, r, wild_ca = 0;
2104 char *tmp; 2116 char *tmp;
2105 Buffer kbuf; 2117 struct sshbuf *kbuf;
2106 2118
2107 if (*identity_file == '\0') 2119 if (*identity_file == '\0')
2108 fatal("KRL generation requires an output file"); 2120 fatal("KRL generation requires an output file");
@@ -2114,10 +2126,15 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
2114 fatal("KRL \"%s\" does not exist", identity_file); 2126 fatal("KRL \"%s\" does not exist", identity_file);
2115 } 2127 }
2116 if (ca_key_path != NULL) { 2128 if (ca_key_path != NULL) {
2117 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); 2129 if (strcasecmp(ca_key_path, "none") == 0)
2118 if ((ca = key_load_public(tmp, NULL)) == NULL) 2130 wild_ca = 1;
2119 fatal("Cannot load CA public key %s", tmp); 2131 else {
2120 free(tmp); 2132 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
2133 if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
2134 fatal("Cannot load CA public key %s: %s",
2135 tmp, ssh_err(r));
2136 free(tmp);
2137 }
2121 } 2138 }
2122 2139
2123 if (updating) 2140 if (updating)
@@ -2131,21 +2148,22 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
2131 ssh_krl_set_comment(krl, identity_comment); 2148 ssh_krl_set_comment(krl, identity_comment);
2132 2149
2133 for (i = 0; i < argc; i++) 2150 for (i = 0; i < argc; i++)
2134 update_krl_from_file(pw, argv[i], ca, krl); 2151 update_krl_from_file(pw, argv[i], wild_ca, ca, krl);
2135 2152
2136 buffer_init(&kbuf); 2153 if ((kbuf = sshbuf_new()) == NULL)
2137 if (ssh_krl_to_blob(krl, &kbuf, NULL, 0) != 0) 2154 fatal("sshbuf_new failed");
2155 if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0)
2138 fatal("Couldn't generate KRL"); 2156 fatal("Couldn't generate KRL");
2139 if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) 2157 if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
2140 fatal("open %s: %s", identity_file, strerror(errno)); 2158 fatal("open %s: %s", identity_file, strerror(errno));
2141 if (atomicio(vwrite, fd, buffer_ptr(&kbuf), buffer_len(&kbuf)) != 2159 if (atomicio(vwrite, fd, (void *)sshbuf_ptr(kbuf), sshbuf_len(kbuf)) !=
2142 buffer_len(&kbuf)) 2160 sshbuf_len(kbuf))
2143 fatal("write %s: %s", identity_file, strerror(errno)); 2161 fatal("write %s: %s", identity_file, strerror(errno));
2144 close(fd); 2162 close(fd);
2145 buffer_free(&kbuf); 2163 sshbuf_free(kbuf);
2146 ssh_krl_free(krl); 2164 ssh_krl_free(krl);
2147 if (ca != NULL) 2165 if (ca != NULL)
2148 key_free(ca); 2166 sshkey_free(ca);
2149} 2167}
2150 2168
2151static void 2169static void
@@ -2154,27 +2172,27 @@ do_check_krl(struct passwd *pw, int argc, char **argv)
2154 int i, r, ret = 0; 2172 int i, r, ret = 0;
2155 char *comment; 2173 char *comment;
2156 struct ssh_krl *krl; 2174 struct ssh_krl *krl;
2157 Key *k; 2175 struct sshkey *k;
2158 2176
2159 if (*identity_file == '\0') 2177 if (*identity_file == '\0')
2160 fatal("KRL checking requires an input file"); 2178 fatal("KRL checking requires an input file");
2161 load_krl(identity_file, &krl); 2179 load_krl(identity_file, &krl);
2162 for (i = 0; i < argc; i++) { 2180 for (i = 0; i < argc; i++) {
2163 if ((k = key_load_public(argv[i], &comment)) == NULL) 2181 if ((r = sshkey_load_public(argv[i], &k, &comment)) != 0)
2164 fatal("Cannot load public key %s", argv[i]); 2182 fatal("Cannot load public key %s: %s",
2183 argv[i], ssh_err(r));
2165 r = ssh_krl_check_key(krl, k); 2184 r = ssh_krl_check_key(krl, k);
2166 printf("%s%s%s%s: %s\n", argv[i], 2185 printf("%s%s%s%s: %s\n", argv[i],
2167 *comment ? " (" : "", comment, *comment ? ")" : "", 2186 *comment ? " (" : "", comment, *comment ? ")" : "",
2168 r == 0 ? "ok" : "REVOKED"); 2187 r == 0 ? "ok" : "REVOKED");
2169 if (r != 0) 2188 if (r != 0)
2170 ret = 1; 2189 ret = 1;
2171 key_free(k); 2190 sshkey_free(k);
2172 free(comment); 2191 free(comment);
2173 } 2192 }
2174 ssh_krl_free(krl); 2193 ssh_krl_free(krl);
2175 exit(ret); 2194 exit(ret);
2176} 2195}
2177#endif
2178 2196
2179static void 2197static void
2180usage(void) 2198usage(void)
@@ -2187,7 +2205,7 @@ usage(void)
2187 " ssh-keygen -e [-m key_format] [-f input_keyfile]\n" 2205 " ssh-keygen -e [-m key_format] [-f input_keyfile]\n"
2188 " ssh-keygen -y [-f input_keyfile]\n" 2206 " ssh-keygen -y [-f input_keyfile]\n"
2189 " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n" 2207 " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n"
2190 " ssh-keygen -l [-f input_keyfile]\n" 2208 " ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n"
2191 " ssh-keygen -B [-f input_keyfile]\n"); 2209 " ssh-keygen -B [-f input_keyfile]\n");
2192#ifdef ENABLE_PKCS11 2210#ifdef ENABLE_PKCS11
2193 fprintf(stderr, 2211 fprintf(stderr,
@@ -2217,13 +2235,13 @@ usage(void)
2217int 2235int
2218main(int argc, char **argv) 2236main(int argc, char **argv)
2219{ 2237{
2220 char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; 2238 char dotsshdir[PATH_MAX], comment[1024], *passphrase1, *passphrase2;
2221 char *checkpoint = NULL; 2239 char *checkpoint = NULL;
2222 char out_file[MAXPATHLEN], *ep, *rr_hostname = NULL; 2240 char out_file[PATH_MAX], *rr_hostname = NULL, *ep, *fp, *ra;
2223 Key *private, *public; 2241 struct sshkey *private, *public;
2224 struct passwd *pw; 2242 struct passwd *pw;
2225 struct stat st; 2243 struct stat st;
2226 int opt, type, fd; 2244 int r, opt, type, fd;
2227 u_int32_t memory = 0, generator_wanted = 0; 2245 u_int32_t memory = 0, generator_wanted = 0;
2228 int do_gen_candidates = 0, do_screen_candidates = 0; 2246 int do_gen_candidates = 0, do_screen_candidates = 0;
2229 int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; 2247 int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
@@ -2240,7 +2258,9 @@ main(int argc, char **argv)
2240 2258
2241 __progname = ssh_get_progname(argv[0]); 2259 __progname = ssh_get_progname(argv[0]);
2242 2260
2261#ifdef WITH_OPENSSL
2243 OpenSSL_add_all_algorithms(); 2262 OpenSSL_add_all_algorithms();
2263#endif
2244 log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); 2264 log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
2245 2265
2246 seed_rng(); 2266 seed_rng();
@@ -2256,9 +2276,10 @@ main(int argc, char **argv)
2256 exit(1); 2276 exit(1);
2257 } 2277 }
2258 2278
2259 /* Remaining characters: EUYdw */ 2279 /* Remaining characters: UYdw */
2260 while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy" 2280 while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy"
2261 "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:a:b:f:g:j:m:n:r:s:t:z:")) != -1) { 2281 "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:"
2282 "a:b:f:g:j:m:n:r:s:t:z:")) != -1) {
2262 switch (opt) { 2283 switch (opt) {
2263 case 'A': 2284 case 'A':
2264 gen_all_hostkeys = 1; 2285 gen_all_hostkeys = 1;
@@ -2269,6 +2290,11 @@ main(int argc, char **argv)
2269 fatal("Bits has bad value %s (%s)", 2290 fatal("Bits has bad value %s (%s)",
2270 optarg, errstr); 2291 optarg, errstr);
2271 break; 2292 break;
2293 case 'E':
2294 fingerprint_hash = ssh_digest_alg_by_name(optarg);
2295 if (fingerprint_hash == -1)
2296 fatal("Invalid hash algorithm \"%s\"", optarg);
2297 break;
2272 case 'F': 2298 case 'F':
2273 find_host = 1; 2299 find_host = 1;
2274 rr_hostname = optarg; 2300 rr_hostname = optarg;
@@ -2412,6 +2438,7 @@ main(int argc, char **argv)
2412 fatal("Invalid number: %s (%s)", 2438 fatal("Invalid number: %s (%s)",
2413 optarg, errstr); 2439 optarg, errstr);
2414 break; 2440 break;
2441#ifdef WITH_OPENSSL
2415 case 'M': 2442 case 'M':
2416 memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); 2443 memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
2417 if (errstr) 2444 if (errstr)
@@ -2430,7 +2457,7 @@ main(int argc, char **argv)
2430 fatal("Output filename too long"); 2457 fatal("Output filename too long");
2431 break; 2458 break;
2432 case 'K': 2459 case 'K':
2433 if (strlen(optarg) >= MAXPATHLEN) 2460 if (strlen(optarg) >= PATH_MAX)
2434 fatal("Checkpoint filename too long"); 2461 fatal("Checkpoint filename too long");
2435 checkpoint = xstrdup(optarg); 2462 checkpoint = xstrdup(optarg);
2436 break; 2463 break;
@@ -2439,6 +2466,7 @@ main(int argc, char **argv)
2439 if (BN_hex2bn(&start, optarg) == 0) 2466 if (BN_hex2bn(&start, optarg) == 0)
2440 fatal("Invalid start point."); 2467 fatal("Invalid start point.");
2441 break; 2468 break;
2469#endif /* WITH_OPENSSL */
2442 case 'V': 2470 case 'V':
2443 parse_cert_times(optarg); 2471 parse_cert_times(optarg);
2444 break; 2472 break;
@@ -2478,7 +2506,6 @@ main(int argc, char **argv)
2478 printf("Cannot use -l with -H or -R.\n"); 2506 printf("Cannot use -l with -H or -R.\n");
2479 usage(); 2507 usage();
2480 } 2508 }
2481#ifdef WITH_OPENSSL
2482 if (gen_krl) { 2509 if (gen_krl) {
2483 do_gen_krl(pw, update_krl, argc, argv); 2510 do_gen_krl(pw, update_krl, argc, argv);
2484 return (0); 2511 return (0);
@@ -2487,7 +2514,6 @@ main(int argc, char **argv)
2487 do_check_krl(pw, argc, argv); 2514 do_check_krl(pw, argc, argv);
2488 return (0); 2515 return (0);
2489 } 2516 }
2490#endif
2491 if (ca_key_path != NULL) { 2517 if (ca_key_path != NULL) {
2492 if (cert_key_id == NULL) 2518 if (cert_key_id == NULL)
2493 fatal("Must specify key id (-I) when certifying"); 2519 fatal("Must specify key id (-I) when certifying");
@@ -2588,17 +2614,20 @@ main(int argc, char **argv)
2588 if (key_type_name == NULL) 2614 if (key_type_name == NULL)
2589 key_type_name = "rsa"; 2615 key_type_name = "rsa";
2590 2616
2591 type = key_type_from_name(key_type_name); 2617 type = sshkey_type_from_name(key_type_name);
2592 type_bits_valid(type, &bits); 2618 type_bits_valid(type, key_type_name, &bits);
2593 2619
2594 if (!quiet) 2620 if (!quiet)
2595 printf("Generating public/private %s key pair.\n", key_type_name); 2621 printf("Generating public/private %s key pair.\n",
2596 private = key_generate(type, bits); 2622 key_type_name);
2597 if (private == NULL) { 2623 if ((r = sshkey_generate(type, bits, &private)) != 0) {
2598 fprintf(stderr, "key_generate failed\n"); 2624 fprintf(stderr, "key_generate failed\n");
2599 exit(1); 2625 exit(1);
2600 } 2626 }
2601 public = key_from_private(private); 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 }
2602 2631
2603 if (!have_identity) 2632 if (!have_identity)
2604 ask_filename(pw, "Enter file in which to save the key"); 2633 ask_filename(pw, "Enter file in which to save the key");
@@ -2666,9 +2695,10 @@ passphrase_again:
2666 } 2695 }
2667 2696
2668 /* Save the key with the given passphrase and comment. */ 2697 /* Save the key with the given passphrase and comment. */
2669 if (!key_save_private(private, identity_file, passphrase1, comment, 2698 if ((r = sshkey_save_private(private, identity_file, passphrase1,
2670 use_new_format, new_format_cipher, rounds)) { 2699 comment, use_new_format, new_format_cipher, rounds)) != 0) {
2671 printf("Saving the key failed: %s.\n", identity_file); 2700 printf("Saving key \"%s\" failed: %s\n",
2701 identity_file, ssh_err(r));
2672 explicit_bzero(passphrase1, strlen(passphrase1)); 2702 explicit_bzero(passphrase1, strlen(passphrase1));
2673 free(passphrase1); 2703 free(passphrase1);
2674 exit(1); 2704 exit(1);
@@ -2678,7 +2708,7 @@ passphrase_again:
2678 free(passphrase1); 2708 free(passphrase1);
2679 2709
2680 /* Clear the private key and the random number generator. */ 2710 /* Clear the private key and the random number generator. */
2681 key_free(private); 2711 sshkey_free(private);
2682 2712
2683 if (!quiet) 2713 if (!quiet)
2684 printf("Your identification has been saved in %s.\n", identity_file); 2714 printf("Your identification has been saved in %s.\n", identity_file);
@@ -2694,15 +2724,18 @@ passphrase_again:
2694 printf("fdopen %s failed\n", identity_file); 2724 printf("fdopen %s failed\n", identity_file);
2695 exit(1); 2725 exit(1);
2696 } 2726 }
2697 if (!key_write(public, f)) 2727 if ((r = sshkey_write(public, f)) != 0)
2698 fprintf(stderr, "write key failed\n"); 2728 fprintf(stderr, "write key failed: %s\n", ssh_err(r));
2699 fprintf(f, " %s\n", comment); 2729 fprintf(f, " %s\n", comment);
2700 fclose(f); 2730 fclose(f);
2701 2731
2702 if (!quiet) { 2732 if (!quiet) {
2703 char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); 2733 fp = sshkey_fingerprint(public, fingerprint_hash,
2704 char *ra = key_fingerprint(public, SSH_FP_MD5, 2734 SSH_FP_DEFAULT);
2735 ra = sshkey_fingerprint(public, fingerprint_hash,
2705 SSH_FP_RANDOMART); 2736 SSH_FP_RANDOMART);
2737 if (fp == NULL || ra == NULL)
2738 fatal("sshkey_fingerprint failed");
2706 printf("Your public key has been saved in %s.\n", 2739 printf("Your public key has been saved in %s.\n",
2707 identity_file); 2740 identity_file);
2708 printf("The key fingerprint is:\n"); 2741 printf("The key fingerprint is:\n");
@@ -2713,6 +2746,6 @@ passphrase_again:
2713 free(fp); 2746 free(fp);
2714 } 2747 }
2715 2748
2716 key_free(public); 2749 sshkey_free(public);
2717 exit(0); 2750 exit(0);
2718} 2751}