+/* $OpenBSD: ssh-keygen.c,v 1.149 2006/07/17 01:31:10 stevesk Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh-keygen.c,v 1.130 2005/10/07 11:13:57 markus Exp $");
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
+#include <errno.h>
+#include <fcntl.h>
+#if defined(HAVE_NETDB_H)
+# include <netdb.h>
+#endif
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+#endif
+#include <pwd.h>
+#include <unistd.h>
+
#include "xmalloc.h"
#include "key.h"
#include "rsa.h"
#include "misc.h"
#include "match.h"
#include "hostfile.h"
+#include "dns.h"
#ifdef SMARTCARD
#include "scard.h"
#endif
-#include "dns.h"
/* Number of bits in the RSA/DSA key. This value can be set on the command line. */
#define DEFAULT_BITS 2048
if (key_type_name == NULL)
name = _PATH_SSH_CLIENT_ID_RSA;
- else
+ else {
switch (key_type_from_name(key_type_name)) {
case KEY_RSA1:
name = _PATH_SSH_CLIENT_IDENTITY;
exit(1);
break;
}
-
+ }
snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name);
fprintf(stderr, "%s (%s): ", prompt, identity_file);
if (fgets(buf, sizeof(buf), stdin) == NULL)
return key;
}
+static int
+get_line(FILE *fp, char *line, size_t len)
+{
+ int c;
+ size_t pos = 0;
+
+ line[0] = '\0';
+ while ((c = fgetc(fp)) != EOF) {
+ if (pos >= len - 1) {
+ fprintf(stderr, "input line too long.\n");
+ exit(1);
+ }
+ switch (c) {
+ case '\r':
+ c = fgetc(fp);
+ if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) {
+ fprintf(stderr, "unget: %s\n", strerror(errno));
+ exit(1);
+ }
+ return pos;
+ case '\n':
+ return pos;
+ }
+ line[pos++] = c;
+ line[pos] = '\0';
+ }
+ if (c == EOF)
+ return -1;
+ return pos;
+}
+
static void
do_convert_from_ssh2(struct passwd *pw)
{
Key *k;
int blen;
u_int len;
- char line[1024], *p;
+ char line[1024];
u_char blob[8096];
char encoded[8096];
struct stat st;
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] == '\\')
+ while ((blen = get_line(fp, line, sizeof(line))) != -1) {
+ if (line[blen - 1] == '\\')
escaped++;
if (strncmp(line, "----", 4) == 0 ||
strstr(line, ": ") != NULL) {
/* fprintf(stderr, "escaped: %s", line); */
continue;
}
- *p = '\0';
strlcat(encoded, line, sizeof(encoded));
}
len = strlen(encoded);
xfree(fp);
exit(0);
}
- if (comment)
+ if (comment) {
xfree(comment);
+ comment = NULL;
+ }
f = fopen(identity_file, "r");
if (f != NULL) {
/*
* Print the SSHFP RR.
*/
-static void
-do_print_resource_record(struct passwd *pw, char *hname)
+static int
+do_print_resource_record(struct passwd *pw, char *fname, char *hname)
{
Key *public;
char *comment = NULL;
struct stat st;
- if (!have_identity)
+ if (fname == NULL)
ask_filename(pw, "Enter file in which the key is");
- if (stat(identity_file, &st) < 0) {
- perror(identity_file);
+ if (stat(fname, &st) < 0) {
+ if (errno == ENOENT)
+ return 0;
+ perror(fname);
exit(1);
}
- public = key_load_public(identity_file, &comment);
+ public = key_load_public(fname, &comment);
if (public != NULL) {
export_dns_rr(hname, public, stdout, print_generic);
key_free(public);
xfree(comment);
- exit(0);
+ return 1;
}
if (comment)
xfree(comment);
- printf("failed to read v2 public key from %s.\n", identity_file);
+ printf("failed to read v2 public key from %s.\n", fname);
exit(1);
}
"degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) {
switch (opt) {
case 'b':
- bits = strtonum(optarg, 512, 32768, &errstr);
+ bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr);
if (errstr)
fatal("Bits has bad value %s (%s)",
optarg, errstr);
break;
case 'D':
download = 1;
+ /*FALLTHROUGH*/
case 'U':
reader_id = optarg;
break;
rr_hostname = optarg;
break;
case 'W':
- generator_wanted = strtonum(optarg, 1, UINT_MAX, &errstr);
+ generator_wanted = (u_int32_t)strtonum(optarg, 1,
+ UINT_MAX, &errstr);
if (errstr)
fatal("Desired generator has bad value: %s (%s)",
optarg, errstr);
break;
case 'a':
- trials = strtonum(optarg, 1, UINT_MAX, &errstr);
+ trials = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
if (errstr)
fatal("Invalid number of trials: %s (%s)",
optarg, errstr);
break;
case 'M':
- memory = strtonum(optarg, 1, UINT_MAX, &errstr);
+ memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
if (errstr) {
fatal("Memory limit is %s: %s", errstr, optarg);
}
if (print_public)
do_print_public(pw);
if (rr_hostname != NULL) {
- do_print_resource_record(pw, rr_hostname);
+ unsigned int n = 0;
+
+ if (have_identity) {
+ n = do_print_resource_record(pw,
+ identity_file, rr_hostname);
+ if (n == 0) {
+ perror(identity_file);
+ exit(1);
+ }
+ exit(0);
+ } else {
+
+ n += do_print_resource_record(pw,
+ _PATH_HOST_RSA_KEY_FILE, rr_hostname);
+ n += do_print_resource_record(pw,
+ _PATH_HOST_DSA_KEY_FILE, rr_hostname);
+
+ if (n == 0)
+ fatal("no keys found.");
+ exit(0);
+ }
}
if (reader_id != NULL) {
#ifdef SMARTCARD
if (bits == 0)
bits = DEFAULT_BITS;
if (gen_candidates(out, memory, bits, start) != 0)
- fatal("modulus candidate generation failed\n");
+ fatal("modulus candidate generation failed");
return (0);
}
out_file, strerror(errno));
}
if (prime_test(in, out, trials, generator_wanted) != 0)
- fatal("modulus screening failed\n");
+ fatal("modulus screening failed");
return (0);
}
arc4random_stir();
- if (key_type_name == NULL) {
- printf("You must specify a key type (-t).\n");
- usage();
- }
+ if (key_type_name == NULL)
+ key_type_name = "rsa";
+
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);
if (bits == 0)
bits = (type == KEY_DSA) ? DEFAULT_BITS_DSA : DEFAULT_BITS;
+ if (type == KEY_DSA && bits != 1024)
+ fatal("DSA keys must be 1024 bits");
+ 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");
if (!have_identity)
ask_filename(pw, "Enter file in which to save the key");
- /* Create ~/.ssh directory if it doesn\'t already exist. */
+ /* Create ~/.ssh directory if it doesn't already exist. */
snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, _PATH_SSH_USER_DIR);
if (strstr(identity_file, dotsshdir) != NULL &&
stat(dotsshdir, &st) < 0) {