summaryrefslogtreecommitdiff
path: root/crypto/openssh/ssh-keygen.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/ssh-keygen.c')
-rw-r--r--crypto/openssh/ssh-keygen.c745
1 files changed, 0 insertions, 745 deletions
diff --git a/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c
deleted file mode 100644
index 874acfe92d639..0000000000000
--- a/crypto/openssh/ssh-keygen.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * Author: Tatu Ylonen <ylo@cs.hut.fi>
- * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
- * All rights reserved
- * Created: Mon Mar 27 02:26:40 1995 ylo
- * Identity and host key generation and maintenance.
- */
-
-#include "includes.h"
-RCSID("$Id: ssh-keygen.c,v 1.26 2000/05/30 17:32:06 markus Exp $");
-
-#include <openssl/evp.h>
-#include <openssl/pem.h>
-#include <openssl/rsa.h>
-#include <openssl/dsa.h>
-
-#include "ssh.h"
-#include "xmalloc.h"
-#include "fingerprint.h"
-#include "key.h"
-#include "rsa.h"
-#include "dsa.h"
-#include "authfile.h"
-#include "uuencode.h"
-
-/* Number of bits in the RSA/DSA key. This value can be changed on the command line. */
-int bits = 1024;
-
-/*
- * Flag indicating that we just want to change the passphrase. This can be
- * set on the command line.
- */
-int change_passphrase = 0;
-
-/*
- * Flag indicating that we just want to change the comment. This can be set
- * on the command line.
- */
-int change_comment = 0;
-
-int quiet = 0;
-
-/* Flag indicating that we just want to see the key fingerprint */
-int print_fingerprint = 0;
-
-/* The identity file name, given on the command line or entered by the user. */
-char identity_file[1024];
-int have_identity = 0;
-
-/* This is set to the passphrase if given on the command line. */
-char *identity_passphrase = NULL;
-
-/* This is set to the new passphrase if given on the command line. */
-char *identity_new_passphrase = NULL;
-
-/* This is set to the new comment if given on the command line. */
-char *identity_comment = NULL;
-
-/* Dump public key file in format used by real and the original SSH 2 */
-int convert_to_ssh2 = 0;
-int convert_from_ssh2 = 0;
-int print_public = 0;
-int dsa_mode = 0;
-
-/* argv0 */
-extern char *__progname;
-
-char hostname[MAXHOSTNAMELEN];
-
-void
-ask_filename(struct passwd *pw, const char *prompt)
-{
- char buf[1024];
- snprintf(identity_file, sizeof(identity_file), "%s/%s",
- pw->pw_dir,
- dsa_mode ? SSH_CLIENT_ID_DSA: SSH_CLIENT_IDENTITY);
- printf("%s (%s): ", prompt, identity_file);
- fflush(stdout);
- if (fgets(buf, sizeof(buf), stdin) == NULL)
- exit(1);
- if (strchr(buf, '\n'))
- *strchr(buf, '\n') = 0;
- if (strcmp(buf, "") != 0)
- strlcpy(identity_file, buf, sizeof(identity_file));
- have_identity = 1;
-}
-
-int
-try_load_key(char *filename, Key *k)
-{
- int success = 1;
- if (!load_private_key(filename, "", k, NULL)) {
- char *pass = read_passphrase("Enter passphrase: ", 1);
- if (!load_private_key(filename, pass, k, NULL)) {
- success = 0;
- }
- memset(pass, 0, strlen(pass));
- xfree(pass);
- }
- return success;
-}
-
-#define SSH_COM_MAGIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----"
-#define SSH_COM_MAGIC_END "---- END SSH2 PUBLIC KEY ----"
-
-void
-do_convert_to_ssh2(struct passwd *pw)
-{
- Key *k;
- int len;
- unsigned char *blob;
- struct stat st;
-
- if (!have_identity)
- ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0) {
- perror(identity_file);
- exit(1);
- }
- k = key_new(KEY_DSA);
- if (!try_load_key(identity_file, k)) {
- fprintf(stderr, "load failed\n");
- exit(1);
- }
- dsa_make_key_blob(k, &blob, &len);
- fprintf(stdout, SSH_COM_MAGIC_BEGIN "\n");
- fprintf(stdout,
- "Comment: \"%d-bit DSA, converted from openssh by %s@%s\"\n",
- BN_num_bits(k->dsa->p),
- pw->pw_name, hostname);
- dump_base64(stdout, blob, len);
- fprintf(stdout, SSH_COM_MAGIC_END "\n");
- key_free(k);
- xfree(blob);
- exit(0);
-}
-
-void
-do_convert_from_ssh2(struct passwd *pw)
-{
- Key *k;
- int blen;
- char line[1024], *p;
- char blob[8096];
- char encoded[8096];
- struct stat st;
- int escaped = 0;
- FILE *fp;
-
- if (!have_identity)
- ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0) {
- perror(identity_file);
- exit(1);
- }
- fp = fopen(identity_file, "r");
- if (fp == NULL) {
- perror(identity_file);
- exit(1);
- }
- encoded[0] = '\0';
- while (fgets(line, sizeof(line), fp)) {
- if (!(p = strchr(line, '\n'))) {
- fprintf(stderr, "input line too long.\n");
- exit(1);
- }
- if (p > line && p[-1] == '\\')
- escaped++;
- if (strncmp(line, "----", 4) == 0 ||
- strstr(line, ": ") != NULL) {
- fprintf(stderr, "ignore: %s", line);
- continue;
- }
- if (escaped) {
- escaped--;
- fprintf(stderr, "escaped: %s", line);
- continue;
- }
- *p = '\0';
- strlcat(encoded, line, sizeof(encoded));
- }
- blen = uudecode(encoded, (unsigned char *)blob, sizeof(blob));
- if (blen < 0) {
- fprintf(stderr, "uudecode failed.\n");
- exit(1);
- }
- k = dsa_key_from_blob(blob, blen);
- if (!key_write(k, stdout))
- fprintf(stderr, "key_write failed");
- key_free(k);
- fprintf(stdout, "\n");
- fclose(fp);
- exit(0);
-}
-
-void
-do_print_public(struct passwd *pw)
-{
- Key *k;
- int len;
- unsigned char *blob;
- struct stat st;
-
- if (!have_identity)
- ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0) {
- perror(identity_file);
- exit(1);
- }
- k = key_new(KEY_DSA);
- if (!try_load_key(identity_file, k)) {
- fprintf(stderr, "load failed\n");
- exit(1);
- }
- dsa_make_key_blob(k, &blob, &len);
- if (!key_write(k, stdout))
- fprintf(stderr, "key_write failed");
- key_free(k);
- xfree(blob);
- fprintf(stdout, "\n");
- exit(0);
-}
-
-void
-do_fingerprint(struct passwd *pw)
-{
- FILE *f;
- BIGNUM *e, *n;
- Key *public;
- char *comment = NULL, *cp, *ep, line[16*1024];
- int i, skip = 0, num = 1, invalid = 1;
- unsigned int ignore;
- struct stat st;
-
- if (!have_identity)
- ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0) {
- perror(identity_file);
- exit(1);
- }
- public = key_new(KEY_RSA);
- if (load_public_key(identity_file, public, &comment)) {
- printf("%d %s %s\n", BN_num_bits(public->rsa->n),
- key_fingerprint(public), comment);
- key_free(public);
- exit(0);
- }
- key_free(public);
-
- /* XXX */
- f = fopen(identity_file, "r");
- if (f != NULL) {
- n = BN_new();
- e = BN_new();
- while (fgets(line, sizeof(line), f)) {
- i = strlen(line) - 1;
- if (line[i] != '\n') {
- error("line %d too long: %.40s...", num, line);
- skip = 1;
- continue;
- }
- num++;
- if (skip) {
- skip = 0;
- continue;
- }
- line[i] = '\0';
-
- /* Skip leading whitespace, empty and comment lines. */
- for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
- ;
- if (!*cp || *cp == '\n' || *cp == '#')
- continue ;
- i = strtol(cp, &ep, 10);
- if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {
- int quoted = 0;
- comment = cp;
- for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
- if (*cp == '\\' && cp[1] == '"')
- cp++; /* Skip both */
- else if (*cp == '"')
- quoted = !quoted;
- }
- if (!*cp)
- continue;
- *cp++ = '\0';
- }
- ep = cp;
- if (auth_rsa_read_key(&cp, &ignore, e, n)) {
- invalid = 0;
- comment = *cp ? cp : comment;
- printf("%d %s %s\n", BN_num_bits(n),
- fingerprint(e, n),
- comment ? comment : "no comment");
- }
- }
- BN_free(e);
- BN_free(n);
- fclose(f);
- }
- if (invalid) {
- printf("%s is not a valid key file.\n", identity_file);
- exit(1);
- }
- exit(0);
-}
-
-/*
- * Perform changing a passphrase. The argument is the passwd structure
- * for the current user.
- */
-void
-do_change_passphrase(struct passwd *pw)
-{
- char *comment;
- char *old_passphrase, *passphrase1, *passphrase2;
- struct stat st;
- Key *private;
- Key *public;
- int type = dsa_mode ? KEY_DSA : KEY_RSA;
-
- if (!have_identity)
- ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0) {
- perror(identity_file);
- exit(1);
- }
-
- if (type == KEY_RSA) {
- /* XXX this works currently only for RSA */
- public = key_new(type);
- if (!load_public_key(identity_file, public, NULL)) {
- printf("%s is not a valid key file.\n", identity_file);
- exit(1);
- }
- /* Clear the public key since we are just about to load the whole file. */
- key_free(public);
- }
-
- /* Try to load the file with empty passphrase. */
- private = key_new(type);
- if (!load_private_key(identity_file, "", private, &comment)) {
- if (identity_passphrase)
- old_passphrase = xstrdup(identity_passphrase);
- else
- old_passphrase = read_passphrase("Enter old passphrase: ", 1);
- if (!load_private_key(identity_file, old_passphrase, private, &comment)) {
- memset(old_passphrase, 0, strlen(old_passphrase));
- xfree(old_passphrase);
- printf("Bad passphrase.\n");
- exit(1);
- }
- memset(old_passphrase, 0, strlen(old_passphrase));
- xfree(old_passphrase);
- }
- printf("Key has comment '%s'\n", comment);
-
- /* Ask the new passphrase (twice). */
- if (identity_new_passphrase) {
- passphrase1 = xstrdup(identity_new_passphrase);
- passphrase2 = NULL;
- } else {
- passphrase1 =
- read_passphrase("Enter new passphrase (empty for no passphrase): ", 1);
- passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
-
- /* Verify that they are the same. */
- if (strcmp(passphrase1, passphrase2) != 0) {
- memset(passphrase1, 0, strlen(passphrase1));
- memset(passphrase2, 0, strlen(passphrase2));
- xfree(passphrase1);
- xfree(passphrase2);
- printf("Pass phrases do not match. Try again.\n");
- exit(1);
- }
- /* Destroy the other copy. */
- memset(passphrase2, 0, strlen(passphrase2));
- xfree(passphrase2);
- }
-
- /* Save the file using the new passphrase. */
- if (!save_private_key(identity_file, passphrase1, private, comment)) {
- printf("Saving the key failed: %s: %s.\n",
- identity_file, strerror(errno));
- memset(passphrase1, 0, strlen(passphrase1));
- xfree(passphrase1);
- key_free(private);
- xfree(comment);
- exit(1);
- }
- /* Destroy the passphrase and the copy of the key in memory. */
- memset(passphrase1, 0, strlen(passphrase1));
- xfree(passphrase1);
- key_free(private); /* Destroys contents */
- xfree(comment);
-
- printf("Your identification has been saved with the new passphrase.\n");
- exit(0);
-}
-
-/*
- * Change the comment of a private key file.
- */
-void
-do_change_comment(struct passwd *pw)
-{
- char new_comment[1024], *comment;
- Key *private;
- Key *public;
- char *passphrase;
- struct stat st;
- FILE *f;
-
- if (!have_identity)
- ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0) {
- perror(identity_file);
- exit(1);
- }
- /*
- * Try to load the public key from the file the verify that it is
- * readable and of the proper format.
- */
- public = key_new(KEY_RSA);
- if (!load_public_key(identity_file, public, NULL)) {
- printf("%s is not a valid key file.\n", identity_file);
- exit(1);
- }
-
- private = key_new(KEY_RSA);
- if (load_private_key(identity_file, "", private, &comment))
- passphrase = xstrdup("");
- else {
- if (identity_passphrase)
- passphrase = xstrdup(identity_passphrase);
- else if (identity_new_passphrase)
- passphrase = xstrdup(identity_new_passphrase);
- else
- passphrase = read_passphrase("Enter passphrase: ", 1);
- /* Try to load using the passphrase. */
- if (!load_private_key(identity_file, passphrase, private, &comment)) {
- memset(passphrase, 0, strlen(passphrase));
- xfree(passphrase);
- printf("Bad passphrase.\n");
- exit(1);
- }
- }
- printf("Key now has comment '%s'\n", comment);
-
- if (identity_comment) {
- strlcpy(new_comment, identity_comment, sizeof(new_comment));
- } else {
- printf("Enter new comment: ");
- fflush(stdout);
- if (!fgets(new_comment, sizeof(new_comment), stdin)) {
- memset(passphrase, 0, strlen(passphrase));
- key_free(private);
- exit(1);
- }
- if (strchr(new_comment, '\n'))
- *strchr(new_comment, '\n') = 0;
- }
-
- /* Save the file using the new passphrase. */
- if (!save_private_key(identity_file, passphrase, private, new_comment)) {
- printf("Saving the key failed: %s: %s.\n",
- identity_file, strerror(errno));
- memset(passphrase, 0, strlen(passphrase));
- xfree(passphrase);
- key_free(private);
- xfree(comment);
- exit(1);
- }
- memset(passphrase, 0, strlen(passphrase));
- xfree(passphrase);
- key_free(private);
-
- strlcat(identity_file, ".pub", sizeof(identity_file));
- f = fopen(identity_file, "w");
- if (!f) {
- printf("Could not save your public key in %s\n", identity_file);
- exit(1);
- }
- if (!key_write(public, f))
- fprintf(stderr, "write key failed");
- key_free(public);
- fprintf(f, " %s\n", new_comment);
- fclose(f);
-
- xfree(comment);
-
- printf("The comment in your key file has been changed.\n");
- exit(0);
-}
-
-void
-usage(void)
-{
- printf("Usage: %s [-lpqxXydc] [-b bits] [-f file] [-C comment] [-N new-pass] [-P pass]\n", __progname);
- exit(1);
-}
-
-/*
- * Main program for key management.
- */
-int
-main(int ac, char **av)
-{
- char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2;
- struct passwd *pw;
- int opt;
- struct stat st;
- FILE *f;
- Key *private;
- Key *public;
- extern int optind;
- extern char *optarg;
-
- SSLeay_add_all_algorithms();
-
- /* we need this for the home * directory. */
- pw = getpwuid(getuid());
- if (!pw) {
- printf("You don't exist, go away!\n");
- exit(1);
- }
- if (gethostname(hostname, sizeof(hostname)) < 0) {
- perror("gethostname");
- exit(1);
- }
-
- while ((opt = getopt(ac, av, "dqpclRxXyb:f:P:N:C:")) != EOF) {
- switch (opt) {
- case 'b':
- bits = atoi(optarg);
- if (bits < 512 || bits > 32768) {
- printf("Bits has bad value.\n");
- exit(1);
- }
- break;
-
- case 'l':
- print_fingerprint = 1;
- break;
-
- case 'p':
- change_passphrase = 1;
- break;
-
- case 'c':
- change_comment = 1;
- break;
-
- case 'f':
- strlcpy(identity_file, optarg, sizeof(identity_file));
- have_identity = 1;
- break;
-
- case 'P':
- identity_passphrase = optarg;
- break;
-
- case 'N':
- identity_new_passphrase = optarg;
- break;
-
- case 'C':
- identity_comment = optarg;
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- case 'R':
- if (rsa_alive() == 0)
- exit(1);
- else
- exit(0);
- break;
-
- case 'x':
- convert_to_ssh2 = 1;
- break;
-
- case 'X':
- convert_from_ssh2 = 1;
- break;
-
- case 'y':
- print_public = 1;
- break;
-
- case 'd':
- dsa_mode = 1;
- break;
-
- case '?':
- default:
- usage();
- }
- }
- if (optind < ac) {
- printf("Too many arguments.\n");
- usage();
- }
- if (change_passphrase && change_comment) {
- printf("Can only have one of -p and -c.\n");
- usage();
- }
- /* check if RSA support is needed and exists */
- if (dsa_mode == 0 && rsa_alive() == 0) {
- fprintf(stderr,
- "%s: no RSA support in libssl and libcrypto. See ssl(8).\n",
- __progname);
- exit(1);
- }
- if (print_fingerprint)
- do_fingerprint(pw);
- if (change_passphrase)
- do_change_passphrase(pw);
- if (change_comment)
- do_change_comment(pw);
- if (convert_to_ssh2)
- do_convert_to_ssh2(pw);
- if (convert_from_ssh2)
- do_convert_from_ssh2(pw);
- if (print_public)
- do_print_public(pw);
-
- arc4random_stir();
-
- if (dsa_mode != 0) {
- if (!quiet)
- printf("Generating DSA parameter and key.\n");
- public = private = dsa_generate_key(bits);
- if (private == NULL) {
- fprintf(stderr, "dsa_generate_keys failed");
- exit(1);
- }
- } else {
- if (quiet)
- rsa_set_verbose(0);
- /* Generate the rsa key pair. */
- public = key_new(KEY_RSA);
- private = key_new(KEY_RSA);
- rsa_generate_key(private->rsa, public->rsa, bits);
- }
-
- if (!have_identity)
- ask_filename(pw, "Enter file in which to save the key");
-
- /* Create ~/.ssh directory if it doesn\'t already exist. */
- snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, SSH_USER_DIR);
- if (strstr(identity_file, dotsshdir) != NULL &&
- stat(dotsshdir, &st) < 0) {
- if (mkdir(dotsshdir, 0755) < 0)
- error("Could not create directory '%s'.", dotsshdir);
- else if (!quiet)
- printf("Created directory '%s'.\n", dotsshdir);
- }
- /* If the file already exists, ask the user to confirm. */
- if (stat(identity_file, &st) >= 0) {
- char yesno[3];
- printf("%s already exists.\n", identity_file);
- printf("Overwrite (y/n)? ");
- fflush(stdout);
- if (fgets(yesno, sizeof(yesno), stdin) == NULL)
- exit(1);
- if (yesno[0] != 'y' && yesno[0] != 'Y')
- exit(1);
- }
- /* Ask for a passphrase (twice). */
- if (identity_passphrase)
- passphrase1 = xstrdup(identity_passphrase);
- else if (identity_new_passphrase)
- passphrase1 = xstrdup(identity_new_passphrase);
- else {
-passphrase_again:
- passphrase1 =
- read_passphrase("Enter passphrase (empty for no passphrase): ", 1);
- passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
- if (strcmp(passphrase1, passphrase2) != 0) {
- /* The passphrases do not match. Clear them and retry. */
- memset(passphrase1, 0, strlen(passphrase1));
- memset(passphrase2, 0, strlen(passphrase2));
- xfree(passphrase1);
- xfree(passphrase2);
- printf("Passphrases do not match. Try again.\n");
- goto passphrase_again;
- }
- /* Clear the other copy of the passphrase. */
- memset(passphrase2, 0, strlen(passphrase2));
- xfree(passphrase2);
- }
-
- if (identity_comment) {
- strlcpy(comment, identity_comment, sizeof(comment));
- } else {
- /* Create default commend field for the passphrase. */
- snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
- }
-
- /* Save the key with the given passphrase and comment. */
- if (!save_private_key(identity_file, passphrase1, private, comment)) {
- printf("Saving the key failed: %s: %s.\n",
- identity_file, strerror(errno));
- memset(passphrase1, 0, strlen(passphrase1));
- xfree(passphrase1);
- exit(1);
- }
- /* Clear the passphrase. */
- memset(passphrase1, 0, strlen(passphrase1));
- xfree(passphrase1);
-
- /* Clear the private key and the random number generator. */
- if (private != public) {
- key_free(private);
- }
- arc4random_stir();
-
- if (!quiet)
- printf("Your identification has been saved in %s.\n", identity_file);
-
- strlcat(identity_file, ".pub", sizeof(identity_file));
- f = fopen(identity_file, "w");
- if (!f) {
- printf("Could not save your public key in %s\n", identity_file);
- exit(1);
- }
- if (!key_write(public, f))
- fprintf(stderr, "write key failed");
- fprintf(f, " %s\n", comment);
- fclose(f);
-
- if (!quiet) {
- printf("Your public key has been saved in %s.\n",
- identity_file);
- printf("The key fingerprint is:\n");
- printf("%s %s\n", key_fingerprint(public), comment);
- }
-
- key_free(public);
- exit(0);
-}