Annotation of src/usr.bin/ssh/ssh-keygen.c, Revision 1.228
1.228 ! djm 1: /* $OpenBSD: ssh-keygen.c,v 1.227 2013/05/17 00:13:14 djm Exp $ */
1.1 deraadt 2: /*
1.13 deraadt 3: * Author: Tatu Ylonen <ylo@cs.hut.fi>
4: * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5: * All rights reserved
6: * Identity and host key generation and maintenance.
1.31 deraadt 7: *
8: * As far as I am concerned, the code I have written for this software
9: * can be used freely for any purpose. Any derived versions of this
10: * software must be clearly marked as such, and if the derived work is
11: * incompatible with the protocol description in the RFC file, it must be
12: * called by a name other than "ssh" or "Secure Shell".
1.13 deraadt 13: */
1.1 deraadt 14:
1.136 stevesk 15: #include <sys/types.h>
1.174 dtucker 16: #include <sys/socket.h>
1.136 stevesk 17: #include <sys/stat.h>
1.151 stevesk 18: #include <sys/param.h>
1.19 markus 19:
20: #include <openssl/evp.h>
21: #include <openssl/pem.h>
1.145 stevesk 22:
1.148 stevesk 23: #include <errno.h>
1.147 stevesk 24: #include <fcntl.h>
1.145 stevesk 25: #include <pwd.h>
1.153 stevesk 26: #include <stdio.h>
1.152 stevesk 27: #include <stdlib.h>
1.150 stevesk 28: #include <string.h>
1.149 stevesk 29: #include <unistd.h>
1.1 deraadt 30:
31: #include "xmalloc.h"
1.19 markus 32: #include "key.h"
1.53 markus 33: #include "rsa.h"
1.19 markus 34: #include "authfile.h"
35: #include "uuencode.h"
1.32 markus 36: #include "buffer.h"
1.40 markus 37: #include "pathnames.h"
1.41 markus 38: #include "log.h"
1.114 djm 39: #include "misc.h"
1.119 djm 40: #include "match.h"
41: #include "hostfile.h"
1.146 stevesk 42: #include "dns.h"
1.223 djm 43: #include "ssh.h"
1.179 djm 44: #include "ssh2.h"
1.223 djm 45: #include "atomicio.h"
46: #include "krl.h"
1.32 markus 47:
1.177 markus 48: #ifdef ENABLE_PKCS11
49: #include "ssh-pkcs11.h"
1.106 djm 50: #endif
1.66 markus 51:
1.130 markus 52: /* Number of bits in the RSA/DSA key. This value can be set on the command line. */
53: #define DEFAULT_BITS 2048
54: #define DEFAULT_BITS_DSA 1024
1.203 naddy 55: #define DEFAULT_BITS_ECDSA 256
1.130 markus 56: u_int32_t bits = 0;
1.1 deraadt 57:
1.14 markus 58: /*
59: * Flag indicating that we just want to change the passphrase. This can be
60: * set on the command line.
61: */
1.1 deraadt 62: int change_passphrase = 0;
63:
1.14 markus 64: /*
65: * Flag indicating that we just want to change the comment. This can be set
66: * on the command line.
67: */
1.1 deraadt 68: int change_comment = 0;
69:
1.2 provos 70: int quiet = 0;
71:
1.169 grunk 72: int log_level = SYSLOG_LEVEL_INFO;
73:
1.119 djm 74: /* Flag indicating that we want to hash a known_hosts file */
75: int hash_hosts = 0;
76: /* Flag indicating that we want lookup a host in known_hosts file */
77: int find_host = 0;
78: /* Flag indicating that we want to delete a host from a known_hosts file */
79: int delete_host = 0;
80:
1.182 djm 81: /* Flag indicating that we want to show the contents of a certificate */
82: int show_cert = 0;
83:
1.8 markus 84: /* Flag indicating that we just want to see the key fingerprint */
85: int print_fingerprint = 0;
1.49 markus 86: int print_bubblebabble = 0;
1.8 markus 87:
1.10 markus 88: /* The identity file name, given on the command line or entered by the user. */
89: char identity_file[1024];
90: int have_identity = 0;
1.1 deraadt 91:
92: /* This is set to the passphrase if given on the command line. */
93: char *identity_passphrase = NULL;
94:
95: /* This is set to the new passphrase if given on the command line. */
96: char *identity_new_passphrase = NULL;
97:
98: /* This is set to the new comment if given on the command line. */
99: char *identity_comment = NULL;
100:
1.179 djm 101: /* Path to CA key when certifying keys. */
102: char *ca_key_path = NULL;
103:
1.186 djm 104: /* Certificate serial number */
1.220 djm 105: unsigned long long cert_serial = 0;
1.186 djm 106:
1.179 djm 107: /* Key type when certifying */
108: u_int cert_key_type = SSH2_CERT_TYPE_USER;
109:
110: /* "key ID" of signed key */
111: char *cert_key_id = NULL;
112:
113: /* Comma-separated list of principal names for certifying keys */
114: char *cert_principals = NULL;
115:
116: /* Validity period for certificates */
117: u_int64_t cert_valid_from = 0;
118: u_int64_t cert_valid_to = ~0ULL;
119:
1.186 djm 120: /* Certificate options */
1.190 djm 121: #define CERTOPT_X_FWD (1)
122: #define CERTOPT_AGENT_FWD (1<<1)
123: #define CERTOPT_PORT_FWD (1<<2)
124: #define CERTOPT_PTY (1<<3)
125: #define CERTOPT_USER_RC (1<<4)
126: #define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \
127: CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC)
128: u_int32_t certflags_flags = CERTOPT_DEFAULT;
129: char *certflags_command = NULL;
130: char *certflags_src_addr = NULL;
1.179 djm 131:
1.193 djm 132: /* Conversion to/from various formats */
133: int convert_to = 0;
134: int convert_from = 0;
135: enum {
136: FMT_RFC4716,
137: FMT_PKCS8,
138: FMT_PEM
139: } convert_format = FMT_RFC4716;
1.19 markus 140: int print_public = 0;
1.105 jakob 141: int print_generic = 0;
1.33 markus 142:
1.87 djm 143: char *key_type_name = NULL;
1.19 markus 144:
1.197 djm 145: /* Load key from this PKCS#11 provider */
146: char *pkcs11provider = NULL;
1.193 djm 147:
1.10 markus 148: /* argv0 */
149: extern char *__progname;
1.1 deraadt 150:
1.19 markus 151: char hostname[MAXHOSTNAMELEN];
152:
1.115 djm 153: /* moduli.c */
1.124 avsm 154: int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
1.215 dtucker 155: int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long,
156: unsigned long);
1.115 djm 157:
1.63 itojun 158: static void
1.209 djm 159: type_bits_valid(int type, u_int32_t *bitsp)
1.206 stevesk 160: {
161: u_int maxbits;
162:
163: if (type == KEY_UNSPEC) {
164: fprintf(stderr, "unknown key type %s\n", key_type_name);
165: exit(1);
166: }
1.209 djm 167: if (*bitsp == 0) {
1.206 stevesk 168: if (type == KEY_DSA)
1.209 djm 169: *bitsp = DEFAULT_BITS_DSA;
1.206 stevesk 170: else if (type == KEY_ECDSA)
1.209 djm 171: *bitsp = DEFAULT_BITS_ECDSA;
1.206 stevesk 172: else
1.209 djm 173: *bitsp = DEFAULT_BITS;
1.206 stevesk 174: }
175: maxbits = (type == KEY_DSA) ?
176: OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS;
1.209 djm 177: if (*bitsp > maxbits) {
1.206 stevesk 178: fprintf(stderr, "key bits exceeds maximum %d\n", maxbits);
179: exit(1);
180: }
1.209 djm 181: if (type == KEY_DSA && *bitsp != 1024)
1.206 stevesk 182: fatal("DSA keys must be 1024 bits");
1.209 djm 183: else if (type != KEY_ECDSA && *bitsp < 768)
1.206 stevesk 184: fatal("Key must at least be 768 bits");
1.209 djm 185: else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(*bitsp) == -1)
1.206 stevesk 186: fatal("Invalid ECDSA key length - valid lengths are "
187: "256, 384 or 521 bits");
188: }
189:
190: static void
1.10 markus 191: ask_filename(struct passwd *pw, const char *prompt)
1.1 deraadt 192: {
1.12 markus 193: char buf[1024];
1.35 markus 194: char *name = NULL;
195:
1.92 stevesk 196: if (key_type_name == NULL)
1.40 markus 197: name = _PATH_SSH_CLIENT_ID_RSA;
1.140 deraadt 198: else {
1.92 stevesk 199: switch (key_type_from_name(key_type_name)) {
200: case KEY_RSA1:
201: name = _PATH_SSH_CLIENT_IDENTITY;
202: break;
1.186 djm 203: case KEY_DSA_CERT:
204: case KEY_DSA_CERT_V00:
1.92 stevesk 205: case KEY_DSA:
206: name = _PATH_SSH_CLIENT_ID_DSA;
207: break;
1.200 djm 208: case KEY_ECDSA_CERT:
209: case KEY_ECDSA:
210: name = _PATH_SSH_CLIENT_ID_ECDSA;
211: break;
1.186 djm 212: case KEY_RSA_CERT:
213: case KEY_RSA_CERT_V00:
1.92 stevesk 214: case KEY_RSA:
215: name = _PATH_SSH_CLIENT_ID_RSA;
216: break;
217: default:
1.173 tobias 218: fprintf(stderr, "bad key type\n");
1.92 stevesk 219: exit(1);
220: break;
221: }
1.140 deraadt 222: }
1.35 markus 223: snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name);
1.37 markus 224: fprintf(stderr, "%s (%s): ", prompt, identity_file);
1.12 markus 225: if (fgets(buf, sizeof(buf), stdin) == NULL)
226: exit(1);
1.162 gilles 227: buf[strcspn(buf, "\n")] = '\0';
1.12 markus 228: if (strcmp(buf, "") != 0)
229: strlcpy(identity_file, buf, sizeof(identity_file));
230: have_identity = 1;
1.7 markus 231: }
232:
1.63 itojun 233: static Key *
1.61 markus 234: load_identity(char *filename)
1.19 markus 235: {
1.52 markus 236: char *pass;
237: Key *prv;
238:
1.55 markus 239: prv = key_load_private(filename, "", NULL);
1.52 markus 240: if (prv == NULL) {
1.61 markus 241: if (identity_passphrase)
242: pass = xstrdup(identity_passphrase);
243: else
1.65 markus 244: pass = read_passphrase("Enter passphrase: ",
245: RP_ALLOW_STDIN);
1.52 markus 246: prv = key_load_private(filename, pass, NULL);
1.19 markus 247: memset(pass, 0, strlen(pass));
1.227 djm 248: free(pass);
1.19 markus 249: }
1.52 markus 250: return prv;
1.19 markus 251: }
252:
1.32 markus 253: #define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----"
1.100 deraadt 254: #define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----"
1.32 markus 255: #define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
1.42 stevesk 256: #define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb
1.19 markus 257:
1.63 itojun 258: static void
1.193 djm 259: do_convert_to_ssh2(struct passwd *pw, Key *k)
1.19 markus 260: {
1.94 markus 261: u_int len;
1.36 markus 262: u_char *blob;
1.176 djm 263: char comment[61];
1.19 markus 264:
1.213 djm 265: if (k->type == KEY_RSA1) {
266: fprintf(stderr, "version 1 keys are not supported\n");
267: exit(1);
268: }
1.81 markus 269: if (key_to_blob(k, &blob, &len) <= 0) {
270: fprintf(stderr, "key_to_blob failed\n");
271: exit(1);
272: }
1.176 djm 273: /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
274: snprintf(comment, sizeof(comment),
275: "%u-bit %s, converted by %s@%s from OpenSSH",
1.59 markus 276: key_size(k), key_type(k),
1.19 markus 277: pw->pw_name, hostname);
1.176 djm 278:
279: fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
280: fprintf(stdout, "Comment: \"%s\"\n", comment);
1.19 markus 281: dump_base64(stdout, blob, len);
1.32 markus 282: fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
1.59 markus 283: key_free(k);
1.227 djm 284: free(blob);
1.19 markus 285: exit(0);
286: }
287:
1.63 itojun 288: static void
1.193 djm 289: do_convert_to_pkcs8(Key *k)
290: {
291: switch (key_type_plain(k->type)) {
1.213 djm 292: case KEY_RSA1:
1.193 djm 293: case KEY_RSA:
294: if (!PEM_write_RSA_PUBKEY(stdout, k->rsa))
295: fatal("PEM_write_RSA_PUBKEY failed");
296: break;
297: case KEY_DSA:
298: if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
299: fatal("PEM_write_DSA_PUBKEY failed");
300: break;
1.200 djm 301: case KEY_ECDSA:
302: if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
303: fatal("PEM_write_EC_PUBKEY failed");
304: break;
1.193 djm 305: default:
306: fatal("%s: unsupported key type %s", __func__, key_type(k));
307: }
308: exit(0);
309: }
310:
311: static void
312: do_convert_to_pem(Key *k)
313: {
314: switch (key_type_plain(k->type)) {
1.213 djm 315: case KEY_RSA1:
1.193 djm 316: case KEY_RSA:
317: if (!PEM_write_RSAPublicKey(stdout, k->rsa))
318: fatal("PEM_write_RSAPublicKey failed");
319: break;
320: #if notyet /* OpenSSH 0.9.8 lacks this function */
321: case KEY_DSA:
322: if (!PEM_write_DSAPublicKey(stdout, k->dsa))
323: fatal("PEM_write_DSAPublicKey failed");
324: break;
325: #endif
1.200 djm 326: /* XXX ECDSA? */
1.193 djm 327: default:
328: fatal("%s: unsupported key type %s", __func__, key_type(k));
329: }
330: exit(0);
331: }
332:
333: static void
334: do_convert_to(struct passwd *pw)
335: {
336: Key *k;
337: struct stat st;
338:
339: if (!have_identity)
340: ask_filename(pw, "Enter file in which the key is");
341: if (stat(identity_file, &st) < 0)
342: fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
343: if ((k = key_load_public(identity_file, NULL)) == NULL) {
344: if ((k = load_identity(identity_file)) == NULL) {
345: fprintf(stderr, "load failed\n");
346: exit(1);
347: }
348: }
349:
350: switch (convert_format) {
351: case FMT_RFC4716:
352: do_convert_to_ssh2(pw, k);
353: break;
354: case FMT_PKCS8:
355: do_convert_to_pkcs8(k);
356: break;
357: case FMT_PEM:
358: do_convert_to_pem(k);
359: break;
360: default:
361: fatal("%s: unknown key format %d", __func__, convert_format);
362: }
363: exit(0);
364: }
365:
366: static void
1.32 markus 367: buffer_get_bignum_bits(Buffer *b, BIGNUM *value)
368: {
1.116 avsm 369: u_int bignum_bits = buffer_get_int(b);
370: u_int bytes = (bignum_bits + 7) / 8;
1.53 markus 371:
1.32 markus 372: if (buffer_len(b) < bytes)
1.53 markus 373: fatal("buffer_get_bignum_bits: input buffer too small: "
374: "need %d have %d", bytes, buffer_len(b));
1.155 markus 375: if (BN_bin2bn(buffer_ptr(b), bytes, value) == NULL)
376: fatal("buffer_get_bignum_bits: BN_bin2bn failed");
1.32 markus 377: buffer_consume(b, bytes);
378: }
379:
1.63 itojun 380: static Key *
1.93 markus 381: do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
1.32 markus 382: {
383: Buffer b;
384: Key *key = NULL;
1.64 markus 385: char *type, *cipher;
1.69 stevesk 386: u_char *sig, data[] = "abcde12345";
1.62 markus 387: int magic, rlen, ktype, i1, i2, i3, i4;
1.64 markus 388: u_int slen;
1.62 markus 389: u_long e;
1.32 markus 390:
391: buffer_init(&b);
392: buffer_append(&b, blob, blen);
393:
1.160 stevesk 394: magic = buffer_get_int(&b);
1.32 markus 395: if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {
396: error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC);
397: buffer_free(&b);
398: return NULL;
399: }
1.62 markus 400: i1 = buffer_get_int(&b);
1.32 markus 401: type = buffer_get_string(&b, NULL);
402: cipher = buffer_get_string(&b, NULL);
1.62 markus 403: i2 = buffer_get_int(&b);
404: i3 = buffer_get_int(&b);
405: i4 = buffer_get_int(&b);
1.158 stevesk 406: debug("ignore (%d %d %d %d)", i1, i2, i3, i4);
1.32 markus 407: if (strcmp(cipher, "none") != 0) {
408: error("unsupported cipher %s", cipher);
1.227 djm 409: free(cipher);
1.32 markus 410: buffer_free(&b);
1.227 djm 411: free(type);
1.32 markus 412: return NULL;
413: }
1.227 djm 414: free(cipher);
1.32 markus 415:
1.53 markus 416: if (strstr(type, "dsa")) {
417: ktype = KEY_DSA;
418: } else if (strstr(type, "rsa")) {
419: ktype = KEY_RSA;
420: } else {
1.118 markus 421: buffer_free(&b);
1.227 djm 422: free(type);
1.32 markus 423: return NULL;
424: }
1.53 markus 425: key = key_new_private(ktype);
1.227 djm 426: free(type);
1.53 markus 427:
428: switch (key->type) {
429: case KEY_DSA:
430: buffer_get_bignum_bits(&b, key->dsa->p);
431: buffer_get_bignum_bits(&b, key->dsa->g);
432: buffer_get_bignum_bits(&b, key->dsa->q);
433: buffer_get_bignum_bits(&b, key->dsa->pub_key);
434: buffer_get_bignum_bits(&b, key->dsa->priv_key);
435: break;
436: case KEY_RSA:
1.160 stevesk 437: e = buffer_get_char(&b);
1.62 markus 438: debug("e %lx", e);
439: if (e < 30) {
440: e <<= 8;
441: e += buffer_get_char(&b);
442: debug("e %lx", e);
443: e <<= 8;
444: e += buffer_get_char(&b);
445: debug("e %lx", e);
446: }
447: if (!BN_set_word(key->rsa->e, e)) {
1.53 markus 448: buffer_free(&b);
449: key_free(key);
450: return NULL;
451: }
452: buffer_get_bignum_bits(&b, key->rsa->d);
453: buffer_get_bignum_bits(&b, key->rsa->n);
454: buffer_get_bignum_bits(&b, key->rsa->iqmp);
455: buffer_get_bignum_bits(&b, key->rsa->q);
456: buffer_get_bignum_bits(&b, key->rsa->p);
1.68 markus 457: rsa_generate_additional_parameters(key->rsa);
1.53 markus 458: break;
459: }
1.32 markus 460: rlen = buffer_len(&b);
1.85 deraadt 461: if (rlen != 0)
1.53 markus 462: error("do_convert_private_ssh2_from_blob: "
463: "remaining bytes in key blob %d", rlen);
1.32 markus 464: buffer_free(&b);
1.64 markus 465:
466: /* try the key */
467: key_sign(key, &sig, &slen, data, sizeof(data));
468: key_verify(key, sig, slen, data, sizeof(data));
1.227 djm 469: free(sig);
1.32 markus 470: return key;
471: }
472:
1.137 dtucker 473: static int
474: get_line(FILE *fp, char *line, size_t len)
475: {
476: int c;
477: size_t pos = 0;
478:
479: line[0] = '\0';
480: while ((c = fgetc(fp)) != EOF) {
481: if (pos >= len - 1) {
482: fprintf(stderr, "input line too long.\n");
483: exit(1);
484: }
1.140 deraadt 485: switch (c) {
1.137 dtucker 486: case '\r':
487: c = fgetc(fp);
488: if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) {
489: fprintf(stderr, "unget: %s\n", strerror(errno));
490: exit(1);
491: }
492: return pos;
493: case '\n':
494: return pos;
495: }
496: line[pos++] = c;
497: line[pos] = '\0';
498: }
1.157 stevesk 499: /* We reached EOF */
500: return -1;
1.137 dtucker 501: }
502:
1.63 itojun 503: static void
1.193 djm 504: do_convert_from_ssh2(struct passwd *pw, Key **k, int *private)
1.19 markus 505: {
506: int blen;
1.98 markus 507: u_int len;
1.137 dtucker 508: char line[1024];
1.80 stevesk 509: u_char blob[8096];
1.19 markus 510: char encoded[8096];
1.193 djm 511: int escaped = 0;
1.19 markus 512: FILE *fp;
513:
1.191 djm 514: if ((fp = fopen(identity_file, "r")) == NULL)
515: fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
1.19 markus 516: encoded[0] = '\0';
1.137 dtucker 517: while ((blen = get_line(fp, line, sizeof(line))) != -1) {
1.228 ! djm 518: if (blen > 0 && line[blen - 1] == '\\')
1.25 markus 519: escaped++;
1.19 markus 520: if (strncmp(line, "----", 4) == 0 ||
521: strstr(line, ": ") != NULL) {
1.32 markus 522: if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL)
1.193 djm 523: *private = 1;
1.64 markus 524: if (strstr(line, " END ") != NULL) {
525: break;
526: }
1.60 markus 527: /* fprintf(stderr, "ignore: %s", line); */
1.19 markus 528: continue;
529: }
1.25 markus 530: if (escaped) {
531: escaped--;
1.60 markus 532: /* fprintf(stderr, "escaped: %s", line); */
1.25 markus 533: continue;
1.19 markus 534: }
535: strlcat(encoded, line, sizeof(encoded));
536: }
1.98 markus 537: len = strlen(encoded);
538: if (((len % 4) == 3) &&
539: (encoded[len-1] == '=') &&
540: (encoded[len-2] == '=') &&
541: (encoded[len-3] == '='))
542: encoded[len-3] = '\0';
1.91 stevesk 543: blen = uudecode(encoded, blob, sizeof(blob));
1.19 markus 544: if (blen < 0) {
545: fprintf(stderr, "uudecode failed.\n");
546: exit(1);
547: }
1.193 djm 548: *k = *private ?
1.32 markus 549: do_convert_private_ssh2_from_blob(blob, blen) :
1.33 markus 550: key_from_blob(blob, blen);
1.193 djm 551: if (*k == NULL) {
1.32 markus 552: fprintf(stderr, "decode blob failed.\n");
553: exit(1);
554: }
1.193 djm 555: fclose(fp);
556: }
557:
558: static void
559: do_convert_from_pkcs8(Key **k, int *private)
560: {
561: EVP_PKEY *pubkey;
562: FILE *fp;
563:
564: if ((fp = fopen(identity_file, "r")) == NULL)
565: fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
566: if ((pubkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) {
567: fatal("%s: %s is not a recognised public key format", __func__,
568: identity_file);
569: }
570: fclose(fp);
571: switch (EVP_PKEY_type(pubkey->type)) {
572: case EVP_PKEY_RSA:
573: *k = key_new(KEY_UNSPEC);
574: (*k)->type = KEY_RSA;
575: (*k)->rsa = EVP_PKEY_get1_RSA(pubkey);
576: break;
577: case EVP_PKEY_DSA:
578: *k = key_new(KEY_UNSPEC);
579: (*k)->type = KEY_DSA;
580: (*k)->dsa = EVP_PKEY_get1_DSA(pubkey);
581: break;
1.200 djm 582: case EVP_PKEY_EC:
583: *k = key_new(KEY_UNSPEC);
584: (*k)->type = KEY_ECDSA;
585: (*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey);
1.204 djm 586: (*k)->ecdsa_nid = key_ecdsa_key_to_nid((*k)->ecdsa);
1.200 djm 587: break;
1.193 djm 588: default:
589: fatal("%s: unsupported pubkey type %d", __func__,
590: EVP_PKEY_type(pubkey->type));
591: }
592: EVP_PKEY_free(pubkey);
593: return;
594: }
595:
596: static void
597: do_convert_from_pem(Key **k, int *private)
598: {
599: FILE *fp;
600: RSA *rsa;
601: #ifdef notyet
602: DSA *dsa;
603: #endif
604:
605: if ((fp = fopen(identity_file, "r")) == NULL)
606: fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
607: if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) {
608: *k = key_new(KEY_UNSPEC);
609: (*k)->type = KEY_RSA;
610: (*k)->rsa = rsa;
611: fclose(fp);
612: return;
613: }
614: #if notyet /* OpenSSH 0.9.8 lacks this function */
615: rewind(fp);
616: if ((dsa = PEM_read_DSAPublicKey(fp, NULL, NULL, NULL)) != NULL) {
617: *k = key_new(KEY_UNSPEC);
618: (*k)->type = KEY_DSA;
619: (*k)->dsa = dsa;
620: fclose(fp);
621: return;
622: }
1.200 djm 623: /* XXX ECDSA */
1.193 djm 624: #endif
625: fatal("%s: unrecognised raw private key format", __func__);
626: }
627:
628: static void
629: do_convert_from(struct passwd *pw)
630: {
631: Key *k = NULL;
1.195 djm 632: int private = 0, ok = 0;
1.193 djm 633: struct stat st;
634:
635: if (!have_identity)
636: ask_filename(pw, "Enter file in which the key is");
637: if (stat(identity_file, &st) < 0)
638: fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
639:
640: switch (convert_format) {
641: case FMT_RFC4716:
642: do_convert_from_ssh2(pw, &k, &private);
643: break;
644: case FMT_PKCS8:
645: do_convert_from_pkcs8(&k, &private);
646: break;
647: case FMT_PEM:
648: do_convert_from_pem(&k, &private);
649: break;
650: default:
651: fatal("%s: unknown key format %d", __func__, convert_format);
652: }
653:
654: if (!private)
655: ok = key_write(k, stdout);
656: if (ok)
657: fprintf(stdout, "\n");
658: else {
659: switch (k->type) {
660: case KEY_DSA:
661: ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL,
662: NULL, 0, NULL, NULL);
663: break;
1.200 djm 664: case KEY_ECDSA:
665: ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL,
666: NULL, 0, NULL, NULL);
667: break;
1.193 djm 668: case KEY_RSA:
669: ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL,
670: NULL, 0, NULL, NULL);
671: break;
672: default:
673: fatal("%s: unsupported key type %s", __func__,
674: key_type(k));
675: }
676: }
677:
1.32 markus 678: if (!ok) {
1.173 tobias 679: fprintf(stderr, "key write failed\n");
1.32 markus 680: exit(1);
681: }
1.19 markus 682: key_free(k);
683: exit(0);
684: }
685:
1.63 itojun 686: static void
1.19 markus 687: do_print_public(struct passwd *pw)
688: {
1.52 markus 689: Key *prv;
1.19 markus 690: struct stat st;
691:
692: if (!have_identity)
693: ask_filename(pw, "Enter file in which the key is");
694: if (stat(identity_file, &st) < 0) {
695: perror(identity_file);
696: exit(1);
697: }
1.61 markus 698: prv = load_identity(identity_file);
1.52 markus 699: if (prv == NULL) {
1.19 markus 700: fprintf(stderr, "load failed\n");
701: exit(1);
702: }
1.52 markus 703: if (!key_write(prv, stdout))
1.19 markus 704: fprintf(stderr, "key_write failed");
1.52 markus 705: key_free(prv);
1.19 markus 706: fprintf(stdout, "\n");
707: exit(0);
708: }
709:
1.66 markus 710: static void
1.197 djm 711: do_download(struct passwd *pw)
1.75 markus 712: {
1.177 markus 713: #ifdef ENABLE_PKCS11
1.97 markus 714: Key **keys = NULL;
1.177 markus 715: int i, nkeys;
1.221 djm 716: enum fp_rep rep;
717: enum fp_type fptype;
718: char *fp, *ra;
1.222 djm 719:
720: fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
721: rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
1.75 markus 722:
1.177 markus 723: pkcs11_init(0);
724: nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys);
725: if (nkeys <= 0)
726: fatal("cannot read public key from pkcs11");
727: for (i = 0; i < nkeys; i++) {
1.221 djm 728: if (print_fingerprint) {
729: fp = key_fingerprint(keys[i], fptype, rep);
730: ra = key_fingerprint(keys[i], SSH_FP_MD5,
731: SSH_FP_RANDOMART);
732: printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]),
733: fp, key_type(keys[i]));
734: if (log_level >= SYSLOG_LEVEL_VERBOSE)
735: printf("%s\n", ra);
1.227 djm 736: free(ra);
737: free(fp);
1.221 djm 738: } else {
739: key_write(keys[i], stdout);
740: fprintf(stdout, "\n");
741: }
1.97 markus 742: key_free(keys[i]);
743: }
1.227 djm 744: free(keys);
1.177 markus 745: pkcs11_terminate();
1.75 markus 746: exit(0);
1.177 markus 747: #else
748: fatal("no pkcs11 support");
749: #endif /* ENABLE_PKCS11 */
1.75 markus 750: }
1.66 markus 751:
1.63 itojun 752: static void
1.8 markus 753: do_fingerprint(struct passwd *pw)
754: {
1.15 markus 755: FILE *f;
1.19 markus 756: Key *public;
1.167 grunk 757: char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;
1.165 djm 758: int i, skip = 0, num = 0, invalid = 1;
1.84 stevesk 759: enum fp_rep rep;
760: enum fp_type fptype;
1.12 markus 761: struct stat st;
762:
1.52 markus 763: fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
764: rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
1.49 markus 765:
1.12 markus 766: if (!have_identity)
767: ask_filename(pw, "Enter file in which the key is");
768: if (stat(identity_file, &st) < 0) {
769: perror(identity_file);
770: exit(1);
771: }
1.52 markus 772: public = key_load_public(identity_file, &comment);
773: if (public != NULL) {
774: fp = key_fingerprint(public, fptype, rep);
1.175 djm 775: ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
1.170 grunk 776: printf("%u %s %s (%s)\n", key_size(public), fp, comment,
777: key_type(public));
1.169 grunk 778: if (log_level >= SYSLOG_LEVEL_VERBOSE)
779: printf("%s\n", ra);
1.33 markus 780: key_free(public);
1.227 djm 781: free(comment);
782: free(ra);
783: free(fp);
1.15 markus 784: exit(0);
785: }
1.144 markus 786: if (comment) {
1.227 djm 787: free(comment);
1.144 markus 788: comment = NULL;
789: }
1.15 markus 790:
1.191 djm 791: if ((f = fopen(identity_file, "r")) == NULL)
792: fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
793:
794: while (fgets(line, sizeof(line), f)) {
795: if ((cp = strchr(line, '\n')) == NULL) {
796: error("line %d too long: %.40s...",
797: num + 1, line);
798: skip = 1;
799: continue;
800: }
801: num++;
802: if (skip) {
803: skip = 0;
804: continue;
805: }
806: *cp = '\0';
807:
808: /* Skip leading whitespace, empty and comment lines. */
809: for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
810: ;
811: if (!*cp || *cp == '\n' || *cp == '#')
812: continue;
813: i = strtol(cp, &ep, 10);
814: if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {
815: int quoted = 0;
816: comment = cp;
817: for (; *cp && (quoted || (*cp != ' ' &&
818: *cp != '\t')); cp++) {
819: if (*cp == '\\' && cp[1] == '"')
820: cp++; /* Skip both */
821: else if (*cp == '"')
822: quoted = !quoted;
1.15 markus 823: }
1.191 djm 824: if (!*cp)
1.15 markus 825: continue;
1.191 djm 826: *cp++ = '\0';
827: }
828: ep = cp;
829: public = key_new(KEY_RSA1);
830: if (key_read(public, &cp) != 1) {
831: cp = ep;
832: key_free(public);
833: public = key_new(KEY_UNSPEC);
1.38 markus 834: if (key_read(public, &cp) != 1) {
835: key_free(public);
1.191 djm 836: continue;
1.12 markus 837: }
838: }
1.191 djm 839: comment = *cp ? cp : comment;
840: fp = key_fingerprint(public, fptype, rep);
841: ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
842: printf("%u %s %s (%s)\n", key_size(public), fp,
843: comment ? comment : "no comment", key_type(public));
844: if (log_level >= SYSLOG_LEVEL_VERBOSE)
845: printf("%s\n", ra);
1.227 djm 846: free(ra);
847: free(fp);
1.191 djm 848: key_free(public);
849: invalid = 0;
1.15 markus 850: }
1.191 djm 851: fclose(f);
852:
1.15 markus 853: if (invalid) {
1.83 markus 854: printf("%s is not a public key file.\n", identity_file);
1.15 markus 855: exit(1);
1.12 markus 856: }
857: exit(0);
1.8 markus 858: }
859:
1.119 djm 860: static void
1.206 stevesk 861: do_gen_all_hostkeys(struct passwd *pw)
862: {
863: struct {
864: char *key_type;
865: char *key_type_display;
866: char *path;
867: } key_types[] = {
868: { "rsa1", "RSA1", _PATH_HOST_KEY_FILE },
869: { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE },
870: { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE },
871: { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE },
872: { NULL, NULL, NULL }
873: };
874:
875: int first = 0;
876: struct stat st;
877: Key *private, *public;
878: char comment[1024];
879: int i, type, fd;
880: FILE *f;
881:
882: for (i = 0; key_types[i].key_type; i++) {
883: if (stat(key_types[i].path, &st) == 0)
884: continue;
885: if (errno != ENOENT) {
886: printf("Could not stat %s: %s", key_types[i].path,
887: strerror(errno));
888: first = 0;
889: continue;
890: }
891:
892: if (first == 0) {
893: first = 1;
894: printf("%s: generating new host keys: ", __progname);
895: }
896: printf("%s ", key_types[i].key_type_display);
897: fflush(stdout);
898: arc4random_stir();
899: type = key_type_from_name(key_types[i].key_type);
900: strlcpy(identity_file, key_types[i].path, sizeof(identity_file));
901: bits = 0;
902: type_bits_valid(type, &bits);
903: private = key_generate(type, bits);
904: if (private == NULL) {
905: fprintf(stderr, "key_generate failed\n");
906: first = 0;
907: continue;
908: }
909: public = key_from_private(private);
910: snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
911: hostname);
912: if (!key_save_private(private, identity_file, "", comment)) {
913: printf("Saving the key failed: %s.\n", identity_file);
914: key_free(private);
915: key_free(public);
916: first = 0;
917: continue;
918: }
919: key_free(private);
920: arc4random_stir();
921: strlcat(identity_file, ".pub", sizeof(identity_file));
922: fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
923: if (fd == -1) {
924: printf("Could not save your public key in %s\n",
925: identity_file);
926: key_free(public);
927: first = 0;
928: continue;
929: }
930: f = fdopen(fd, "w");
931: if (f == NULL) {
932: printf("fdopen %s failed\n", identity_file);
933: key_free(public);
934: first = 0;
935: continue;
936: }
937: if (!key_write(public, f)) {
938: fprintf(stderr, "write key failed\n");
939: key_free(public);
940: first = 0;
941: continue;
942: }
943: fprintf(f, " %s\n", comment);
944: fclose(f);
945: key_free(public);
946:
947: }
948: if (first != 0)
949: printf("\n");
950: }
951:
952: static void
1.179 djm 953: printhost(FILE *f, const char *name, Key *public, int ca, int hash)
1.119 djm 954: {
1.166 djm 955: if (print_fingerprint) {
956: enum fp_rep rep;
957: enum fp_type fptype;
1.167 grunk 958: char *fp, *ra;
1.166 djm 959:
960: fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
961: rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
962: fp = key_fingerprint(public, fptype, rep);
1.175 djm 963: ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
1.171 sthen 964: printf("%u %s %s (%s)\n", key_size(public), fp, name,
965: key_type(public));
966: if (log_level >= SYSLOG_LEVEL_VERBOSE)
967: printf("%s\n", ra);
1.227 djm 968: free(ra);
969: free(fp);
1.166 djm 970: } else {
971: if (hash && (name = host_hash(name, NULL, 0)) == NULL)
972: fatal("hash_host failed");
1.179 djm 973: fprintf(f, "%s%s%s ", ca ? CA_MARKER : "", ca ? " " : "", name);
1.166 djm 974: if (!key_write(public, f))
975: fatal("key_write failed");
976: fprintf(f, "\n");
977: }
1.119 djm 978: }
979:
980: static void
981: do_known_hosts(struct passwd *pw, const char *name)
982: {
983: FILE *in, *out = stdout;
1.179 djm 984: Key *pub;
1.119 djm 985: char *cp, *cp2, *kp, *kp2;
986: char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN];
1.165 djm 987: int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0;
1.179 djm 988: int ca;
1.119 djm 989:
990: if (!have_identity) {
991: cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
992: if (strlcpy(identity_file, cp, sizeof(identity_file)) >=
993: sizeof(identity_file))
994: fatal("Specified known hosts path too long");
1.227 djm 995: free(cp);
1.119 djm 996: have_identity = 1;
997: }
998: if ((in = fopen(identity_file, "r")) == NULL)
1.191 djm 999: fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
1.119 djm 1000:
1001: /*
1002: * Find hosts goes to stdout, hash and deletions happen in-place
1003: * A corner case is ssh-keygen -HF foo, which should go to stdout
1004: */
1005: if (!find_host && (hash_hosts || delete_host)) {
1006: if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp) ||
1007: strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp) ||
1008: strlcpy(old, identity_file, sizeof(old)) >= sizeof(old) ||
1009: strlcat(old, ".old", sizeof(old)) >= sizeof(old))
1010: fatal("known_hosts path too long");
1011: umask(077);
1012: if ((c = mkstemp(tmp)) == -1)
1013: fatal("mkstemp: %s", strerror(errno));
1014: if ((out = fdopen(c, "w")) == NULL) {
1015: c = errno;
1016: unlink(tmp);
1017: fatal("fdopen: %s", strerror(c));
1018: }
1019: inplace = 1;
1020: }
1021:
1022: while (fgets(line, sizeof(line), in)) {
1.163 chl 1023: if ((cp = strchr(line, '\n')) == NULL) {
1.165 djm 1024: error("line %d too long: %.40s...", num + 1, line);
1.119 djm 1025: skip = 1;
1026: invalid = 1;
1027: continue;
1028: }
1.163 chl 1029: num++;
1.119 djm 1030: if (skip) {
1031: skip = 0;
1032: continue;
1033: }
1.163 chl 1034: *cp = '\0';
1.119 djm 1035:
1036: /* Skip leading whitespace, empty and comment lines. */
1037: for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
1038: ;
1039: if (!*cp || *cp == '\n' || *cp == '#') {
1040: if (inplace)
1041: fprintf(out, "%s\n", cp);
1042: continue;
1043: }
1.179 djm 1044: /* Check whether this is a CA key */
1045: if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 &&
1046: (cp[sizeof(CA_MARKER) - 1] == ' ' ||
1047: cp[sizeof(CA_MARKER) - 1] == '\t')) {
1048: ca = 1;
1049: cp += sizeof(CA_MARKER);
1050: } else
1051: ca = 0;
1052:
1.119 djm 1053: /* Find the end of the host name portion. */
1054: for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++)
1055: ;
1.179 djm 1056:
1.119 djm 1057: if (*kp == '\0' || *(kp + 1) == '\0') {
1058: error("line %d missing key: %.40s...",
1059: num, line);
1060: invalid = 1;
1061: continue;
1062: }
1063: *kp++ = '\0';
1064: kp2 = kp;
1065:
1.179 djm 1066: pub = key_new(KEY_RSA1);
1067: if (key_read(pub, &kp) != 1) {
1.119 djm 1068: kp = kp2;
1.179 djm 1069: key_free(pub);
1070: pub = key_new(KEY_UNSPEC);
1071: if (key_read(pub, &kp) != 1) {
1.119 djm 1072: error("line %d invalid key: %.40s...",
1073: num, line);
1.179 djm 1074: key_free(pub);
1.119 djm 1075: invalid = 1;
1076: continue;
1077: }
1078: }
1079:
1080: if (*cp == HASH_DELIM) {
1081: if (find_host || delete_host) {
1082: cp2 = host_hash(name, cp, strlen(cp));
1083: if (cp2 == NULL) {
1084: error("line %d: invalid hashed "
1085: "name: %.64s...", num, line);
1086: invalid = 1;
1087: continue;
1088: }
1089: c = (strcmp(cp2, cp) == 0);
1090: if (find_host && c) {
1091: printf("# Host %s found: "
1.179 djm 1092: "line %d type %s%s\n", name,
1093: num, key_type(pub),
1094: ca ? " (CA key)" : "");
1095: printhost(out, cp, pub, ca, 0);
1.119 djm 1096: }
1.217 djm 1097: if (delete_host) {
1098: if (!c && !ca)
1099: printhost(out, cp, pub, ca, 0);
1100: else
1101: printf("# Host %s found: "
1102: "line %d type %s\n", name,
1103: num, key_type(pub));
1104: }
1.119 djm 1105: } else if (hash_hosts)
1.179 djm 1106: printhost(out, cp, pub, ca, 0);
1.119 djm 1107: } else {
1108: if (find_host || delete_host) {
1109: c = (match_hostname(name, cp,
1110: strlen(cp)) == 1);
1111: if (find_host && c) {
1112: printf("# Host %s found: "
1.179 djm 1113: "line %d type %s%s\n", name,
1114: num, key_type(pub),
1115: ca ? " (CA key)" : "");
1116: printhost(out, name, pub,
1117: ca, hash_hosts && !ca);
1.119 djm 1118: }
1.217 djm 1119: if (delete_host) {
1120: if (!c && !ca)
1121: printhost(out, cp, pub, ca, 0);
1122: else
1123: printf("# Host %s found: "
1124: "line %d type %s\n", name,
1125: num, key_type(pub));
1126: }
1.119 djm 1127: } else if (hash_hosts) {
1.121 deraadt 1128: for (cp2 = strsep(&cp, ",");
1.119 djm 1129: cp2 != NULL && *cp2 != '\0';
1.120 djm 1130: cp2 = strsep(&cp, ",")) {
1.179 djm 1131: if (ca) {
1132: fprintf(stderr, "Warning: "
1133: "ignoring CA key for host: "
1134: "%.64s\n", cp2);
1135: printhost(out, cp2, pub, ca, 0);
1136: } else if (strcspn(cp2, "*?!") !=
1137: strlen(cp2)) {
1.120 djm 1138: fprintf(stderr, "Warning: "
1139: "ignoring host name with "
1140: "metacharacters: %.64s\n",
1141: cp2);
1.179 djm 1142: printhost(out, cp2, pub, ca, 0);
1143: } else
1144: printhost(out, cp2, pub, ca, 1);
1.120 djm 1145: }
1.119 djm 1146: has_unhashed = 1;
1147: }
1148: }
1.179 djm 1149: key_free(pub);
1.119 djm 1150: }
1151: fclose(in);
1152:
1153: if (invalid) {
1.165 djm 1154: fprintf(stderr, "%s is not a valid known_hosts file.\n",
1.119 djm 1155: identity_file);
1156: if (inplace) {
1157: fprintf(stderr, "Not replacing existing known_hosts "
1.122 markus 1158: "file because of errors\n");
1.119 djm 1159: fclose(out);
1160: unlink(tmp);
1161: }
1162: exit(1);
1163: }
1164:
1165: if (inplace) {
1166: fclose(out);
1167:
1168: /* Backup existing file */
1169: if (unlink(old) == -1 && errno != ENOENT)
1170: fatal("unlink %.100s: %s", old, strerror(errno));
1171: if (link(identity_file, old) == -1)
1172: fatal("link %.100s to %.100s: %s", identity_file, old,
1173: strerror(errno));
1174: /* Move new one into place */
1175: if (rename(tmp, identity_file) == -1) {
1176: error("rename\"%s\" to \"%s\": %s", tmp, identity_file,
1177: strerror(errno));
1178: unlink(tmp);
1179: unlink(old);
1180: exit(1);
1181: }
1182:
1183: fprintf(stderr, "%s updated.\n", identity_file);
1184: fprintf(stderr, "Original contents retained as %s\n", old);
1185: if (has_unhashed) {
1186: fprintf(stderr, "WARNING: %s contains unhashed "
1187: "entries\n", old);
1188: fprintf(stderr, "Delete this file to ensure privacy "
1.128 djm 1189: "of hostnames\n");
1.119 djm 1190: }
1191: }
1192:
1193: exit(0);
1194: }
1195:
1.13 deraadt 1196: /*
1197: * Perform changing a passphrase. The argument is the passwd structure
1198: * for the current user.
1199: */
1.63 itojun 1200: static void
1.7 markus 1201: do_change_passphrase(struct passwd *pw)
1202: {
1.12 markus 1203: char *comment;
1204: char *old_passphrase, *passphrase1, *passphrase2;
1205: struct stat st;
1.19 markus 1206: Key *private;
1.12 markus 1207:
1208: if (!have_identity)
1209: ask_filename(pw, "Enter file in which the key is");
1210: if (stat(identity_file, &st) < 0) {
1211: perror(identity_file);
1212: exit(1);
1213: }
1214: /* Try to load the file with empty passphrase. */
1.52 markus 1215: private = key_load_private(identity_file, "", &comment);
1216: if (private == NULL) {
1.12 markus 1217: if (identity_passphrase)
1218: old_passphrase = xstrdup(identity_passphrase);
1219: else
1.65 markus 1220: old_passphrase =
1221: read_passphrase("Enter old passphrase: ",
1222: RP_ALLOW_STDIN);
1223: private = key_load_private(identity_file, old_passphrase,
1224: &comment);
1.52 markus 1225: memset(old_passphrase, 0, strlen(old_passphrase));
1.227 djm 1226: free(old_passphrase);
1.52 markus 1227: if (private == NULL) {
1.12 markus 1228: printf("Bad passphrase.\n");
1229: exit(1);
1230: }
1231: }
1232: printf("Key has comment '%s'\n", comment);
1233:
1234: /* Ask the new passphrase (twice). */
1235: if (identity_new_passphrase) {
1236: passphrase1 = xstrdup(identity_new_passphrase);
1237: passphrase2 = NULL;
1238: } else {
1239: passphrase1 =
1.65 markus 1240: read_passphrase("Enter new passphrase (empty for no "
1241: "passphrase): ", RP_ALLOW_STDIN);
1242: passphrase2 = read_passphrase("Enter same passphrase again: ",
1.86 deraadt 1243: RP_ALLOW_STDIN);
1.12 markus 1244:
1245: /* Verify that they are the same. */
1246: if (strcmp(passphrase1, passphrase2) != 0) {
1247: memset(passphrase1, 0, strlen(passphrase1));
1248: memset(passphrase2, 0, strlen(passphrase2));
1.227 djm 1249: free(passphrase1);
1250: free(passphrase2);
1.12 markus 1251: printf("Pass phrases do not match. Try again.\n");
1252: exit(1);
1253: }
1254: /* Destroy the other copy. */
1255: memset(passphrase2, 0, strlen(passphrase2));
1.227 djm 1256: free(passphrase2);
1.12 markus 1257: }
1258:
1259: /* Save the file using the new passphrase. */
1.52 markus 1260: if (!key_save_private(private, identity_file, passphrase1, comment)) {
1.56 markus 1261: printf("Saving the key failed: %s.\n", identity_file);
1.12 markus 1262: memset(passphrase1, 0, strlen(passphrase1));
1.227 djm 1263: free(passphrase1);
1.19 markus 1264: key_free(private);
1.227 djm 1265: free(comment);
1.12 markus 1266: exit(1);
1267: }
1268: /* Destroy the passphrase and the copy of the key in memory. */
1269: memset(passphrase1, 0, strlen(passphrase1));
1.227 djm 1270: free(passphrase1);
1.19 markus 1271: key_free(private); /* Destroys contents */
1.227 djm 1272: free(comment);
1.1 deraadt 1273:
1.12 markus 1274: printf("Your identification has been saved with the new passphrase.\n");
1275: exit(0);
1.1 deraadt 1276: }
1277:
1.105 jakob 1278: /*
1279: * Print the SSHFP RR.
1280: */
1.138 jakob 1281: static int
1282: do_print_resource_record(struct passwd *pw, char *fname, char *hname)
1.105 jakob 1283: {
1284: Key *public;
1285: char *comment = NULL;
1286: struct stat st;
1287:
1.138 jakob 1288: if (fname == NULL)
1.105 jakob 1289: ask_filename(pw, "Enter file in which the key is");
1.138 jakob 1290: if (stat(fname, &st) < 0) {
1291: if (errno == ENOENT)
1292: return 0;
1293: perror(fname);
1.105 jakob 1294: exit(1);
1295: }
1.138 jakob 1296: public = key_load_public(fname, &comment);
1.105 jakob 1297: if (public != NULL) {
1.116 avsm 1298: export_dns_rr(hname, public, stdout, print_generic);
1.105 jakob 1299: key_free(public);
1.227 djm 1300: free(comment);
1.138 jakob 1301: return 1;
1.105 jakob 1302: }
1303: if (comment)
1.227 djm 1304: free(comment);
1.105 jakob 1305:
1.138 jakob 1306: printf("failed to read v2 public key from %s.\n", fname);
1.105 jakob 1307: exit(1);
1308: }
1309:
1.13 deraadt 1310: /*
1311: * Change the comment of a private key file.
1312: */
1.63 itojun 1313: static void
1.2 provos 1314: do_change_comment(struct passwd *pw)
1.1 deraadt 1315: {
1.46 deraadt 1316: char new_comment[1024], *comment, *passphrase;
1.52 markus 1317: Key *private;
1318: Key *public;
1.12 markus 1319: struct stat st;
1320: FILE *f;
1.46 deraadt 1321: int fd;
1.12 markus 1322:
1323: if (!have_identity)
1324: ask_filename(pw, "Enter file in which the key is");
1325: if (stat(identity_file, &st) < 0) {
1326: perror(identity_file);
1327: exit(1);
1328: }
1.52 markus 1329: private = key_load_private(identity_file, "", &comment);
1330: if (private == NULL) {
1.12 markus 1331: if (identity_passphrase)
1332: passphrase = xstrdup(identity_passphrase);
1333: else if (identity_new_passphrase)
1334: passphrase = xstrdup(identity_new_passphrase);
1335: else
1.65 markus 1336: passphrase = read_passphrase("Enter passphrase: ",
1337: RP_ALLOW_STDIN);
1.12 markus 1338: /* Try to load using the passphrase. */
1.52 markus 1339: private = key_load_private(identity_file, passphrase, &comment);
1340: if (private == NULL) {
1.12 markus 1341: memset(passphrase, 0, strlen(passphrase));
1.227 djm 1342: free(passphrase);
1.12 markus 1343: printf("Bad passphrase.\n");
1344: exit(1);
1345: }
1.52 markus 1346: } else {
1347: passphrase = xstrdup("");
1.12 markus 1348: }
1.52 markus 1349: if (private->type != KEY_RSA1) {
1350: fprintf(stderr, "Comments are only supported for RSA1 keys.\n");
1351: key_free(private);
1352: exit(1);
1.86 deraadt 1353: }
1.12 markus 1354: printf("Key now has comment '%s'\n", comment);
1355:
1356: if (identity_comment) {
1357: strlcpy(new_comment, identity_comment, sizeof(new_comment));
1358: } else {
1359: printf("Enter new comment: ");
1360: fflush(stdout);
1361: if (!fgets(new_comment, sizeof(new_comment), stdin)) {
1362: memset(passphrase, 0, strlen(passphrase));
1.19 markus 1363: key_free(private);
1.12 markus 1364: exit(1);
1365: }
1.162 gilles 1366: new_comment[strcspn(new_comment, "\n")] = '\0';
1.12 markus 1367: }
1368:
1369: /* Save the file using the new passphrase. */
1.52 markus 1370: if (!key_save_private(private, identity_file, passphrase, new_comment)) {
1.56 markus 1371: printf("Saving the key failed: %s.\n", identity_file);
1.12 markus 1372: memset(passphrase, 0, strlen(passphrase));
1.227 djm 1373: free(passphrase);
1.19 markus 1374: key_free(private);
1.227 djm 1375: free(comment);
1.12 markus 1376: exit(1);
1377: }
1378: memset(passphrase, 0, strlen(passphrase));
1.227 djm 1379: free(passphrase);
1.52 markus 1380: public = key_from_private(private);
1.19 markus 1381: key_free(private);
1.12 markus 1382:
1383: strlcat(identity_file, ".pub", sizeof(identity_file));
1.46 deraadt 1384: fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1385: if (fd == -1) {
1.12 markus 1386: printf("Could not save your public key in %s\n", identity_file);
1387: exit(1);
1388: }
1.46 deraadt 1389: f = fdopen(fd, "w");
1390: if (f == NULL) {
1.173 tobias 1391: printf("fdopen %s failed\n", identity_file);
1.46 deraadt 1392: exit(1);
1393: }
1.19 markus 1394: if (!key_write(public, f))
1.173 tobias 1395: fprintf(stderr, "write key failed\n");
1.19 markus 1396: key_free(public);
1397: fprintf(f, " %s\n", new_comment);
1.12 markus 1398: fclose(f);
1.1 deraadt 1399:
1.227 djm 1400: free(comment);
1.1 deraadt 1401:
1.12 markus 1402: printf("The comment in your key file has been changed.\n");
1403: exit(0);
1.1 deraadt 1404: }
1405:
1.179 djm 1406: static const char *
1.182 djm 1407: fmt_validity(u_int64_t valid_from, u_int64_t valid_to)
1.179 djm 1408: {
1409: char from[32], to[32];
1410: static char ret[64];
1411: time_t tt;
1412: struct tm *tm;
1413:
1414: *from = *to = '\0';
1.182 djm 1415: if (valid_from == 0 && valid_to == 0xffffffffffffffffULL)
1.179 djm 1416: return "forever";
1417:
1.182 djm 1418: if (valid_from != 0) {
1.179 djm 1419: /* XXX revisit INT_MAX in 2038 :) */
1.182 djm 1420: tt = valid_from > INT_MAX ? INT_MAX : valid_from;
1.179 djm 1421: tm = localtime(&tt);
1422: strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm);
1423: }
1.182 djm 1424: if (valid_to != 0xffffffffffffffffULL) {
1.179 djm 1425: /* XXX revisit INT_MAX in 2038 :) */
1.182 djm 1426: tt = valid_to > INT_MAX ? INT_MAX : valid_to;
1.179 djm 1427: tm = localtime(&tt);
1428: strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm);
1429: }
1430:
1.182 djm 1431: if (valid_from == 0) {
1.179 djm 1432: snprintf(ret, sizeof(ret), "before %s", to);
1433: return ret;
1434: }
1.182 djm 1435: if (valid_to == 0xffffffffffffffffULL) {
1.179 djm 1436: snprintf(ret, sizeof(ret), "after %s", from);
1437: return ret;
1438: }
1439:
1440: snprintf(ret, sizeof(ret), "from %s to %s", from, to);
1441: return ret;
1442: }
1443:
1444: static void
1.186 djm 1445: add_flag_option(Buffer *c, const char *name)
1.179 djm 1446: {
1447: debug3("%s: %s", __func__, name);
1448: buffer_put_cstring(c, name);
1449: buffer_put_string(c, NULL, 0);
1450: }
1451:
1452: static void
1.186 djm 1453: add_string_option(Buffer *c, const char *name, const char *value)
1.179 djm 1454: {
1455: Buffer b;
1456:
1457: debug3("%s: %s=%s", __func__, name, value);
1458: buffer_init(&b);
1459: buffer_put_cstring(&b, value);
1460:
1461: buffer_put_cstring(c, name);
1462: buffer_put_string(c, buffer_ptr(&b), buffer_len(&b));
1463:
1464: buffer_free(&b);
1465: }
1466:
1.190 djm 1467: #define OPTIONS_CRITICAL 1
1468: #define OPTIONS_EXTENSIONS 2
1.179 djm 1469: static void
1.190 djm 1470: prepare_options_buf(Buffer *c, int which)
1.179 djm 1471: {
1472: buffer_clear(c);
1.196 djm 1473: if ((which & OPTIONS_CRITICAL) != 0 &&
1474: certflags_command != NULL)
1475: add_string_option(c, "force-command", certflags_command);
1.190 djm 1476: if ((which & OPTIONS_EXTENSIONS) != 0 &&
1.210 djm 1477: (certflags_flags & CERTOPT_X_FWD) != 0)
1478: add_flag_option(c, "permit-X11-forwarding");
1479: if ((which & OPTIONS_EXTENSIONS) != 0 &&
1.190 djm 1480: (certflags_flags & CERTOPT_AGENT_FWD) != 0)
1.186 djm 1481: add_flag_option(c, "permit-agent-forwarding");
1.190 djm 1482: if ((which & OPTIONS_EXTENSIONS) != 0 &&
1483: (certflags_flags & CERTOPT_PORT_FWD) != 0)
1.186 djm 1484: add_flag_option(c, "permit-port-forwarding");
1.190 djm 1485: if ((which & OPTIONS_EXTENSIONS) != 0 &&
1486: (certflags_flags & CERTOPT_PTY) != 0)
1.186 djm 1487: add_flag_option(c, "permit-pty");
1.190 djm 1488: if ((which & OPTIONS_EXTENSIONS) != 0 &&
1489: (certflags_flags & CERTOPT_USER_RC) != 0)
1.186 djm 1490: add_flag_option(c, "permit-user-rc");
1.190 djm 1491: if ((which & OPTIONS_CRITICAL) != 0 &&
1492: certflags_src_addr != NULL)
1493: add_string_option(c, "source-address", certflags_src_addr);
1.179 djm 1494: }
1495:
1.197 djm 1496: static Key *
1497: load_pkcs11_key(char *path)
1498: {
1499: #ifdef ENABLE_PKCS11
1500: Key **keys = NULL, *public, *private = NULL;
1501: int i, nkeys;
1502:
1503: if ((public = key_load_public(path, NULL)) == NULL)
1504: fatal("Couldn't load CA public key \"%s\"", path);
1505:
1506: nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys);
1507: debug3("%s: %d keys", __func__, nkeys);
1508: if (nkeys <= 0)
1509: fatal("cannot read public key from pkcs11");
1510: for (i = 0; i < nkeys; i++) {
1511: if (key_equal_public(public, keys[i])) {
1512: private = keys[i];
1513: continue;
1514: }
1515: key_free(keys[i]);
1516: }
1.227 djm 1517: free(keys);
1.197 djm 1518: key_free(public);
1519: return private;
1520: #else
1521: fatal("no pkcs11 support");
1522: #endif /* ENABLE_PKCS11 */
1523: }
1524:
1.179 djm 1525: static void
1526: do_ca_sign(struct passwd *pw, int argc, char **argv)
1527: {
1528: int i, fd;
1529: u_int n;
1530: Key *ca, *public;
1531: char *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
1532: FILE *f;
1.186 djm 1533: int v00 = 0; /* legacy keys */
1.179 djm 1534:
1.186 djm 1535: if (key_type_name != NULL) {
1536: switch (key_type_from_name(key_type_name)) {
1537: case KEY_RSA_CERT_V00:
1538: case KEY_DSA_CERT_V00:
1539: v00 = 1;
1540: break;
1541: case KEY_UNSPEC:
1542: if (strcasecmp(key_type_name, "v00") == 0) {
1543: v00 = 1;
1544: break;
1545: } else if (strcasecmp(key_type_name, "v01") == 0)
1546: break;
1547: /* FALLTHROUGH */
1548: default:
1549: fprintf(stderr, "unknown key type %s\n", key_type_name);
1550: exit(1);
1551: }
1552: }
1553:
1.197 djm 1554: pkcs11_init(1);
1555: tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1556: if (pkcs11provider != NULL) {
1557: if ((ca = load_pkcs11_key(tmp)) == NULL)
1558: fatal("No PKCS#11 key matching %s found", ca_key_path);
1559: } else if ((ca = load_identity(tmp)) == NULL)
1560: fatal("Couldn't load CA key \"%s\"", tmp);
1.227 djm 1561: free(tmp);
1.197 djm 1562:
1.179 djm 1563: for (i = 0; i < argc; i++) {
1564: /* Split list of principals */
1565: n = 0;
1566: if (cert_principals != NULL) {
1567: otmp = tmp = xstrdup(cert_principals);
1568: plist = NULL;
1569: for (; (cp = strsep(&tmp, ",")) != NULL; n++) {
1570: plist = xrealloc(plist, n + 1, sizeof(*plist));
1571: if (*(plist[n] = xstrdup(cp)) == '\0')
1572: fatal("Empty principal name");
1573: }
1.227 djm 1574: free(otmp);
1.179 djm 1575: }
1576:
1577: tmp = tilde_expand_filename(argv[i], pw->pw_uid);
1578: if ((public = key_load_public(tmp, &comment)) == NULL)
1579: fatal("%s: unable to open \"%s\"", __func__, tmp);
1.200 djm 1580: if (public->type != KEY_RSA && public->type != KEY_DSA &&
1581: public->type != KEY_ECDSA)
1.179 djm 1582: fatal("%s: key \"%s\" type %s cannot be certified",
1583: __func__, tmp, key_type(public));
1584:
1585: /* Prepare certificate to sign */
1.186 djm 1586: if (key_to_certified(public, v00) != 0)
1.179 djm 1587: fatal("Could not upgrade key %s to certificate", tmp);
1588: public->cert->type = cert_key_type;
1.186 djm 1589: public->cert->serial = (u_int64_t)cert_serial;
1.179 djm 1590: public->cert->key_id = xstrdup(cert_key_id);
1591: public->cert->nprincipals = n;
1592: public->cert->principals = plist;
1593: public->cert->valid_after = cert_valid_from;
1594: public->cert->valid_before = cert_valid_to;
1.190 djm 1595: if (v00) {
1596: prepare_options_buf(&public->cert->critical,
1597: OPTIONS_CRITICAL|OPTIONS_EXTENSIONS);
1598: } else {
1599: prepare_options_buf(&public->cert->critical,
1600: OPTIONS_CRITICAL);
1601: prepare_options_buf(&public->cert->extensions,
1602: OPTIONS_EXTENSIONS);
1603: }
1.179 djm 1604: public->cert->signature_key = key_from_private(ca);
1605:
1606: if (key_certify(public, ca) != 0)
1607: fatal("Couldn't not certify key %s", tmp);
1608:
1609: if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
1610: *cp = '\0';
1611: xasprintf(&out, "%s-cert.pub", tmp);
1.227 djm 1612: free(tmp);
1.179 djm 1613:
1614: if ((fd = open(out, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
1615: fatal("Could not open \"%s\" for writing: %s", out,
1616: strerror(errno));
1617: if ((f = fdopen(fd, "w")) == NULL)
1618: fatal("%s: fdopen: %s", __func__, strerror(errno));
1619: if (!key_write(public, f))
1620: fatal("Could not write certified key to %s", out);
1621: fprintf(f, " %s\n", comment);
1622: fclose(f);
1623:
1.186 djm 1624: if (!quiet) {
1625: logit("Signed %s key %s: id \"%s\" serial %llu%s%s "
1626: "valid %s", key_cert_type(public),
1.205 djm 1627: out, public->cert->key_id,
1628: (unsigned long long)public->cert->serial,
1.179 djm 1629: cert_principals != NULL ? " for " : "",
1630: cert_principals != NULL ? cert_principals : "",
1.182 djm 1631: fmt_validity(cert_valid_from, cert_valid_to));
1.186 djm 1632: }
1.179 djm 1633:
1634: key_free(public);
1.227 djm 1635: free(out);
1.179 djm 1636: }
1.197 djm 1637: pkcs11_terminate();
1.179 djm 1638: exit(0);
1639: }
1640:
1641: static u_int64_t
1642: parse_relative_time(const char *s, time_t now)
1643: {
1644: int64_t mul, secs;
1645:
1646: mul = *s == '-' ? -1 : 1;
1647:
1648: if ((secs = convtime(s + 1)) == -1)
1649: fatal("Invalid relative certificate time %s", s);
1650: if (mul == -1 && secs > now)
1651: fatal("Certificate time %s cannot be represented", s);
1652: return now + (u_int64_t)(secs * mul);
1653: }
1654:
1655: static u_int64_t
1656: parse_absolute_time(const char *s)
1657: {
1658: struct tm tm;
1659: time_t tt;
1.180 djm 1660: char buf[32], *fmt;
1.179 djm 1661:
1.180 djm 1662: /*
1663: * POSIX strptime says "The application shall ensure that there
1664: * is white-space or other non-alphanumeric characters between
1665: * any two conversion specifications" so arrange things this way.
1666: */
1667: switch (strlen(s)) {
1668: case 8:
1.184 djm 1669: fmt = "%Y-%m-%d";
1670: snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6);
1.180 djm 1671: break;
1672: case 14:
1.184 djm 1673: fmt = "%Y-%m-%dT%H:%M:%S";
1674: snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s",
1.180 djm 1675: s, s + 4, s + 6, s + 8, s + 10, s + 12);
1676: break;
1677: default:
1.179 djm 1678: fatal("Invalid certificate time format %s", s);
1.180 djm 1679: }
1.179 djm 1680:
1681: bzero(&tm, sizeof(tm));
1.180 djm 1682: if (strptime(buf, fmt, &tm) == NULL)
1.179 djm 1683: fatal("Invalid certificate time %s", s);
1684: if ((tt = mktime(&tm)) < 0)
1685: fatal("Certificate time %s cannot be represented", s);
1686: return (u_int64_t)tt;
1687: }
1688:
1689: static void
1690: parse_cert_times(char *timespec)
1691: {
1692: char *from, *to;
1693: time_t now = time(NULL);
1694: int64_t secs;
1695:
1696: /* +timespec relative to now */
1697: if (*timespec == '+' && strchr(timespec, ':') == NULL) {
1698: if ((secs = convtime(timespec + 1)) == -1)
1699: fatal("Invalid relative certificate life %s", timespec);
1700: cert_valid_to = now + secs;
1701: /*
1702: * Backdate certificate one minute to avoid problems on hosts
1703: * with poorly-synchronised clocks.
1704: */
1705: cert_valid_from = ((now - 59)/ 60) * 60;
1706: return;
1707: }
1708:
1709: /*
1710: * from:to, where
1711: * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS
1712: * to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS
1713: */
1714: from = xstrdup(timespec);
1715: to = strchr(from, ':');
1716: if (to == NULL || from == to || *(to + 1) == '\0')
1.181 djm 1717: fatal("Invalid certificate life specification %s", timespec);
1.179 djm 1718: *to++ = '\0';
1719:
1720: if (*from == '-' || *from == '+')
1721: cert_valid_from = parse_relative_time(from, now);
1722: else
1723: cert_valid_from = parse_absolute_time(from);
1724:
1725: if (*to == '-' || *to == '+')
1726: cert_valid_to = parse_relative_time(to, cert_valid_from);
1727: else
1728: cert_valid_to = parse_absolute_time(to);
1729:
1730: if (cert_valid_to <= cert_valid_from)
1731: fatal("Empty certificate validity interval");
1.227 djm 1732: free(from);
1.179 djm 1733: }
1734:
1735: static void
1.186 djm 1736: add_cert_option(char *opt)
1.179 djm 1737: {
1738: char *val;
1739:
1.208 stevesk 1740: if (strcasecmp(opt, "clear") == 0)
1.190 djm 1741: certflags_flags = 0;
1.179 djm 1742: else if (strcasecmp(opt, "no-x11-forwarding") == 0)
1.190 djm 1743: certflags_flags &= ~CERTOPT_X_FWD;
1.179 djm 1744: else if (strcasecmp(opt, "permit-x11-forwarding") == 0)
1.190 djm 1745: certflags_flags |= CERTOPT_X_FWD;
1.179 djm 1746: else if (strcasecmp(opt, "no-agent-forwarding") == 0)
1.190 djm 1747: certflags_flags &= ~CERTOPT_AGENT_FWD;
1.179 djm 1748: else if (strcasecmp(opt, "permit-agent-forwarding") == 0)
1.190 djm 1749: certflags_flags |= CERTOPT_AGENT_FWD;
1.179 djm 1750: else if (strcasecmp(opt, "no-port-forwarding") == 0)
1.190 djm 1751: certflags_flags &= ~CERTOPT_PORT_FWD;
1.179 djm 1752: else if (strcasecmp(opt, "permit-port-forwarding") == 0)
1.190 djm 1753: certflags_flags |= CERTOPT_PORT_FWD;
1.179 djm 1754: else if (strcasecmp(opt, "no-pty") == 0)
1.190 djm 1755: certflags_flags &= ~CERTOPT_PTY;
1.179 djm 1756: else if (strcasecmp(opt, "permit-pty") == 0)
1.190 djm 1757: certflags_flags |= CERTOPT_PTY;
1.179 djm 1758: else if (strcasecmp(opt, "no-user-rc") == 0)
1.190 djm 1759: certflags_flags &= ~CERTOPT_USER_RC;
1.179 djm 1760: else if (strcasecmp(opt, "permit-user-rc") == 0)
1.190 djm 1761: certflags_flags |= CERTOPT_USER_RC;
1.179 djm 1762: else if (strncasecmp(opt, "force-command=", 14) == 0) {
1763: val = opt + 14;
1764: if (*val == '\0')
1.186 djm 1765: fatal("Empty force-command option");
1.190 djm 1766: if (certflags_command != NULL)
1.179 djm 1767: fatal("force-command already specified");
1.190 djm 1768: certflags_command = xstrdup(val);
1.179 djm 1769: } else if (strncasecmp(opt, "source-address=", 15) == 0) {
1770: val = opt + 15;
1771: if (*val == '\0')
1.186 djm 1772: fatal("Empty source-address option");
1.190 djm 1773: if (certflags_src_addr != NULL)
1.179 djm 1774: fatal("source-address already specified");
1775: if (addr_match_cidr_list(NULL, val) != 0)
1776: fatal("Invalid source-address list");
1.190 djm 1777: certflags_src_addr = xstrdup(val);
1.179 djm 1778: } else
1.186 djm 1779: fatal("Unsupported certificate option \"%s\"", opt);
1.179 djm 1780: }
1781:
1.63 itojun 1782: static void
1.192 djm 1783: show_options(const Buffer *optbuf, int v00, int in_critical)
1784: {
1.228 ! djm 1785: char *name;
! 1786: u_char *data;
1.192 djm 1787: u_int dlen;
1788: Buffer options, option;
1789:
1790: buffer_init(&options);
1791: buffer_append(&options, buffer_ptr(optbuf), buffer_len(optbuf));
1792:
1793: buffer_init(&option);
1794: while (buffer_len(&options) != 0) {
1795: name = buffer_get_string(&options, NULL);
1796: data = buffer_get_string_ptr(&options, &dlen);
1797: buffer_append(&option, data, dlen);
1798: printf(" %s", name);
1799: if ((v00 || !in_critical) &&
1800: (strcmp(name, "permit-X11-forwarding") == 0 ||
1801: strcmp(name, "permit-agent-forwarding") == 0 ||
1802: strcmp(name, "permit-port-forwarding") == 0 ||
1803: strcmp(name, "permit-pty") == 0 ||
1804: strcmp(name, "permit-user-rc") == 0))
1805: printf("\n");
1806: else if ((v00 || in_critical) &&
1807: (strcmp(name, "force-command") == 0 ||
1808: strcmp(name, "source-address") == 0)) {
1809: data = buffer_get_string(&option, NULL);
1810: printf(" %s\n", data);
1.227 djm 1811: free(data);
1.192 djm 1812: } else {
1813: printf(" UNKNOWN OPTION (len %u)\n",
1814: buffer_len(&option));
1815: buffer_clear(&option);
1816: }
1.227 djm 1817: free(name);
1.192 djm 1818: if (buffer_len(&option) != 0)
1819: fatal("Option corrupt: extra data at end");
1820: }
1821: buffer_free(&option);
1822: buffer_free(&options);
1823: }
1824:
1825: static void
1.182 djm 1826: do_show_cert(struct passwd *pw)
1827: {
1828: Key *key;
1829: struct stat st;
1830: char *key_fp, *ca_fp;
1.192 djm 1831: u_int i, v00;
1.182 djm 1832:
1833: if (!have_identity)
1834: ask_filename(pw, "Enter file in which the key is");
1.191 djm 1835: if (stat(identity_file, &st) < 0)
1836: fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
1.182 djm 1837: if ((key = key_load_public(identity_file, NULL)) == NULL)
1838: fatal("%s is not a public key", identity_file);
1839: if (!key_is_cert(key))
1840: fatal("%s is not a certificate", identity_file);
1.186 djm 1841: v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00;
1842:
1.182 djm 1843: key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
1844: ca_fp = key_fingerprint(key->cert->signature_key,
1845: SSH_FP_MD5, SSH_FP_HEX);
1846:
1847: printf("%s:\n", identity_file);
1.186 djm 1848: printf(" Type: %s %s certificate\n", key_ssh_name(key),
1849: key_cert_type(key));
1850: printf(" Public key: %s %s\n", key_type(key), key_fp);
1851: printf(" Signing CA: %s %s\n",
1.182 djm 1852: key_type(key->cert->signature_key), ca_fp);
1.186 djm 1853: printf(" Key ID: \"%s\"\n", key->cert->key_id);
1.205 djm 1854: if (!v00) {
1855: printf(" Serial: %llu\n",
1856: (unsigned long long)key->cert->serial);
1857: }
1.182 djm 1858: printf(" Valid: %s\n",
1859: fmt_validity(key->cert->valid_after, key->cert->valid_before));
1860: printf(" Principals: ");
1861: if (key->cert->nprincipals == 0)
1862: printf("(none)\n");
1863: else {
1864: for (i = 0; i < key->cert->nprincipals; i++)
1865: printf("\n %s",
1866: key->cert->principals[i]);
1867: printf("\n");
1868: }
1.186 djm 1869: printf(" Critical Options: ");
1870: if (buffer_len(&key->cert->critical) == 0)
1.182 djm 1871: printf("(none)\n");
1872: else {
1873: printf("\n");
1.192 djm 1874: show_options(&key->cert->critical, v00, 1);
1.186 djm 1875: }
1876: if (!v00) {
1877: printf(" Extensions: ");
1878: if (buffer_len(&key->cert->extensions) == 0)
1879: printf("(none)\n");
1880: else {
1881: printf("\n");
1.192 djm 1882: show_options(&key->cert->extensions, v00, 0);
1.182 djm 1883: }
1884: }
1885: exit(0);
1886: }
1887:
1888: static void
1.223 djm 1889: load_krl(const char *path, struct ssh_krl **krlp)
1890: {
1891: Buffer krlbuf;
1892: int fd;
1893:
1894: buffer_init(&krlbuf);
1895: if ((fd = open(path, O_RDONLY)) == -1)
1896: fatal("open %s: %s", path, strerror(errno));
1897: if (!key_load_file(fd, path, &krlbuf))
1898: fatal("Unable to load KRL");
1899: close(fd);
1900: /* XXX check sigs */
1901: if (ssh_krl_from_blob(&krlbuf, krlp, NULL, 0) != 0 ||
1902: *krlp == NULL)
1903: fatal("Invalid KRL file");
1904: buffer_free(&krlbuf);
1905: }
1906:
1907: static void
1908: update_krl_from_file(struct passwd *pw, const char *file, const Key *ca,
1909: struct ssh_krl *krl)
1910: {
1911: Key *key = NULL;
1912: u_long lnum = 0;
1913: char *path, *cp, *ep, line[SSH_MAX_PUBKEY_BYTES];
1914: unsigned long long serial, serial2;
1915: int i, was_explicit_key, was_sha1, r;
1916: FILE *krl_spec;
1917:
1918: path = tilde_expand_filename(file, pw->pw_uid);
1919: if (strcmp(path, "-") == 0) {
1920: krl_spec = stdin;
1921: free(path);
1922: path = xstrdup("(standard input)");
1923: } else if ((krl_spec = fopen(path, "r")) == NULL)
1924: fatal("fopen %s: %s", path, strerror(errno));
1925:
1926: if (!quiet)
1927: printf("Revoking from %s\n", path);
1928: while (read_keyfile_line(krl_spec, path, line, sizeof(line),
1929: &lnum) == 0) {
1930: was_explicit_key = was_sha1 = 0;
1931: cp = line + strspn(line, " \t");
1932: /* Trim trailing space, comments and strip \n */
1933: for (i = 0, r = -1; cp[i] != '\0'; i++) {
1934: if (cp[i] == '#' || cp[i] == '\n') {
1935: cp[i] = '\0';
1936: break;
1937: }
1938: if (cp[i] == ' ' || cp[i] == '\t') {
1939: /* Remember the start of a span of whitespace */
1940: if (r == -1)
1941: r = i;
1942: } else
1943: r = -1;
1944: }
1945: if (r != -1)
1946: cp[r] = '\0';
1947: if (*cp == '\0')
1948: continue;
1949: if (strncasecmp(cp, "serial:", 7) == 0) {
1950: if (ca == NULL) {
1951: fatal("revoking certificated by serial number "
1952: "requires specification of a CA key");
1953: }
1954: cp += 7;
1955: cp = cp + strspn(cp, " \t");
1956: errno = 0;
1957: serial = strtoull(cp, &ep, 0);
1958: if (*cp == '\0' || (*ep != '\0' && *ep != '-'))
1959: fatal("%s:%lu: invalid serial \"%s\"",
1960: path, lnum, cp);
1961: if (errno == ERANGE && serial == ULLONG_MAX)
1962: fatal("%s:%lu: serial out of range",
1963: path, lnum);
1964: serial2 = serial;
1965: if (*ep == '-') {
1966: cp = ep + 1;
1967: errno = 0;
1968: serial2 = strtoull(cp, &ep, 0);
1969: if (*cp == '\0' || *ep != '\0')
1970: fatal("%s:%lu: invalid serial \"%s\"",
1971: path, lnum, cp);
1972: if (errno == ERANGE && serial2 == ULLONG_MAX)
1973: fatal("%s:%lu: serial out of range",
1974: path, lnum);
1975: if (serial2 <= serial)
1976: fatal("%s:%lu: invalid serial range "
1977: "%llu:%llu", path, lnum,
1978: (unsigned long long)serial,
1979: (unsigned long long)serial2);
1980: }
1981: if (ssh_krl_revoke_cert_by_serial_range(krl,
1982: ca, serial, serial2) != 0) {
1983: fatal("%s: revoke serial failed",
1984: __func__);
1985: }
1986: } else if (strncasecmp(cp, "id:", 3) == 0) {
1987: if (ca == NULL) {
1988: fatal("revoking certificated by key ID "
1989: "requires specification of a CA key");
1990: }
1991: cp += 3;
1992: cp = cp + strspn(cp, " \t");
1993: if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0)
1994: fatal("%s: revoke key ID failed", __func__);
1995: } else {
1996: if (strncasecmp(cp, "key:", 4) == 0) {
1997: cp += 4;
1998: cp = cp + strspn(cp, " \t");
1999: was_explicit_key = 1;
2000: } else if (strncasecmp(cp, "sha1:", 5) == 0) {
2001: cp += 5;
2002: cp = cp + strspn(cp, " \t");
2003: was_sha1 = 1;
2004: } else {
2005: /*
2006: * Just try to process the line as a key.
2007: * Parsing will fail if it isn't.
2008: */
2009: }
2010: if ((key = key_new(KEY_UNSPEC)) == NULL)
2011: fatal("key_new");
2012: if (key_read(key, &cp) != 1)
2013: fatal("%s:%lu: invalid key", path, lnum);
2014: if (was_explicit_key)
2015: r = ssh_krl_revoke_key_explicit(krl, key);
2016: else if (was_sha1)
2017: r = ssh_krl_revoke_key_sha1(krl, key);
2018: else
2019: r = ssh_krl_revoke_key(krl, key);
2020: if (r != 0)
2021: fatal("%s: revoke key failed", __func__);
2022: key_free(key);
2023: }
2024: }
2025: if (strcmp(path, "-") != 0)
2026: fclose(krl_spec);
1.226 djm 2027: free(path);
1.223 djm 2028: }
2029:
2030: static void
2031: do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
2032: {
2033: struct ssh_krl *krl;
2034: struct stat sb;
2035: Key *ca = NULL;
2036: int fd, i;
2037: char *tmp;
2038: Buffer kbuf;
2039:
2040: if (*identity_file == '\0')
2041: fatal("KRL generation requires an output file");
2042: if (stat(identity_file, &sb) == -1) {
2043: if (errno != ENOENT)
2044: fatal("Cannot access KRL \"%s\": %s",
2045: identity_file, strerror(errno));
2046: if (updating)
2047: fatal("KRL \"%s\" does not exist", identity_file);
2048: }
2049: if (ca_key_path != NULL) {
2050: tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
2051: if ((ca = key_load_public(tmp, NULL)) == NULL)
2052: fatal("Cannot load CA public key %s", tmp);
1.227 djm 2053: free(tmp);
1.223 djm 2054: }
2055:
2056: if (updating)
2057: load_krl(identity_file, &krl);
2058: else if ((krl = ssh_krl_init()) == NULL)
2059: fatal("couldn't create KRL");
2060:
2061: if (cert_serial != 0)
2062: ssh_krl_set_version(krl, cert_serial);
2063: if (identity_comment != NULL)
2064: ssh_krl_set_comment(krl, identity_comment);
2065:
2066: for (i = 0; i < argc; i++)
2067: update_krl_from_file(pw, argv[i], ca, krl);
2068:
2069: buffer_init(&kbuf);
2070: if (ssh_krl_to_blob(krl, &kbuf, NULL, 0) != 0)
2071: fatal("Couldn't generate KRL");
2072: if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
2073: fatal("open %s: %s", identity_file, strerror(errno));
2074: if (atomicio(vwrite, fd, buffer_ptr(&kbuf), buffer_len(&kbuf)) !=
2075: buffer_len(&kbuf))
2076: fatal("write %s: %s", identity_file, strerror(errno));
2077: close(fd);
2078: buffer_free(&kbuf);
2079: ssh_krl_free(krl);
1.226 djm 2080: if (ca != NULL)
2081: key_free(ca);
1.223 djm 2082: }
2083:
2084: static void
2085: do_check_krl(struct passwd *pw, int argc, char **argv)
2086: {
2087: int i, r, ret = 0;
2088: char *comment;
2089: struct ssh_krl *krl;
2090: Key *k;
2091:
2092: if (*identity_file == '\0')
2093: fatal("KRL checking requires an input file");
2094: load_krl(identity_file, &krl);
2095: for (i = 0; i < argc; i++) {
2096: if ((k = key_load_public(argv[i], &comment)) == NULL)
2097: fatal("Cannot load public key %s", argv[i]);
2098: r = ssh_krl_check_key(krl, k);
2099: printf("%s%s%s%s: %s\n", argv[i],
2100: *comment ? " (" : "", comment, *comment ? ")" : "",
2101: r == 0 ? "ok" : "REVOKED");
2102: if (r != 0)
2103: ret = 1;
2104: key_free(k);
2105: free(comment);
2106: }
2107: ssh_krl_free(krl);
2108: exit(ret);
2109: }
2110:
2111: static void
1.10 markus 2112: usage(void)
2113: {
1.161 sobrado 2114: fprintf(stderr, "usage: %s [options]\n", __progname);
1.77 jakob 2115: fprintf(stderr, "Options:\n");
1.206 stevesk 2116: fprintf(stderr, " -A Generate non-existent host keys for all key types.\n");
1.123 otto 2117: fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n");
2118: fprintf(stderr, " -B Show bubblebabble digest of key file.\n");
1.77 jakob 2119: fprintf(stderr, " -b bits Number of bits in the key to create.\n");
1.123 otto 2120: fprintf(stderr, " -C comment Provide new comment.\n");
1.77 jakob 2121: fprintf(stderr, " -c Change comment in private and public key files.\n");
1.177 markus 2122: #ifdef ENABLE_PKCS11
2123: fprintf(stderr, " -D pkcs11 Download public key from pkcs11 token.\n");
2124: #endif
1.193 djm 2125: fprintf(stderr, " -e Export OpenSSH to foreign format key file.\n");
1.123 otto 2126: fprintf(stderr, " -F hostname Find hostname in known hosts file.\n");
1.77 jakob 2127: fprintf(stderr, " -f filename Filename of the key file.\n");
1.123 otto 2128: fprintf(stderr, " -G file Generate candidates for DH-GEX moduli.\n");
1.105 jakob 2129: fprintf(stderr, " -g Use generic DNS resource record format.\n");
1.123 otto 2130: fprintf(stderr, " -H Hash names in known_hosts file.\n");
1.179 djm 2131: fprintf(stderr, " -h Generate host certificate instead of a user certificate.\n");
2132: fprintf(stderr, " -I key_id Key identifier to include in certificate.\n");
1.193 djm 2133: fprintf(stderr, " -i Import foreign format to OpenSSH key file.\n");
1.216 jmc 2134: fprintf(stderr, " -J number Screen this number of moduli lines.\n");
1.215 dtucker 2135: fprintf(stderr, " -j number Start screening moduli at specified line.\n");
1.212 jmc 2136: fprintf(stderr, " -K checkpt Write checkpoints to this file.\n");
1.223 djm 2137: fprintf(stderr, " -k Generate a KRL file.\n");
1.182 djm 2138: fprintf(stderr, " -L Print the contents of a certificate.\n");
1.77 jakob 2139: fprintf(stderr, " -l Show fingerprint of key file.\n");
1.194 jmc 2140: fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n");
1.193 djm 2141: fprintf(stderr, " -m key_fmt Conversion format for -e/-i (PEM|PKCS8|RFC4716).\n");
1.194 jmc 2142: fprintf(stderr, " -N phrase Provide new passphrase.\n");
1.179 djm 2143: fprintf(stderr, " -n name,... User/host principal names to include in certificate\n");
1.187 jmc 2144: fprintf(stderr, " -O option Specify a certificate option.\n");
1.123 otto 2145: fprintf(stderr, " -P phrase Provide old passphrase.\n");
1.77 jakob 2146: fprintf(stderr, " -p Change passphrase of private key file.\n");
1.223 djm 2147: fprintf(stderr, " -Q Test whether key(s) are revoked in KRL.\n");
1.77 jakob 2148: fprintf(stderr, " -q Quiet.\n");
1.123 otto 2149: fprintf(stderr, " -R hostname Remove host from known_hosts file.\n");
2150: fprintf(stderr, " -r hostname Print DNS resource record.\n");
1.194 jmc 2151: fprintf(stderr, " -S start Start point (hex) for generating DH-GEX moduli.\n");
1.179 djm 2152: fprintf(stderr, " -s ca_key Certify keys with CA key.\n");
1.123 otto 2153: fprintf(stderr, " -T file Screen candidates for DH-GEX moduli.\n");
1.77 jakob 2154: fprintf(stderr, " -t type Specify type of key to create.\n");
1.224 jmc 2155: fprintf(stderr, " -u Update KRL rather than creating a new one.\n");
1.179 djm 2156: fprintf(stderr, " -V from:to Specify certificate validity interval.\n");
1.123 otto 2157: fprintf(stderr, " -v Verbose.\n");
2158: fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n");
2159: fprintf(stderr, " -y Read private key file and print public key.\n");
1.187 jmc 2160: fprintf(stderr, " -z serial Specify a serial number.\n");
1.107 djm 2161:
1.12 markus 2162: exit(1);
1.10 markus 2163: }
2164:
1.13 deraadt 2165: /*
2166: * Main program for key management.
2167: */
1.2 provos 2168: int
1.156 deraadt 2169: main(int argc, char **argv)
1.1 deraadt 2170: {
1.87 djm 2171: char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
1.211 dtucker 2172: char *checkpoint = NULL;
1.223 djm 2173: char out_file[MAXPATHLEN], *ep, *rr_hostname = NULL;
1.46 deraadt 2174: Key *private, *public;
1.12 markus 2175: struct passwd *pw;
2176: struct stat st;
1.177 markus 2177: int opt, type, fd;
1.126 dtucker 2178: u_int32_t memory = 0, generator_wanted = 0, trials = 100;
1.107 djm 2179: int do_gen_candidates = 0, do_screen_candidates = 0;
1.223 djm 2180: int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
1.215 dtucker 2181: unsigned long start_lineno = 0, lines_to_process = 0;
1.107 djm 2182: BIGNUM *start = NULL;
1.12 markus 2183: FILE *f;
1.125 avsm 2184: const char *errstr;
1.33 markus 2185:
1.12 markus 2186: extern int optind;
2187: extern char *optarg;
1.129 djm 2188:
2189: /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
2190: sanitise_stdfd();
1.12 markus 2191:
1.201 djm 2192: OpenSSL_add_all_algorithms();
1.156 deraadt 2193: log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
1.19 markus 2194:
1.14 markus 2195: /* we need this for the home * directory. */
1.12 markus 2196: pw = getpwuid(getuid());
2197: if (!pw) {
2198: printf("You don't exist, go away!\n");
2199: exit(1);
2200: }
1.19 markus 2201: if (gethostname(hostname, sizeof(hostname)) < 0) {
2202: perror("gethostname");
2203: exit(1);
2204: }
1.14 markus 2205:
1.223 djm 2206: while ((opt = getopt(argc, argv, "ABHLQXceghiklpquvxy"
2207: "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:a:b:f:g:j:m:n:r:s:t:z:")) != -1) {
1.12 markus 2208: switch (opt) {
1.206 stevesk 2209: case 'A':
2210: gen_all_hostkeys = 1;
2211: break;
1.12 markus 2212: case 'b':
1.202 markus 2213: bits = (u_int32_t)strtonum(optarg, 256, 32768, &errstr);
1.125 avsm 2214: if (errstr)
2215: fatal("Bits has bad value %s (%s)",
2216: optarg, errstr);
1.12 markus 2217: break;
1.119 djm 2218: case 'F':
2219: find_host = 1;
2220: rr_hostname = optarg;
2221: break;
2222: case 'H':
2223: hash_hosts = 1;
2224: break;
1.179 djm 2225: case 'I':
2226: cert_key_id = optarg;
2227: break;
1.215 dtucker 2228: case 'J':
2229: lines_to_process = strtoul(optarg, NULL, 10);
2230: break;
2231: case 'j':
2232: start_lineno = strtoul(optarg, NULL, 10);
2233: break;
1.119 djm 2234: case 'R':
2235: delete_host = 1;
2236: rr_hostname = optarg;
2237: break;
1.182 djm 2238: case 'L':
2239: show_cert = 1;
2240: break;
1.12 markus 2241: case 'l':
2242: print_fingerprint = 1;
2243: break;
1.49 markus 2244: case 'B':
2245: print_bubblebabble = 1;
2246: break;
1.193 djm 2247: case 'm':
2248: if (strcasecmp(optarg, "RFC4716") == 0 ||
2249: strcasecmp(optarg, "ssh2") == 0) {
2250: convert_format = FMT_RFC4716;
2251: break;
2252: }
2253: if (strcasecmp(optarg, "PKCS8") == 0) {
2254: convert_format = FMT_PKCS8;
2255: break;
2256: }
2257: if (strcasecmp(optarg, "PEM") == 0) {
2258: convert_format = FMT_PEM;
2259: break;
2260: }
2261: fatal("Unsupported conversion format \"%s\"", optarg);
1.179 djm 2262: case 'n':
2263: cert_principals = optarg;
2264: break;
1.12 markus 2265: case 'p':
2266: change_passphrase = 1;
2267: break;
2268: case 'c':
2269: change_comment = 1;
2270: break;
2271: case 'f':
1.124 avsm 2272: if (strlcpy(identity_file, optarg, sizeof(identity_file)) >=
2273: sizeof(identity_file))
2274: fatal("Identity filename too long");
1.12 markus 2275: have_identity = 1;
2276: break;
1.105 jakob 2277: case 'g':
2278: print_generic = 1;
2279: break;
1.12 markus 2280: case 'P':
2281: identity_passphrase = optarg;
2282: break;
2283: case 'N':
2284: identity_new_passphrase = optarg;
2285: break;
1.223 djm 2286: case 'Q':
2287: check_krl = 1;
2288: break;
1.179 djm 2289: case 'O':
1.186 djm 2290: add_cert_option(optarg);
1.179 djm 2291: break;
1.12 markus 2292: case 'C':
2293: identity_comment = optarg;
2294: break;
2295: case 'q':
2296: quiet = 1;
1.20 deraadt 2297: break;
1.57 markus 2298: case 'e':
1.19 markus 2299: case 'x':
1.57 markus 2300: /* export key */
1.193 djm 2301: convert_to = 1;
1.19 markus 2302: break;
1.179 djm 2303: case 'h':
2304: cert_key_type = SSH2_CERT_TYPE_HOST;
1.190 djm 2305: certflags_flags = 0;
1.179 djm 2306: break;
1.223 djm 2307: case 'k':
2308: gen_krl = 1;
2309: break;
1.57 markus 2310: case 'i':
1.19 markus 2311: case 'X':
1.57 markus 2312: /* import key */
1.193 djm 2313: convert_from = 1;
1.19 markus 2314: break;
2315: case 'y':
2316: print_public = 1;
2317: break;
1.179 djm 2318: case 's':
2319: ca_key_path = optarg;
2320: break;
1.33 markus 2321: case 't':
2322: key_type_name = optarg;
2323: break;
1.75 markus 2324: case 'D':
1.177 markus 2325: pkcs11provider = optarg;
1.66 markus 2326: break;
1.223 djm 2327: case 'u':
2328: update_krl = 1;
2329: break;
1.113 djm 2330: case 'v':
2331: if (log_level == SYSLOG_LEVEL_INFO)
2332: log_level = SYSLOG_LEVEL_DEBUG1;
2333: else {
1.117 deraadt 2334: if (log_level >= SYSLOG_LEVEL_DEBUG1 &&
1.113 djm 2335: log_level < SYSLOG_LEVEL_DEBUG3)
2336: log_level++;
2337: }
2338: break;
1.105 jakob 2339: case 'r':
1.119 djm 2340: rr_hostname = optarg;
1.105 jakob 2341: break;
1.107 djm 2342: case 'W':
1.142 deraadt 2343: generator_wanted = (u_int32_t)strtonum(optarg, 1,
2344: UINT_MAX, &errstr);
1.124 avsm 2345: if (errstr)
2346: fatal("Desired generator has bad value: %s (%s)",
2347: optarg, errstr);
1.107 djm 2348: break;
2349: case 'a':
1.142 deraadt 2350: trials = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
1.124 avsm 2351: if (errstr)
2352: fatal("Invalid number of trials: %s (%s)",
2353: optarg, errstr);
1.107 djm 2354: break;
2355: case 'M':
1.142 deraadt 2356: memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
1.186 djm 2357: if (errstr)
1.124 avsm 2358: fatal("Memory limit is %s: %s", errstr, optarg);
1.107 djm 2359: break;
2360: case 'G':
2361: do_gen_candidates = 1;
1.124 avsm 2362: if (strlcpy(out_file, optarg, sizeof(out_file)) >=
2363: sizeof(out_file))
2364: fatal("Output filename too long");
1.107 djm 2365: break;
2366: case 'T':
2367: do_screen_candidates = 1;
1.124 avsm 2368: if (strlcpy(out_file, optarg, sizeof(out_file)) >=
2369: sizeof(out_file))
2370: fatal("Output filename too long");
1.107 djm 2371: break;
1.211 dtucker 2372: case 'K':
2373: if (strlen(optarg) >= MAXPATHLEN)
2374: fatal("Checkpoint filename too long");
2375: checkpoint = xstrdup(optarg);
2376: break;
1.107 djm 2377: case 'S':
2378: /* XXX - also compare length against bits */
2379: if (BN_hex2bn(&start, optarg) == 0)
2380: fatal("Invalid start point.");
2381: break;
1.179 djm 2382: case 'V':
2383: parse_cert_times(optarg);
1.186 djm 2384: break;
2385: case 'z':
1.219 djm 2386: errno = 0;
2387: cert_serial = strtoull(optarg, &ep, 10);
2388: if (*optarg < '0' || *optarg > '9' || *ep != '\0' ||
2389: (errno == ERANGE && cert_serial == ULLONG_MAX))
2390: fatal("Invalid serial number \"%s\"", optarg);
1.179 djm 2391: break;
1.12 markus 2392: case '?':
2393: default:
2394: usage();
2395: }
2396: }
1.113 djm 2397:
2398: /* reinit */
1.156 deraadt 2399: log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
1.113 djm 2400:
1.179 djm 2401: argv += optind;
2402: argc -= optind;
2403:
2404: if (ca_key_path != NULL) {
1.223 djm 2405: if (argc < 1 && !gen_krl) {
1.179 djm 2406: printf("Too few arguments.\n");
2407: usage();
2408: }
1.223 djm 2409: } else if (argc > 0 && !gen_krl && !check_krl) {
1.12 markus 2410: printf("Too many arguments.\n");
1.87 djm 2411: usage();
2412: }
1.12 markus 2413: if (change_passphrase && change_comment) {
2414: printf("Can only have one of -p and -c.\n");
1.166 djm 2415: usage();
2416: }
2417: if (print_fingerprint && (delete_host || hash_hosts)) {
1.221 djm 2418: printf("Cannot use -l with -H or -R.\n");
1.12 markus 2419: usage();
1.223 djm 2420: }
2421: if (gen_krl) {
2422: do_gen_krl(pw, update_krl, argc, argv);
2423: return (0);
2424: }
2425: if (check_krl) {
2426: do_check_krl(pw, argc, argv);
2427: return (0);
1.179 djm 2428: }
2429: if (ca_key_path != NULL) {
2430: if (cert_key_id == NULL)
2431: fatal("Must specify key id (-I) when certifying");
2432: do_ca_sign(pw, argc, argv);
1.12 markus 2433: }
1.182 djm 2434: if (show_cert)
2435: do_show_cert(pw);
1.119 djm 2436: if (delete_host || hash_hosts || find_host)
2437: do_known_hosts(pw, rr_hostname);
1.221 djm 2438: if (pkcs11provider != NULL)
2439: do_download(pw);
1.49 markus 2440: if (print_fingerprint || print_bubblebabble)
1.12 markus 2441: do_fingerprint(pw);
2442: if (change_passphrase)
2443: do_change_passphrase(pw);
2444: if (change_comment)
2445: do_change_comment(pw);
1.193 djm 2446: if (convert_to)
2447: do_convert_to(pw);
2448: if (convert_from)
2449: do_convert_from(pw);
1.19 markus 2450: if (print_public)
2451: do_print_public(pw);
1.119 djm 2452: if (rr_hostname != NULL) {
1.138 jakob 2453: unsigned int n = 0;
2454:
2455: if (have_identity) {
2456: n = do_print_resource_record(pw,
2457: identity_file, rr_hostname);
2458: if (n == 0) {
2459: perror(identity_file);
2460: exit(1);
2461: }
2462: exit(0);
2463: } else {
2464:
2465: n += do_print_resource_record(pw,
2466: _PATH_HOST_RSA_KEY_FILE, rr_hostname);
2467: n += do_print_resource_record(pw,
2468: _PATH_HOST_DSA_KEY_FILE, rr_hostname);
1.214 djm 2469: n += do_print_resource_record(pw,
2470: _PATH_HOST_ECDSA_KEY_FILE, rr_hostname);
1.138 jakob 2471:
2472: if (n == 0)
2473: fatal("no keys found.");
2474: exit(0);
2475: }
1.105 jakob 2476: }
1.107 djm 2477:
2478: if (do_gen_candidates) {
2479: FILE *out = fopen(out_file, "w");
1.111 djm 2480:
1.107 djm 2481: if (out == NULL) {
2482: error("Couldn't open modulus candidate file \"%s\": %s",
2483: out_file, strerror(errno));
2484: return (1);
2485: }
1.130 markus 2486: if (bits == 0)
2487: bits = DEFAULT_BITS;
1.107 djm 2488: if (gen_candidates(out, memory, bits, start) != 0)
1.131 stevesk 2489: fatal("modulus candidate generation failed");
1.107 djm 2490:
2491: return (0);
2492: }
2493:
2494: if (do_screen_candidates) {
2495: FILE *in;
1.225 djm 2496: FILE *out = fopen(out_file, "a");
1.107 djm 2497:
2498: if (have_identity && strcmp(identity_file, "-") != 0) {
2499: if ((in = fopen(identity_file, "r")) == NULL) {
2500: fatal("Couldn't open modulus candidate "
1.111 djm 2501: "file \"%s\": %s", identity_file,
1.107 djm 2502: strerror(errno));
2503: }
2504: } else
2505: in = stdin;
2506:
2507: if (out == NULL) {
2508: fatal("Couldn't open moduli file \"%s\": %s",
2509: out_file, strerror(errno));
2510: }
1.215 dtucker 2511: if (prime_test(in, out, trials, generator_wanted, checkpoint,
2512: start_lineno, lines_to_process) != 0)
1.131 stevesk 2513: fatal("modulus screening failed");
1.108 markus 2514: return (0);
1.75 markus 2515: }
1.12 markus 2516:
1.206 stevesk 2517: if (gen_all_hostkeys) {
2518: do_gen_all_hostkeys(pw);
2519: return (0);
2520: }
2521:
1.12 markus 2522: arc4random_stir();
2523:
1.133 djm 2524: if (key_type_name == NULL)
2525: key_type_name = "rsa";
2526:
1.35 markus 2527: type = key_type_from_name(key_type_name);
1.206 stevesk 2528: type_bits_valid(type, &bits);
2529:
1.33 markus 2530: if (!quiet)
1.35 markus 2531: printf("Generating public/private %s key pair.\n", key_type_name);
1.33 markus 2532: private = key_generate(type, bits);
2533: if (private == NULL) {
1.173 tobias 2534: fprintf(stderr, "key_generate failed\n");
1.33 markus 2535: exit(1);
2536: }
2537: public = key_from_private(private);
1.12 markus 2538:
2539: if (!have_identity)
2540: ask_filename(pw, "Enter file in which to save the key");
2541:
1.132 djm 2542: /* Create ~/.ssh directory if it doesn't already exist. */
1.188 djm 2543: snprintf(dotsshdir, sizeof dotsshdir, "%s/%s",
2544: pw->pw_dir, _PATH_SSH_USER_DIR);
2545: if (strstr(identity_file, dotsshdir) != NULL) {
2546: if (stat(dotsshdir, &st) < 0) {
2547: if (errno != ENOENT) {
2548: error("Could not stat %s: %s", dotsshdir,
2549: strerror(errno));
2550: } else if (mkdir(dotsshdir, 0700) < 0) {
2551: error("Could not create directory '%s': %s",
2552: dotsshdir, strerror(errno));
2553: } else if (!quiet)
2554: printf("Created directory '%s'.\n", dotsshdir);
2555: }
1.12 markus 2556: }
2557: /* If the file already exists, ask the user to confirm. */
2558: if (stat(identity_file, &st) >= 0) {
2559: char yesno[3];
2560: printf("%s already exists.\n", identity_file);
2561: printf("Overwrite (y/n)? ");
2562: fflush(stdout);
2563: if (fgets(yesno, sizeof(yesno), stdin) == NULL)
2564: exit(1);
2565: if (yesno[0] != 'y' && yesno[0] != 'Y')
2566: exit(1);
2567: }
2568: /* Ask for a passphrase (twice). */
2569: if (identity_passphrase)
2570: passphrase1 = xstrdup(identity_passphrase);
2571: else if (identity_new_passphrase)
2572: passphrase1 = xstrdup(identity_new_passphrase);
2573: else {
2574: passphrase_again:
2575: passphrase1 =
1.65 markus 2576: read_passphrase("Enter passphrase (empty for no "
2577: "passphrase): ", RP_ALLOW_STDIN);
2578: passphrase2 = read_passphrase("Enter same passphrase again: ",
2579: RP_ALLOW_STDIN);
1.12 markus 2580: if (strcmp(passphrase1, passphrase2) != 0) {
1.65 markus 2581: /*
2582: * The passphrases do not match. Clear them and
2583: * retry.
2584: */
1.12 markus 2585: memset(passphrase1, 0, strlen(passphrase1));
2586: memset(passphrase2, 0, strlen(passphrase2));
1.227 djm 2587: free(passphrase1);
2588: free(passphrase2);
1.12 markus 2589: printf("Passphrases do not match. Try again.\n");
2590: goto passphrase_again;
2591: }
2592: /* Clear the other copy of the passphrase. */
2593: memset(passphrase2, 0, strlen(passphrase2));
1.227 djm 2594: free(passphrase2);
1.12 markus 2595: }
2596:
2597: if (identity_comment) {
2598: strlcpy(comment, identity_comment, sizeof(comment));
2599: } else {
1.172 stevesk 2600: /* Create default comment field for the passphrase. */
1.12 markus 2601: snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
2602: }
2603:
2604: /* Save the key with the given passphrase and comment. */
1.52 markus 2605: if (!key_save_private(private, identity_file, passphrase1, comment)) {
1.56 markus 2606: printf("Saving the key failed: %s.\n", identity_file);
1.12 markus 2607: memset(passphrase1, 0, strlen(passphrase1));
1.227 djm 2608: free(passphrase1);
1.12 markus 2609: exit(1);
2610: }
2611: /* Clear the passphrase. */
2612: memset(passphrase1, 0, strlen(passphrase1));
1.227 djm 2613: free(passphrase1);
1.12 markus 2614:
2615: /* Clear the private key and the random number generator. */
1.33 markus 2616: key_free(private);
1.12 markus 2617: arc4random_stir();
2618:
2619: if (!quiet)
2620: printf("Your identification has been saved in %s.\n", identity_file);
2621:
2622: strlcat(identity_file, ".pub", sizeof(identity_file));
1.46 deraadt 2623: fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
2624: if (fd == -1) {
1.12 markus 2625: printf("Could not save your public key in %s\n", identity_file);
1.46 deraadt 2626: exit(1);
2627: }
2628: f = fdopen(fd, "w");
2629: if (f == NULL) {
1.173 tobias 2630: printf("fdopen %s failed\n", identity_file);
1.12 markus 2631: exit(1);
2632: }
1.19 markus 2633: if (!key_write(public, f))
1.173 tobias 2634: fprintf(stderr, "write key failed\n");
1.19 markus 2635: fprintf(f, " %s\n", comment);
1.12 markus 2636: fclose(f);
2637:
2638: if (!quiet) {
1.50 markus 2639: char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
1.167 grunk 2640: char *ra = key_fingerprint(public, SSH_FP_MD5,
2641: SSH_FP_RANDOMART);
1.19 markus 2642: printf("Your public key has been saved in %s.\n",
2643: identity_file);
1.12 markus 2644: printf("The key fingerprint is:\n");
1.50 markus 2645: printf("%s %s\n", fp, comment);
1.167 grunk 2646: printf("The key's randomart image is:\n");
2647: printf("%s\n", ra);
1.227 djm 2648: free(ra);
2649: free(fp);
1.12 markus 2650: }
1.19 markus 2651:
2652: key_free(public);
1.12 markus 2653: exit(0);
1.1 deraadt 2654: }