*/
#include "includes.h"
-RCSID("$OpenBSD: ssh-keygen.c,v 1.32 2000/10/09 21:30:44 markus Exp $");
+RCSID("$OpenBSD: ssh-keygen.c,v 1.45 2001/02/22 08:03:51 deraadt Exp $");
#include <openssl/evp.h>
#include <openssl/pem.h>
-#include <openssl/rsa.h>
-#include <openssl/dsa.h>
-#include "ssh.h"
#include "xmalloc.h"
#include "key.h"
-#include "rsa.h"
-#include "dsa.h"
#include "authfile.h"
#include "uuencode.h"
-
#include "buffer.h"
#include "bufaux.h"
+#include "pathnames.h"
+#include "log.h"
+#include "readpass.h"
/* Number of bits in the RSA/DSA key. This value can be changed on the command line. */
int bits = 1024;
int convert_to_ssh2 = 0;
int convert_from_ssh2 = 0;
int print_public = 0;
-int dsa_mode = 0;
+
+/* default to RSA for SSH-1 */
+char *key_type_name = "rsa1";
/* argv0 */
#ifdef HAVE___PROGNAME
extern char *__progname;
-#else /* HAVE___PROGNAME */
-static const char *__progname = "ssh-keygen";
-#endif /* HAVE___PROGNAME */
+#else
+char *__progname;
+#endif
char hostname[MAXHOSTNAMELEN];
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);
+ char *name = NULL;
+
+ switch (key_type_from_name(key_type_name)) {
+ case KEY_RSA1:
+ name = _PATH_SSH_CLIENT_IDENTITY;
+ break;
+ case KEY_DSA:
+ name = _PATH_SSH_CLIENT_ID_DSA;
+ break;
+ case KEY_RSA:
+ name = _PATH_SSH_CLIENT_ID_RSA;
+ break;
+ default:
+ fprintf(stderr, "bad key type");
+ exit(1);
+ break;
+ }
+ snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name);
+ fprintf(stderr, "%s (%s): ", prompt, identity_file);
+ fflush(stderr);
if (fgets(buf, sizeof(buf), stdin) == NULL)
exit(1);
if (strchr(buf, '\n'))
#define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----"
#define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----"
#define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
-#define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb
+#define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb
void
do_convert_to_ssh2(struct passwd *pw)
{
Key *k;
int len;
- unsigned char *blob;
+ u_char *blob;
struct stat st;
if (!have_identity)
perror(identity_file);
exit(1);
}
- k = key_new(KEY_DSA);
+ k = key_new(KEY_UNSPEC);
if (!try_load_key(identity_file, k)) {
fprintf(stderr, "load failed\n");
exit(1);
}
- dsa_make_key_blob(k, &blob, &len);
+ key_to_blob(k, &blob, &len);
fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
fprintf(stdout,
"Comment: \"%d-bit %s, converted from OpenSSH by %s@%s\"\n",
int bytes = (bits + 7) / 8;
if (buffer_len(b) < bytes)
fatal("buffer_get_bignum_bits: input buffer too small");
- BN_bin2bn((unsigned char *)buffer_ptr(b), bytes, value);
+ BN_bin2bn((u_char *)buffer_ptr(b), bytes, value);
buffer_consume(b, bytes);
}
*p = '\0';
strlcat(encoded, line, sizeof(encoded));
}
- blen = uudecode(encoded, (unsigned char *)blob, sizeof(blob));
+ blen = uudecode(encoded, (u_char *)blob, sizeof(blob));
if (blen < 0) {
fprintf(stderr, "uudecode failed.\n");
exit(1);
}
k = private ?
do_convert_private_ssh2_from_blob(blob, blen) :
- dsa_key_from_blob(blob, blen);
+ key_from_blob(blob, blen);
if (k == NULL) {
fprintf(stderr, "decode blob failed.\n");
exit(1);
do_print_public(struct passwd *pw)
{
Key *k;
- int len;
- unsigned char *blob;
struct stat st;
if (!have_identity)
perror(identity_file);
exit(1);
}
- k = key_new(KEY_DSA);
+ k = key_new(KEY_UNSPEC);
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)
{
- /* XXX RSA1 only */
FILE *f;
Key *public;
char *comment = NULL, *cp, *ep, line[16*1024];
- int i, skip = 0, num = 1, invalid = 1;
- unsigned int ignore;
+ int i, skip = 0, num = 1, invalid = 1, success = 0;
struct stat st;
if (!have_identity)
perror(identity_file);
exit(1);
}
- public = key_new(KEY_RSA);
+ public = key_new(KEY_RSA1);
if (load_public_key(identity_file, public, &comment)) {
- printf("%d %s %s\n", BN_num_bits(public->rsa->n),
- key_fingerprint(public), comment);
+ success = 1;
+ } else {
+ key_free(public);
+ public = key_new(KEY_UNSPEC);
+ if (try_load_public_key(identity_file, public, &comment))
+ success = 1;
+ else
+ debug("try_load_public_key KEY_UNSPEC failed");
+ }
+ if (success) {
+ printf("%d %s %s\n", key_size(public), key_fingerprint(public), comment);
key_free(public);
+ xfree(comment);
exit(0);
}
*cp++ = '\0';
}
ep = cp;
- if (auth_rsa_read_key(&cp, &ignore, public->rsa->e, public->rsa->n)) {
- invalid = 0;
- comment = *cp ? cp : comment;
- printf("%d %s %s\n", key_size(public),
- key_fingerprint(public),
- comment ? comment : "no comment");
+ public = key_new(KEY_RSA1);
+ if (key_read(public, &cp) != 1) {
+ cp = ep;
+ key_free(public);
+ public = key_new(KEY_UNSPEC);
+ if (key_read(public, &cp) != 1) {
+ key_free(public);
+ continue;
+ }
}
+ comment = *cp ? cp : comment;
+ printf("%d %s %s\n", key_size(public),
+ key_fingerprint(public),
+ comment ? comment : "no comment");
+ invalid = 0;
}
fclose(f);
}
struct stat st;
Key *private;
Key *public;
- int type = dsa_mode ? KEY_DSA : KEY_RSA;
+ int type = KEY_RSA1;
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
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);
- }
+ public = key_new(type);
+ if (!load_public_key(identity_file, public, NULL)) {
+ type = KEY_UNSPEC;
+ } else {
/* 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)) {
* 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);
+ public = key_new(KEY_RSA1);
if (!load_public_key(identity_file, public, NULL)) {
printf("%s is not a valid key file.\n", identity_file);
+ printf("Comments are only supported in RSA1 keys\n");
exit(1);
}
- private = key_new(KEY_RSA);
+ private = key_new(KEY_RSA1);
if (load_private_key(identity_file, "", private, &comment))
passphrase = xstrdup("");
else {
void
usage(void)
{
- printf("Usage: %s [-lpqxXydc] [-b bits] [-f file] [-C comment] [-N new-pass] [-P pass]\n", __progname);
+ printf("Usage: %s [-lpqxXyc] [-t type] [-b bits] [-f file] [-C comment] "
+ "[-N new-pass] [-P pass]\n", __progname);
exit(1);
}
{
char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2;
struct passwd *pw;
- int opt;
+ int opt, type;
struct stat st;
FILE *f;
Key *private;
Key *public;
+
extern int optind;
extern char *optarg;
+ __progname = get_progname(av[0]);
init_rng();
SSLeay_add_all_algorithms();
exit(1);
}
- while ((opt = getopt(ac, av, "dqpclRxXyb:f:P:N:C:")) != EOF) {
+ while ((opt = getopt(ac, av, "dqpclRxXyb:f:t:P:N:C:")) != -1) {
switch (opt) {
case 'b':
bits = atoi(optarg);
break;
case 'R':
- if (rsa_alive() == 0)
- exit(1);
- else
- exit(0);
+ /* unused */
+ exit(0);
break;
case 'x':
break;
case 'd':
- dsa_mode = 1;
+ key_type_name = "dsa";
+ break;
+
+ case 't':
+ key_type_name = optarg;
break;
case '?':
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)
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);
+ type = key_type_from_name(key_type_name);
+ if (type == KEY_UNSPEC) {
+ fprintf(stderr, "unknown key type %s\n", key_type_name);
+ exit(1);
+ }
+ if (!quiet)
+ printf("Generating public/private %s key pair.\n", key_type_name);
+ private = key_generate(type, bits);
+ if (private == NULL) {
+ fprintf(stderr, "key_generate failed");
+ exit(1);
}
+ public = key_from_private(private);
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);
+ snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, _PATH_SSH_USER_DIR);
if (strstr(identity_file, dotsshdir) != NULL &&
stat(dotsshdir, &st) < 0) {
if (mkdir(dotsshdir, 0700) < 0)
xfree(passphrase1);
/* Clear the private key and the random number generator. */
- if (private != public) {
- key_free(private);
- }
+ key_free(private);
arc4random_stir();
if (!quiet)