[BACK]Return to ssh-keygen.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/ssh-keygen.c, Revision 1.215

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