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

Diff for /src/usr.bin/ssh/ssh-keygen.c between version 1.134 and 1.163

version 1.134, 2005/11/28 05:16:53 version 1.163, 2007/10/02 17:49:58
Line 1 
Line 1 
   /* $OpenBSD$ */
 /*  /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>   * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland   * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
Line 11 
Line 12 
  * called by a name other than "ssh" or "Secure Shell".   * called by a name other than "ssh" or "Secure Shell".
  */   */
   
 #include "includes.h"  #include <sys/types.h>
 RCSID("$OpenBSD$");  #include <sys/stat.h>
   #include <sys/socket.h>
   #include <sys/param.h>
   
 #include <openssl/evp.h>  #include <openssl/evp.h>
 #include <openssl/pem.h>  #include <openssl/pem.h>
   
   #include <errno.h>
   #include <fcntl.h>
   #include <pwd.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <unistd.h>
   
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "key.h"  #include "key.h"
 #include "rsa.h"  #include "rsa.h"
 #include "authfile.h"  #include "authfile.h"
 #include "uuencode.h"  #include "uuencode.h"
 #include "buffer.h"  #include "buffer.h"
 #include "bufaux.h"  
 #include "pathnames.h"  #include "pathnames.h"
 #include "log.h"  #include "log.h"
 #include "misc.h"  #include "misc.h"
 #include "match.h"  #include "match.h"
 #include "hostfile.h"  #include "hostfile.h"
   #include "dns.h"
   
 #ifdef SMARTCARD  #ifdef SMARTCARD
 #include "scard.h"  #include "scard.h"
 #endif  #endif
 #include "dns.h"  
   
 /* Number of bits in the RSA/DSA key.  This value can be set on the command line. */  /* Number of bits in the RSA/DSA key.  This value can be set on the command line. */
 #define DEFAULT_BITS            2048  #define DEFAULT_BITS            2048
Line 103 
Line 113 
   
         if (key_type_name == NULL)          if (key_type_name == NULL)
                 name = _PATH_SSH_CLIENT_ID_RSA;                  name = _PATH_SSH_CLIENT_ID_RSA;
         else          else {
                 switch (key_type_from_name(key_type_name)) {                  switch (key_type_from_name(key_type_name)) {
                 case KEY_RSA1:                  case KEY_RSA1:
                         name = _PATH_SSH_CLIENT_IDENTITY;                          name = _PATH_SSH_CLIENT_IDENTITY;
Line 119 
Line 129 
                         exit(1);                          exit(1);
                         break;                          break;
                 }                  }
           }
         snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name);          snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name);
         fprintf(stderr, "%s (%s): ", prompt, identity_file);          fprintf(stderr, "%s (%s): ", prompt, identity_file);
         if (fgets(buf, sizeof(buf), stdin) == NULL)          if (fgets(buf, sizeof(buf), stdin) == NULL)
                 exit(1);                  exit(1);
         if (strchr(buf, '\n'))          buf[strcspn(buf, "\n")] = '\0';
                 *strchr(buf, '\n') = 0;  
         if (strcmp(buf, "") != 0)          if (strcmp(buf, "") != 0)
                 strlcpy(identity_file, buf, sizeof(identity_file));                  strlcpy(identity_file, buf, sizeof(identity_file));
         have_identity = 1;          have_identity = 1;
Line 205 
Line 214 
         if (buffer_len(b) < bytes)          if (buffer_len(b) < bytes)
                 fatal("buffer_get_bignum_bits: input buffer too small: "                  fatal("buffer_get_bignum_bits: input buffer too small: "
                     "need %d have %d", bytes, buffer_len(b));                      "need %d have %d", bytes, buffer_len(b));
         BN_bin2bn(buffer_ptr(b), bytes, value);          if (BN_bin2bn(buffer_ptr(b), bytes, value) == NULL)
                   fatal("buffer_get_bignum_bits: BN_bin2bn failed");
         buffer_consume(b, bytes);          buffer_consume(b, bytes);
 }  }
   
Line 223 
Line 233 
         buffer_init(&b);          buffer_init(&b);
         buffer_append(&b, blob, blen);          buffer_append(&b, blob, blen);
   
         magic  = buffer_get_int(&b);          magic = buffer_get_int(&b);
         if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {          if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {
                 error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC);                  error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC);
                 buffer_free(&b);                  buffer_free(&b);
Line 235 
Line 245 
         i2 = buffer_get_int(&b);          i2 = buffer_get_int(&b);
         i3 = buffer_get_int(&b);          i3 = buffer_get_int(&b);
         i4 = buffer_get_int(&b);          i4 = buffer_get_int(&b);
         debug("ignore (%d %d %d %d)", i1,i2,i3,i4);          debug("ignore (%d %d %d %d)", i1, i2, i3, i4);
         if (strcmp(cipher, "none") != 0) {          if (strcmp(cipher, "none") != 0) {
                 error("unsupported cipher %s", cipher);                  error("unsupported cipher %s", cipher);
                 xfree(cipher);                  xfree(cipher);
Line 266 
Line 276 
                 buffer_get_bignum_bits(&b, key->dsa->priv_key);                  buffer_get_bignum_bits(&b, key->dsa->priv_key);
                 break;                  break;
         case KEY_RSA:          case KEY_RSA:
                 e  = buffer_get_char(&b);                  e = buffer_get_char(&b);
                 debug("e %lx", e);                  debug("e %lx", e);
                 if (e < 30) {                  if (e < 30) {
                         e <<= 8;                          e <<= 8;
Line 302 
Line 312 
         return key;          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';
           }
           /* We reached EOF */
           return -1;
   }
   
 static void  static void
 do_convert_from_ssh2(struct passwd *pw)  do_convert_from_ssh2(struct passwd *pw)
 {  {
         Key *k;          Key *k;
         int blen;          int blen;
         u_int len;          u_int len;
         char line[1024], *p;          char line[1024];
         u_char blob[8096];          u_char blob[8096];
         char encoded[8096];          char encoded[8096];
         struct stat st;          struct stat st;
Line 327 
Line 367 
                 exit(1);                  exit(1);
         }          }
         encoded[0] = '\0';          encoded[0] = '\0';
         while (fgets(line, sizeof(line), fp)) {          while ((blen = get_line(fp, line, sizeof(line))) != -1) {
                 if (!(p = strchr(line, '\n'))) {                  if (line[blen - 1] == '\\')
                         fprintf(stderr, "input line too long.\n");  
                         exit(1);  
                 }  
                 if (p > line && p[-1] == '\\')  
                         escaped++;                          escaped++;
                 if (strncmp(line, "----", 4) == 0 ||                  if (strncmp(line, "----", 4) == 0 ||
                     strstr(line, ": ") != NULL) {                      strstr(line, ": ") != NULL) {
Line 349 
Line 385 
                         /* fprintf(stderr, "escaped: %s", line); */                          /* fprintf(stderr, "escaped: %s", line); */
                         continue;                          continue;
                 }                  }
                 *p = '\0';  
                 strlcat(encoded, line, sizeof(encoded));                  strlcat(encoded, line, sizeof(encoded));
         }          }
         len = strlen(encoded);          len = strlen(encoded);
Line 485 
Line 520 
                 xfree(fp);                  xfree(fp);
                 exit(0);                  exit(0);
         }          }
         if (comment)          if (comment) {
                 xfree(comment);                  xfree(comment);
                   comment = NULL;
           }
   
         f = fopen(identity_file, "r");          f = fopen(identity_file, "r");
         if (f != NULL) {          if (f != NULL) {
                 while (fgets(line, sizeof(line), f)) {                  while (fgets(line, sizeof(line), f)) {
                         i = strlen(line) - 1;                          if ((cp = strchr(line, '\n')) == NULL) {
                         if (line[i] != '\n') {  
                                 error("line %d too long: %.40s...", num, line);                                  error("line %d too long: %.40s...", num, line);
                                 skip = 1;                                  skip = 1;
                                 continue;                                  continue;
Line 502 
Line 538 
                                 skip = 0;                                  skip = 0;
                                 continue;                                  continue;
                         }                          }
                         line[i] = '\0';                          *cp = '\0';
   
                         /* Skip leading whitespace, empty and comment lines. */                          /* Skip leading whitespace, empty and comment lines. */
                         for (cp = line; *cp == ' ' || *cp == '\t'; cp++)                          for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
                                 ;                                  ;
                         if (!*cp || *cp == '\n' || *cp == '#')                          if (!*cp || *cp == '\n' || *cp == '#')
                                 continue ;                                  continue;
                         i = strtol(cp, &ep, 10);                          i = strtol(cp, &ep, 10);
                         if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {                          if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {
                                 int quoted = 0;                                  int quoted = 0;
Line 570 
Line 606 
         Key *public;          Key *public;
         char *cp, *cp2, *kp, *kp2;          char *cp, *cp2, *kp, *kp2;
         char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN];          char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN];
         int c, i, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0;          int c, skip = 0, inplace = 0, num = 1, invalid = 0, has_unhashed = 0;
   
         if (!have_identity) {          if (!have_identity) {
                 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);                  cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
Line 605 
Line 641 
         }          }
   
         while (fgets(line, sizeof(line), in)) {          while (fgets(line, sizeof(line), in)) {
                 num++;                  if ((cp = strchr(line, '\n')) == NULL) {
                 i = strlen(line) - 1;  
                 if (line[i] != '\n') {  
                         error("line %d too long: %.40s...", num, line);                          error("line %d too long: %.40s...", num, line);
                         skip = 1;                          skip = 1;
                         invalid = 1;                          invalid = 1;
                         continue;                          continue;
                 }                  }
                   num++;
                 if (skip) {                  if (skip) {
                         skip = 0;                          skip = 0;
                         continue;                          continue;
                 }                  }
                 line[i] = '\0';                  *cp = '\0';
   
                 /* Skip leading whitespace, empty and comment lines. */                  /* Skip leading whitespace, empty and comment lines. */
                 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)                  for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
Line 832 
Line 867 
 /*  /*
  * Print the SSHFP RR.   * Print the SSHFP RR.
  */   */
 static void  static int
 do_print_resource_record(struct passwd *pw, char *hname)  do_print_resource_record(struct passwd *pw, char *fname, char *hname)
 {  {
         Key *public;          Key *public;
         char *comment = NULL;          char *comment = NULL;
         struct stat st;          struct stat st;
   
         if (!have_identity)          if (fname == NULL)
                 ask_filename(pw, "Enter file in which the key is");                  ask_filename(pw, "Enter file in which the key is");
         if (stat(identity_file, &st) < 0) {          if (stat(fname, &st) < 0) {
                 perror(identity_file);                  if (errno == ENOENT)
                           return 0;
                   perror(fname);
                 exit(1);                  exit(1);
         }          }
         public = key_load_public(identity_file, &comment);          public = key_load_public(fname, &comment);
         if (public != NULL) {          if (public != NULL) {
                 export_dns_rr(hname, public, stdout, print_generic);                  export_dns_rr(hname, public, stdout, print_generic);
                 key_free(public);                  key_free(public);
                 xfree(comment);                  xfree(comment);
                 exit(0);                  return 1;
         }          }
         if (comment)          if (comment)
                 xfree(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);          exit(1);
 }  }
   
Line 915 
Line 952 
                         key_free(private);                          key_free(private);
                         exit(1);                          exit(1);
                 }                  }
                 if (strchr(new_comment, '\n'))                  new_comment[strcspn(new_comment, "\n")] = '\0';
                         *strchr(new_comment, '\n') = 0;  
         }          }
   
         /* Save the file using the new passphrase. */          /* Save the file using the new passphrase. */
Line 959 
Line 995 
 static void  static void
 usage(void)  usage(void)
 {  {
         fprintf(stderr, "Usage: %s [options]\n", __progname);          fprintf(stderr, "usage: %s [options]\n", __progname);
         fprintf(stderr, "Options:\n");          fprintf(stderr, "Options:\n");
         fprintf(stderr, "  -a trials   Number of trials for screening DH-GEX moduli.\n");          fprintf(stderr, "  -a trials   Number of trials for screening DH-GEX moduli.\n");
         fprintf(stderr, "  -B          Show bubblebabble digest of key file.\n");          fprintf(stderr, "  -B          Show bubblebabble digest of key file.\n");
Line 969 
Line 1005 
 #ifdef SMARTCARD  #ifdef SMARTCARD
         fprintf(stderr, "  -D reader   Download public key from smartcard.\n");          fprintf(stderr, "  -D reader   Download public key from smartcard.\n");
 #endif /* SMARTCARD */  #endif /* SMARTCARD */
         fprintf(stderr, "  -e          Convert OpenSSH to IETF SECSH key file.\n");          fprintf(stderr, "  -e          Convert OpenSSH to RFC 4716 key file.\n");
         fprintf(stderr, "  -F hostname Find hostname in known hosts file.\n");          fprintf(stderr, "  -F hostname Find hostname in known hosts file.\n");
         fprintf(stderr, "  -f filename Filename of the key file.\n");          fprintf(stderr, "  -f filename Filename of the key file.\n");
         fprintf(stderr, "  -G file     Generate candidates for DH-GEX moduli.\n");          fprintf(stderr, "  -G file     Generate candidates for DH-GEX moduli.\n");
         fprintf(stderr, "  -g          Use generic DNS resource record format.\n");          fprintf(stderr, "  -g          Use generic DNS resource record format.\n");
         fprintf(stderr, "  -H          Hash names in known_hosts file.\n");          fprintf(stderr, "  -H          Hash names in known_hosts file.\n");
         fprintf(stderr, "  -i          Convert IETF SECSH to OpenSSH key file.\n");          fprintf(stderr, "  -i          Convert RFC 4716 to OpenSSH key file.\n");
         fprintf(stderr, "  -l          Show fingerprint of key file.\n");          fprintf(stderr, "  -l          Show fingerprint of key file.\n");
         fprintf(stderr, "  -M memory   Amount of memory (MB) to use for generating DH-GEX moduli.\n");          fprintf(stderr, "  -M memory   Amount of memory (MB) to use for generating DH-GEX moduli.\n");
         fprintf(stderr, "  -N phrase   Provide new passphrase.\n");          fprintf(stderr, "  -N phrase   Provide new passphrase.\n");
Line 1001 
Line 1037 
  * Main program for key management.   * Main program for key management.
  */   */
 int  int
 main(int ac, char **av)  main(int argc, char **argv)
 {  {
         char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;          char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
         char out_file[MAXPATHLEN], *reader_id = NULL;          char out_file[MAXPATHLEN], *reader_id = NULL;
Line 1024 
Line 1060 
         sanitise_stdfd();          sanitise_stdfd();
   
         SSLeay_add_all_algorithms();          SSLeay_add_all_algorithms();
         log_init(av[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);          log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
   
         /* we need this for the home * directory.  */          /* we need this for the home * directory.  */
         pw = getpwuid(getuid());          pw = getpwuid(getuid());
Line 1037 
Line 1073 
                 exit(1);                  exit(1);
         }          }
   
         while ((opt = getopt(ac, av,          while ((opt = getopt(argc, argv,
             "degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) {              "degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) {
                 switch (opt) {                  switch (opt) {
                 case 'b':                  case 'b':
                         bits = strtonum(optarg, 768, 32768, &errstr);                          bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr);
                         if (errstr)                          if (errstr)
                                 fatal("Bits has bad value %s (%s)",                                  fatal("Bits has bad value %s (%s)",
                                         optarg, errstr);                                          optarg, errstr);
Line 1111 
Line 1147 
                         break;                          break;
                 case 'D':                  case 'D':
                         download = 1;                          download = 1;
                           /*FALLTHROUGH*/
                 case 'U':                  case 'U':
                         reader_id = optarg;                          reader_id = optarg;
                         break;                          break;
Line 1127 
Line 1164 
                         rr_hostname = optarg;                          rr_hostname = optarg;
                         break;                          break;
                 case 'W':                  case 'W':
                         generator_wanted = strtonum(optarg, 1, UINT_MAX, &errstr);                          generator_wanted = (u_int32_t)strtonum(optarg, 1,
                               UINT_MAX, &errstr);
                         if (errstr)                          if (errstr)
                                 fatal("Desired generator has bad value: %s (%s)",                                  fatal("Desired generator has bad value: %s (%s)",
                                         optarg, errstr);                                          optarg, errstr);
                         break;                          break;
                 case 'a':                  case 'a':
                         trials = strtonum(optarg, 1, UINT_MAX, &errstr);                          trials = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
                         if (errstr)                          if (errstr)
                                 fatal("Invalid number of trials: %s (%s)",                                  fatal("Invalid number of trials: %s (%s)",
                                         optarg, errstr);                                          optarg, errstr);
                         break;                          break;
                 case 'M':                  case 'M':
                         memory = strtonum(optarg, 1, UINT_MAX, &errstr);                          memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
                         if (errstr) {                          if (errstr) {
                                 fatal("Memory limit is %s: %s", errstr, optarg);                                  fatal("Memory limit is %s: %s", errstr, optarg);
                         }                          }
Line 1168 
Line 1206 
         }          }
   
         /* reinit */          /* reinit */
         log_init(av[0], log_level, SYSLOG_FACILITY_USER, 1);          log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
   
         if (optind < ac) {          if (optind < argc) {
                 printf("Too many arguments.\n");                  printf("Too many arguments.\n");
                 usage();                  usage();
         }          }
Line 1193 
Line 1231 
         if (print_public)          if (print_public)
                 do_print_public(pw);                  do_print_public(pw);
         if (rr_hostname != NULL) {          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) {          if (reader_id != NULL) {
 #ifdef SMARTCARD  #ifdef SMARTCARD
Line 1254 
Line 1312 
                 fprintf(stderr, "unknown key type %s\n", key_type_name);                  fprintf(stderr, "unknown key type %s\n", key_type_name);
                 exit(1);                  exit(1);
         }          }
           if (bits == 0)
                   bits = (type == KEY_DSA) ? DEFAULT_BITS_DSA : DEFAULT_BITS;
         if (type == KEY_DSA && bits != 1024)          if (type == KEY_DSA && bits != 1024)
                 fatal("DSA keys must be 1024 bits");                  fatal("DSA keys must be 1024 bits");
         if (!quiet)          if (!quiet)
                 printf("Generating public/private %s key pair.\n", key_type_name);                  printf("Generating public/private %s key pair.\n", key_type_name);
         if (bits == 0)  
                 bits = (type == KEY_DSA) ? DEFAULT_BITS_DSA : DEFAULT_BITS;  
         private = key_generate(type, bits);          private = key_generate(type, bits);
         if (private == NULL) {          if (private == NULL) {
                 fprintf(stderr, "key_generate failed");                  fprintf(stderr, "key_generate failed");

Legend:
Removed from v.1.134  
changed lines
  Added in v.1.163