[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.21

1.1       deraadt     1: /*
1.13      deraadt     2:  * Author: Tatu Ylonen <ylo@cs.hut.fi>
                      3:  * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                      4:  *                    All rights reserved
                      5:  * Created: Mon Mar 27 02:26:40 1995 ylo
                      6:  * Identity and host key generation and maintenance.
                      7:  */
1.1       deraadt     8:
                      9: #include "includes.h"
1.21    ! markus     10: RCSID("$Id: ssh-keygen.c,v 1.20 2000/04/26 21:55:04 deraadt Exp $");
1.19      markus     11:
                     12: #include <openssl/evp.h>
                     13: #include <openssl/pem.h>
                     14: #include <openssl/rsa.h>
                     15: #include <openssl/dsa.h>
1.1       deraadt    16:
                     17: #include "ssh.h"
                     18: #include "xmalloc.h"
1.8       markus     19: #include "fingerprint.h"
1.19      markus     20: #include "key.h"
                     21: #include "rsa.h"
                     22: #include "dsa.h"
                     23: #include "authfile.h"
                     24: #include "uuencode.h"
1.1       deraadt    25:
1.19      markus     26: /* Number of bits in the RSA/DSA key.  This value can be changed on the command line. */
1.1       deraadt    27: int bits = 1024;
                     28:
1.14      markus     29: /*
                     30:  * Flag indicating that we just want to change the passphrase.  This can be
                     31:  * set on the command line.
                     32:  */
1.1       deraadt    33: int change_passphrase = 0;
                     34:
1.14      markus     35: /*
                     36:  * Flag indicating that we just want to change the comment.  This can be set
                     37:  * on the command line.
                     38:  */
1.1       deraadt    39: int change_comment = 0;
                     40:
1.2       provos     41: int quiet = 0;
                     42:
1.8       markus     43: /* Flag indicating that we just want to see the key fingerprint */
                     44: int print_fingerprint = 0;
                     45:
1.10      markus     46: /* The identity file name, given on the command line or entered by the user. */
                     47: char identity_file[1024];
                     48: int have_identity = 0;
1.1       deraadt    49:
                     50: /* This is set to the passphrase if given on the command line. */
                     51: char *identity_passphrase = NULL;
                     52:
                     53: /* This is set to the new passphrase if given on the command line. */
                     54: char *identity_new_passphrase = NULL;
                     55:
                     56: /* This is set to the new comment if given on the command line. */
                     57: char *identity_comment = NULL;
                     58:
1.19      markus     59: /* Dump public key file in format used by real and the original SSH 2 */
                     60: int convert_to_ssh2 = 0;
                     61: int convert_from_ssh2 = 0;
                     62: int print_public = 0;
                     63: int dsa_mode = 0;
                     64:
1.10      markus     65: /* argv0 */
                     66: extern char *__progname;
1.1       deraadt    67:
1.19      markus     68: char hostname[MAXHOSTNAMELEN];
                     69:
1.10      markus     70: void
                     71: ask_filename(struct passwd *pw, const char *prompt)
1.1       deraadt    72: {
1.12      markus     73:        char buf[1024];
                     74:        snprintf(identity_file, sizeof(identity_file), "%s/%s",
                     75:                 pw->pw_dir, SSH_CLIENT_IDENTITY);
                     76:        printf("%s (%s): ", prompt, identity_file);
                     77:        fflush(stdout);
                     78:        if (fgets(buf, sizeof(buf), stdin) == NULL)
                     79:                exit(1);
                     80:        if (strchr(buf, '\n'))
                     81:                *strchr(buf, '\n') = 0;
                     82:        if (strcmp(buf, "") != 0)
                     83:                strlcpy(identity_file, buf, sizeof(identity_file));
                     84:        have_identity = 1;
1.7       markus     85: }
                     86:
1.19      markus     87: int
                     88: try_load_key(char *filename, Key *k)
                     89: {
                     90:        int success = 1;
                     91:        if (!load_private_key(filename, "", k, NULL)) {
                     92:                char *pass = read_passphrase("Enter passphrase: ", 1);
                     93:                if (!load_private_key(filename, pass, k, NULL)) {
                     94:                        success = 0;
                     95:                }
                     96:                memset(pass, 0, strlen(pass));
                     97:                xfree(pass);
                     98:        }
                     99:        return success;
                    100: }
                    101:
                    102: #define SSH_COM_MAGIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----"
                    103: #define SSH_COM_MAGIC_END   "---- END SSH2 PUBLIC KEY ----"
                    104:
                    105: void
                    106: do_convert_to_ssh2(struct passwd *pw)
                    107: {
                    108:        Key *k;
                    109:        int len;
                    110:        unsigned char *blob;
                    111:        struct stat st;
                    112:
                    113:        if (!have_identity)
                    114:                ask_filename(pw, "Enter file in which the key is");
                    115:        if (stat(identity_file, &st) < 0) {
                    116:                perror(identity_file);
                    117:                exit(1);
                    118:        }
                    119:        k = key_new(KEY_DSA);
                    120:        if (!try_load_key(identity_file, k)) {
                    121:                fprintf(stderr, "load failed\n");
                    122:                exit(1);
                    123:        }
                    124:        dsa_make_key_blob(k, &blob, &len);
                    125:        fprintf(stdout, SSH_COM_MAGIC_BEGIN "\n");
                    126:        fprintf(stdout,
                    127:            "Comment: \"%d-bit DSA, converted from openssh by %s@%s\"\n",
                    128:            BN_num_bits(k->dsa->p),
                    129:            pw->pw_name, hostname);
                    130:        dump_base64(stdout, blob, len);
                    131:        fprintf(stdout, SSH_COM_MAGIC_END "\n");
                    132:        key_free(k);
1.21    ! markus    133:        xfree(blob);
1.19      markus    134:        exit(0);
                    135: }
                    136:
                    137: void
                    138: do_convert_from_ssh2(struct passwd *pw)
                    139: {
                    140:        Key *k;
                    141:        int blen;
                    142:        char line[1024], *p;
                    143:        char blob[8096];
                    144:        char encoded[8096];
                    145:        struct stat st;
                    146:        FILE *fp;
                    147:
                    148:        if (!have_identity)
                    149:                ask_filename(pw, "Enter file in which the key is");
                    150:        if (stat(identity_file, &st) < 0) {
                    151:                perror(identity_file);
                    152:                exit(1);
                    153:        }
                    154:        fp = fopen(identity_file, "r");
                    155:        if (fp == NULL) {
                    156:                perror(identity_file);
                    157:                exit(1);
                    158:        }
                    159:        encoded[0] = '\0';
                    160:        while (fgets(line, sizeof(line), fp)) {
                    161:                if (strncmp(line, "----", 4) == 0 ||
                    162:                    strstr(line, ": ") != NULL) {
                    163:                        fprintf(stderr, "ignore: %s", line);
                    164:                        continue;
                    165:                }
                    166:                if (!(p = strchr(line, '\n'))) {
                    167:                        fprintf(stderr, "input line too long.\n");
                    168:                        exit(1);
                    169:                }
                    170:                *p = '\0';
                    171:                strlcat(encoded, line, sizeof(encoded));
                    172:        }
                    173:        blen = uudecode(encoded, (unsigned char *)blob, sizeof(blob));
                    174:        if (blen < 0) {
                    175:                fprintf(stderr, "uudecode failed.\n");
                    176:                exit(1);
                    177:        }
                    178:        k = dsa_key_from_blob(blob, blen);
                    179:        if (!key_write(k, stdout))
                    180:                fprintf(stderr, "key_write failed");
                    181:        key_free(k);
                    182:        fprintf(stdout, "\n");
                    183:        fclose(fp);
                    184:        exit(0);
                    185: }
                    186:
                    187: void
                    188: do_print_public(struct passwd *pw)
                    189: {
                    190:        Key *k;
                    191:        int len;
                    192:        unsigned char *blob;
                    193:        struct stat st;
                    194:
                    195:        if (!have_identity)
                    196:                ask_filename(pw, "Enter file in which the key is");
                    197:        if (stat(identity_file, &st) < 0) {
                    198:                perror(identity_file);
                    199:                exit(1);
                    200:        }
                    201:        k = key_new(KEY_DSA);
                    202:        if (!try_load_key(identity_file, k)) {
                    203:                fprintf(stderr, "load failed\n");
                    204:                exit(1);
                    205:        }
                    206:        dsa_make_key_blob(k, &blob, &len);
                    207:        if (!key_write(k, stdout))
                    208:                fprintf(stderr, "key_write failed");
                    209:        key_free(k);
1.21    ! markus    210:        xfree(blob);
1.19      markus    211:        fprintf(stdout, "\n");
                    212:        exit(0);
                    213: }
                    214:
1.7       markus    215: void
1.8       markus    216: do_fingerprint(struct passwd *pw)
                    217: {
1.15      markus    218:        FILE *f;
                    219:        BIGNUM *e, *n;
1.19      markus    220:        Key *public;
1.16      markus    221:        char *comment = NULL, *cp, *ep, line[16*1024];
1.15      markus    222:        int i, skip = 0, num = 1, invalid = 1;
1.17      markus    223:        unsigned int ignore;
1.12      markus    224:        struct stat st;
                    225:
                    226:        if (!have_identity)
                    227:                ask_filename(pw, "Enter file in which the key is");
                    228:        if (stat(identity_file, &st) < 0) {
                    229:                perror(identity_file);
                    230:                exit(1);
                    231:        }
1.19      markus    232:        public = key_new(KEY_RSA);
                    233:        if (load_public_key(identity_file, public, &comment)) {
                    234:                printf("%d %s %s\n", BN_num_bits(public->rsa->n),
                    235:                    key_fingerprint(public), comment);
                    236:                key_free(public);
1.15      markus    237:                exit(0);
                    238:        }
1.19      markus    239:        key_free(public);
1.15      markus    240:
1.19      markus    241:        /* XXX */
1.15      markus    242:        f = fopen(identity_file, "r");
                    243:        if (f != NULL) {
1.12      markus    244:                n = BN_new();
                    245:                e = BN_new();
1.15      markus    246:                while (fgets(line, sizeof(line), f)) {
                    247:                        i = strlen(line) - 1;
                    248:                        if (line[i] != '\n') {
                    249:                                error("line %d too long: %.40s...", num, line);
                    250:                                skip = 1;
                    251:                                continue;
                    252:                        }
                    253:                        num++;
                    254:                        if (skip) {
                    255:                                skip = 0;
                    256:                                continue;
                    257:                        }
                    258:                        line[i] = '\0';
                    259:
                    260:                        /* Skip leading whitespace, empty and comment lines. */
                    261:                        for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
                    262:                                ;
                    263:                        if (!*cp || *cp == '\n' || *cp == '#')
                    264:                                continue ;
                    265:                        i = strtol(cp, &ep, 10);
                    266:                        if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {
                    267:                                int quoted = 0;
                    268:                                comment = cp;
                    269:                                for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
                    270:                                        if (*cp == '\\' && cp[1] == '"')
                    271:                                                cp++;   /* Skip both */
                    272:                                        else if (*cp == '"')
                    273:                                                quoted = !quoted;
                    274:                                }
                    275:                                if (!*cp)
                    276:                                        continue;
                    277:                                *cp++ = '\0';
                    278:                        }
                    279:                        ep = cp;
1.17      markus    280:                        if (auth_rsa_read_key(&cp, &ignore, e, n)) {
1.15      markus    281:                                invalid = 0;
                    282:                                comment = *cp ? cp : comment;
                    283:                                printf("%d %s %s\n", BN_num_bits(n),
                    284:                                    fingerprint(e, n),
                    285:                                    comment ? comment : "no comment");
1.12      markus    286:                        }
                    287:                }
1.15      markus    288:                BN_free(e);
                    289:                BN_free(n);
                    290:                fclose(f);
                    291:        }
                    292:        if (invalid) {
                    293:                printf("%s is not a valid key file.\n", identity_file);
                    294:                exit(1);
1.12      markus    295:        }
                    296:        exit(0);
1.8       markus    297: }
                    298:
1.13      deraadt   299: /*
                    300:  * Perform changing a passphrase.  The argument is the passwd structure
                    301:  * for the current user.
                    302:  */
1.8       markus    303: void
1.7       markus    304: do_change_passphrase(struct passwd *pw)
                    305: {
1.12      markus    306:        char *comment;
                    307:        char *old_passphrase, *passphrase1, *passphrase2;
                    308:        struct stat st;
1.19      markus    309:        Key *private;
                    310:        Key *public;
                    311:        int type = dsa_mode ? KEY_DSA : KEY_RSA;
1.12      markus    312:
                    313:        if (!have_identity)
                    314:                ask_filename(pw, "Enter file in which the key is");
                    315:        if (stat(identity_file, &st) < 0) {
                    316:                perror(identity_file);
                    317:                exit(1);
                    318:        }
1.19      markus    319:
                    320:        if (type == KEY_RSA) {
                    321:                /* XXX this works currently only for RSA */
                    322:                public = key_new(type);
                    323:                if (!load_public_key(identity_file, public, NULL)) {
                    324:                        printf("%s is not a valid key file.\n", identity_file);
                    325:                        exit(1);
                    326:                }
                    327:                /* Clear the public key since we are just about to load the whole file. */
                    328:                key_free(public);
1.12      markus    329:        }
                    330:
                    331:        /* Try to load the file with empty passphrase. */
1.19      markus    332:        private = key_new(type);
                    333:        if (!load_private_key(identity_file, "", private, &comment)) {
1.12      markus    334:                if (identity_passphrase)
                    335:                        old_passphrase = xstrdup(identity_passphrase);
                    336:                else
                    337:                        old_passphrase = read_passphrase("Enter old passphrase: ", 1);
1.19      markus    338:                if (!load_private_key(identity_file, old_passphrase, private, &comment)) {
1.12      markus    339:                        memset(old_passphrase, 0, strlen(old_passphrase));
                    340:                        xfree(old_passphrase);
                    341:                        printf("Bad passphrase.\n");
                    342:                        exit(1);
                    343:                }
                    344:                memset(old_passphrase, 0, strlen(old_passphrase));
                    345:                xfree(old_passphrase);
                    346:        }
                    347:        printf("Key has comment '%s'\n", comment);
                    348:
                    349:        /* Ask the new passphrase (twice). */
                    350:        if (identity_new_passphrase) {
                    351:                passphrase1 = xstrdup(identity_new_passphrase);
                    352:                passphrase2 = NULL;
                    353:        } else {
                    354:                passphrase1 =
                    355:                        read_passphrase("Enter new passphrase (empty for no passphrase): ", 1);
                    356:                passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
                    357:
                    358:                /* Verify that they are the same. */
                    359:                if (strcmp(passphrase1, passphrase2) != 0) {
                    360:                        memset(passphrase1, 0, strlen(passphrase1));
                    361:                        memset(passphrase2, 0, strlen(passphrase2));
                    362:                        xfree(passphrase1);
                    363:                        xfree(passphrase2);
                    364:                        printf("Pass phrases do not match.  Try again.\n");
                    365:                        exit(1);
                    366:                }
                    367:                /* Destroy the other copy. */
                    368:                memset(passphrase2, 0, strlen(passphrase2));
                    369:                xfree(passphrase2);
                    370:        }
                    371:
                    372:        /* Save the file using the new passphrase. */
1.19      markus    373:        if (!save_private_key(identity_file, passphrase1, private, comment)) {
1.12      markus    374:                printf("Saving the key failed: %s: %s.\n",
                    375:                       identity_file, strerror(errno));
                    376:                memset(passphrase1, 0, strlen(passphrase1));
                    377:                xfree(passphrase1);
1.19      markus    378:                key_free(private);
1.12      markus    379:                xfree(comment);
                    380:                exit(1);
                    381:        }
                    382:        /* Destroy the passphrase and the copy of the key in memory. */
                    383:        memset(passphrase1, 0, strlen(passphrase1));
                    384:        xfree(passphrase1);
1.19      markus    385:        key_free(private);               /* Destroys contents */
1.12      markus    386:        xfree(comment);
1.1       deraadt   387:
1.12      markus    388:        printf("Your identification has been saved with the new passphrase.\n");
                    389:        exit(0);
1.1       deraadt   390: }
                    391:
1.13      deraadt   392: /*
                    393:  * Change the comment of a private key file.
                    394:  */
1.2       provos    395: void
                    396: do_change_comment(struct passwd *pw)
1.1       deraadt   397: {
1.12      markus    398:        char new_comment[1024], *comment;
1.19      markus    399:        Key *private;
                    400:        Key *public;
1.12      markus    401:        char *passphrase;
                    402:        struct stat st;
                    403:        FILE *f;
                    404:
                    405:        if (!have_identity)
                    406:                ask_filename(pw, "Enter file in which the key is");
                    407:        if (stat(identity_file, &st) < 0) {
                    408:                perror(identity_file);
                    409:                exit(1);
                    410:        }
1.14      markus    411:        /*
                    412:         * Try to load the public key from the file the verify that it is
                    413:         * readable and of the proper format.
                    414:         */
1.19      markus    415:        public = key_new(KEY_RSA);
                    416:        if (!load_public_key(identity_file, public, NULL)) {
1.12      markus    417:                printf("%s is not a valid key file.\n", identity_file);
                    418:                exit(1);
                    419:        }
1.14      markus    420:
1.19      markus    421:        private = key_new(KEY_RSA);
                    422:        if (load_private_key(identity_file, "", private, &comment))
1.12      markus    423:                passphrase = xstrdup("");
                    424:        else {
                    425:                if (identity_passphrase)
                    426:                        passphrase = xstrdup(identity_passphrase);
                    427:                else if (identity_new_passphrase)
                    428:                        passphrase = xstrdup(identity_new_passphrase);
                    429:                else
                    430:                        passphrase = read_passphrase("Enter passphrase: ", 1);
                    431:                /* Try to load using the passphrase. */
1.19      markus    432:                if (!load_private_key(identity_file, passphrase, private, &comment)) {
1.12      markus    433:                        memset(passphrase, 0, strlen(passphrase));
                    434:                        xfree(passphrase);
                    435:                        printf("Bad passphrase.\n");
                    436:                        exit(1);
                    437:                }
                    438:        }
                    439:        printf("Key now has comment '%s'\n", comment);
                    440:
                    441:        if (identity_comment) {
                    442:                strlcpy(new_comment, identity_comment, sizeof(new_comment));
                    443:        } else {
                    444:                printf("Enter new comment: ");
                    445:                fflush(stdout);
                    446:                if (!fgets(new_comment, sizeof(new_comment), stdin)) {
                    447:                        memset(passphrase, 0, strlen(passphrase));
1.19      markus    448:                        key_free(private);
1.12      markus    449:                        exit(1);
                    450:                }
                    451:                if (strchr(new_comment, '\n'))
                    452:                        *strchr(new_comment, '\n') = 0;
                    453:        }
                    454:
                    455:        /* Save the file using the new passphrase. */
1.19      markus    456:        if (!save_private_key(identity_file, passphrase, private, new_comment)) {
1.12      markus    457:                printf("Saving the key failed: %s: %s.\n",
                    458:                       identity_file, strerror(errno));
                    459:                memset(passphrase, 0, strlen(passphrase));
                    460:                xfree(passphrase);
1.19      markus    461:                key_free(private);
1.12      markus    462:                xfree(comment);
                    463:                exit(1);
                    464:        }
                    465:        memset(passphrase, 0, strlen(passphrase));
                    466:        xfree(passphrase);
1.19      markus    467:        key_free(private);
1.12      markus    468:
                    469:        strlcat(identity_file, ".pub", sizeof(identity_file));
                    470:        f = fopen(identity_file, "w");
                    471:        if (!f) {
                    472:                printf("Could not save your public key in %s\n", identity_file);
                    473:                exit(1);
                    474:        }
1.19      markus    475:        if (!key_write(public, f))
                    476:                fprintf(stderr, "write key failed");
                    477:        key_free(public);
                    478:        fprintf(f, " %s\n", new_comment);
1.12      markus    479:        fclose(f);
1.1       deraadt   480:
1.12      markus    481:        xfree(comment);
1.1       deraadt   482:
1.12      markus    483:        printf("The comment in your key file has been changed.\n");
                    484:        exit(0);
1.1       deraadt   485: }
                    486:
1.10      markus    487: void
                    488: usage(void)
                    489: {
1.12      markus    490:        printf("ssh-keygen version %s\n", SSH_VERSION);
1.19      markus    491:        printf("Usage: %s [-b bits] [-p] [-c] [-l] [-x] [-X] [-y] [-f file] [-P pass] [-N new-pass] [-C comment]\n", __progname);
1.12      markus    492:        exit(1);
1.10      markus    493: }
                    494:
1.13      deraadt   495: /*
                    496:  * Main program for key management.
                    497:  */
1.2       provos    498: int
                    499: main(int ac, char **av)
1.1       deraadt   500: {
1.12      markus    501:        char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2;
                    502:        struct passwd *pw;
                    503:        int opt;
                    504:        struct stat st;
                    505:        FILE *f;
1.19      markus    506:        Key *private;
                    507:        Key *public;
1.12      markus    508:        extern int optind;
                    509:        extern char *optarg;
                    510:
1.19      markus    511:        OpenSSL_add_all_algorithms();
                    512:
1.14      markus    513:        /* we need this for the home * directory.  */
1.12      markus    514:        pw = getpwuid(getuid());
                    515:        if (!pw) {
                    516:                printf("You don't exist, go away!\n");
                    517:                exit(1);
                    518:        }
1.19      markus    519:        if (gethostname(hostname, sizeof(hostname)) < 0) {
                    520:                perror("gethostname");
                    521:                exit(1);
                    522:        }
1.14      markus    523:
1.20      deraadt   524:        while ((opt = getopt(ac, av, "dqpclRxXyb:f:P:N:C:")) != EOF) {
1.12      markus    525:                switch (opt) {
                    526:                case 'b':
                    527:                        bits = atoi(optarg);
                    528:                        if (bits < 512 || bits > 32768) {
                    529:                                printf("Bits has bad value.\n");
                    530:                                exit(1);
                    531:                        }
                    532:                        break;
                    533:
                    534:                case 'l':
                    535:                        print_fingerprint = 1;
                    536:                        break;
                    537:
                    538:                case 'p':
                    539:                        change_passphrase = 1;
                    540:                        break;
                    541:
                    542:                case 'c':
                    543:                        change_comment = 1;
                    544:                        break;
                    545:
                    546:                case 'f':
                    547:                        strlcpy(identity_file, optarg, sizeof(identity_file));
                    548:                        have_identity = 1;
                    549:                        break;
                    550:
                    551:                case 'P':
                    552:                        identity_passphrase = optarg;
                    553:                        break;
                    554:
                    555:                case 'N':
                    556:                        identity_new_passphrase = optarg;
                    557:                        break;
                    558:
                    559:                case 'C':
                    560:                        identity_comment = optarg;
                    561:                        break;
                    562:
                    563:                case 'q':
                    564:                        quiet = 1;
1.20      deraadt   565:                        break;
                    566:
                    567:                case 'R':
                    568:                        if (rsa_alive() == 0)
                    569:                                exit(1);
                    570:                        else
                    571:                                exit(0);
1.12      markus    572:                        break;
                    573:
1.19      markus    574:                case 'x':
                    575:                        convert_to_ssh2 = 1;
                    576:                        break;
                    577:
                    578:                case 'X':
                    579:                        convert_from_ssh2 = 1;
                    580:                        break;
                    581:
                    582:                case 'y':
                    583:                        print_public = 1;
                    584:                        break;
                    585:
                    586:                case 'd':
                    587:                        dsa_mode = 1;
                    588:                        break;
                    589:
1.12      markus    590:                case '?':
                    591:                default:
                    592:                        usage();
                    593:                }
                    594:        }
                    595:        if (optind < ac) {
                    596:                printf("Too many arguments.\n");
                    597:                usage();
                    598:        }
                    599:        if (change_passphrase && change_comment) {
                    600:                printf("Can only have one of -p and -c.\n");
                    601:                usage();
                    602:        }
1.19      markus    603:        /* check if RSA support is needed and exists */
                    604:        if (dsa_mode == 0 && rsa_alive() == 0) {
                    605:                fprintf(stderr,
                    606:                        "%s: no RSA support in libssl and libcrypto.  See ssl(8).\n",
                    607:                        __progname);
                    608:                exit(1);
                    609:        }
1.12      markus    610:        if (print_fingerprint)
                    611:                do_fingerprint(pw);
                    612:        if (change_passphrase)
                    613:                do_change_passphrase(pw);
                    614:        if (change_comment)
                    615:                do_change_comment(pw);
1.19      markus    616:        if (convert_to_ssh2)
                    617:                do_convert_to_ssh2(pw);
                    618:        if (convert_from_ssh2)
                    619:                do_convert_from_ssh2(pw);
                    620:        if (print_public)
                    621:                do_print_public(pw);
1.12      markus    622:
                    623:        arc4random_stir();
                    624:
1.19      markus    625:        if (dsa_mode != 0) {
                    626:                if (!quiet)
                    627:                        printf("Generating DSA parameter and key.\n");
                    628:                public = private = dsa_generate_key(bits);
                    629:                if (private == NULL) {
                    630:                        fprintf(stderr, "dsa_generate_keys failed");
                    631:                        exit(1);
                    632:                }
                    633:        } else {
                    634:                if (quiet)
                    635:                        rsa_set_verbose(0);
                    636:                /* Generate the rsa key pair. */
                    637:                public = key_new(KEY_RSA);
                    638:                private = key_new(KEY_RSA);
                    639:                rsa_generate_key(private->rsa, public->rsa, bits);
                    640:        }
1.12      markus    641:
                    642:        if (!have_identity)
                    643:                ask_filename(pw, "Enter file in which to save the key");
                    644:
                    645:        /* Create ~/.ssh directory if it doesn\'t already exist. */
                    646:        snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, SSH_USER_DIR);
                    647:        if (strstr(identity_file, dotsshdir) != NULL &&
                    648:            stat(dotsshdir, &st) < 0) {
                    649:                if (mkdir(dotsshdir, 0755) < 0)
                    650:                        error("Could not create directory '%s'.", dotsshdir);
                    651:                else if (!quiet)
                    652:                        printf("Created directory '%s'.\n", dotsshdir);
                    653:        }
                    654:        /* If the file already exists, ask the user to confirm. */
                    655:        if (stat(identity_file, &st) >= 0) {
                    656:                char yesno[3];
                    657:                printf("%s already exists.\n", identity_file);
                    658:                printf("Overwrite (y/n)? ");
                    659:                fflush(stdout);
                    660:                if (fgets(yesno, sizeof(yesno), stdin) == NULL)
                    661:                        exit(1);
                    662:                if (yesno[0] != 'y' && yesno[0] != 'Y')
                    663:                        exit(1);
                    664:        }
                    665:        /* Ask for a passphrase (twice). */
                    666:        if (identity_passphrase)
                    667:                passphrase1 = xstrdup(identity_passphrase);
                    668:        else if (identity_new_passphrase)
                    669:                passphrase1 = xstrdup(identity_new_passphrase);
                    670:        else {
                    671: passphrase_again:
                    672:                passphrase1 =
                    673:                        read_passphrase("Enter passphrase (empty for no passphrase): ", 1);
                    674:                passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
                    675:                if (strcmp(passphrase1, passphrase2) != 0) {
                    676:                        /* The passphrases do not match.  Clear them and retry. */
                    677:                        memset(passphrase1, 0, strlen(passphrase1));
                    678:                        memset(passphrase2, 0, strlen(passphrase2));
                    679:                        xfree(passphrase1);
                    680:                        xfree(passphrase2);
                    681:                        printf("Passphrases do not match.  Try again.\n");
                    682:                        goto passphrase_again;
                    683:                }
                    684:                /* Clear the other copy of the passphrase. */
                    685:                memset(passphrase2, 0, strlen(passphrase2));
                    686:                xfree(passphrase2);
                    687:        }
                    688:
                    689:        if (identity_comment) {
                    690:                strlcpy(comment, identity_comment, sizeof(comment));
                    691:        } else {
1.18      markus    692:                /* Create default commend field for the passphrase. */
1.12      markus    693:                snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
                    694:        }
                    695:
                    696:        /* Save the key with the given passphrase and comment. */
1.19      markus    697:        if (!save_private_key(identity_file, passphrase1, private, comment)) {
1.12      markus    698:                printf("Saving the key failed: %s: %s.\n",
1.19      markus    699:                    identity_file, strerror(errno));
1.12      markus    700:                memset(passphrase1, 0, strlen(passphrase1));
                    701:                xfree(passphrase1);
                    702:                exit(1);
                    703:        }
                    704:        /* Clear the passphrase. */
                    705:        memset(passphrase1, 0, strlen(passphrase1));
                    706:        xfree(passphrase1);
                    707:
                    708:        /* Clear the private key and the random number generator. */
1.19      markus    709:        if (private != public) {
                    710:                key_free(private);
                    711:        }
1.12      markus    712:        arc4random_stir();
                    713:
                    714:        if (!quiet)
                    715:                printf("Your identification has been saved in %s.\n", identity_file);
                    716:
                    717:        strlcat(identity_file, ".pub", sizeof(identity_file));
                    718:        f = fopen(identity_file, "w");
                    719:        if (!f) {
                    720:                printf("Could not save your public key in %s\n", identity_file);
                    721:                exit(1);
                    722:        }
1.19      markus    723:        if (!key_write(public, f))
                    724:                fprintf(stderr, "write key failed");
                    725:        fprintf(f, " %s\n", comment);
1.12      markus    726:        fclose(f);
                    727:
                    728:        if (!quiet) {
1.19      markus    729:                printf("Your public key has been saved in %s.\n",
                    730:                    identity_file);
1.12      markus    731:                printf("The key fingerprint is:\n");
1.19      markus    732:                printf("%s %s\n", key_fingerprint(public), comment);
1.12      markus    733:        }
1.19      markus    734:
                    735:        key_free(public);
1.12      markus    736:        exit(0);
1.1       deraadt   737: }