[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.275 and 1.280

version 1.275, 2015/07/03 03:43:18 version 1.280, 2015/11/18 08:37:28
Line 212 
Line 212 
                 fatal("key bits exceeds maximum %d", maxbits);                  fatal("key bits exceeds maximum %d", maxbits);
         if (type == KEY_DSA && *bitsp != 1024)          if (type == KEY_DSA && *bitsp != 1024)
                 fatal("DSA keys must be 1024 bits");                  fatal("DSA keys must be 1024 bits");
         else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768)          else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 1024)
                 fatal("Key must at least be 768 bits");                  fatal("Key must at least be 1024 bits");
         else if (type == KEY_ECDSA && sshkey_ecdsa_bits_to_nid(*bitsp) == -1)          else if (type == KEY_ECDSA && sshkey_ecdsa_bits_to_nid(*bitsp) == -1)
                 fatal("Invalid ECDSA key length - valid lengths are "                  fatal("Invalid ECDSA key length - valid lengths are "
                     "256, 384 or 521 bits");                      "256, 384 or 521 bits");
Line 795 
Line 795 
 #endif /* ENABLE_PKCS11 */  #endif /* ENABLE_PKCS11 */
 }  }
   
   static struct sshkey *
   try_read_key(char **cpp)
   {
           struct sshkey *ret;
           int r;
   
           if ((ret = sshkey_new(KEY_RSA1)) == NULL)
                   fatal("sshkey_new failed");
           /* Try RSA1 */
           if ((r = sshkey_read(ret, cpp)) == 0)
                   return ret;
           /* Try modern */
           sshkey_free(ret);
           if ((ret = sshkey_new(KEY_UNSPEC)) == NULL)
                   fatal("sshkey_new failed");
           if ((r = sshkey_read(ret, cpp)) == 0)
                   return ret;
           /* Not a key */
           sshkey_free(ret);
           return NULL;
   }
   
 static void  static void
 do_fingerprint(struct passwd *pw)  fingerprint_one_key(const struct sshkey *public, const char *comment)
 {  {
         FILE *f;          char *fp = NULL, *ra = NULL;
         struct sshkey *public;  
         char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;  
         int r, i, skip = 0, num = 0, invalid = 1;  
         enum sshkey_fp_rep rep;          enum sshkey_fp_rep rep;
         int fptype;          int fptype;
         struct stat st;  
   
         fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;          fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
         rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;          rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
         if (!have_identity)          fp = sshkey_fingerprint(public, fptype, rep);
                 ask_filename(pw, "Enter file in which the key is");          ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART);
           if (fp == NULL || ra == NULL)
                   fatal("%s: sshkey_fingerprint failed", __func__);
           printf("%u %s %s (%s)\n", sshkey_size(public), fp,
               comment ? comment : "no comment", sshkey_type(public));
           if (log_level >= SYSLOG_LEVEL_VERBOSE)
                   printf("%s\n", ra);
           free(ra);
           free(fp);
   }
   
   static void
   fingerprint_private(const char *path)
   {
           struct stat st;
           char *comment = NULL;
           struct sshkey *public = NULL;
           int r;
   
         if (stat(identity_file, &st) < 0)          if (stat(identity_file, &st) < 0)
                 fatal("%s: %s", identity_file, strerror(errno));                  fatal("%s: %s", path, strerror(errno));
         if ((r = sshkey_load_public(identity_file, &public, &comment)) != 0)          if ((r = sshkey_load_public(path, &public, &comment)) != 0) {
                 debug2("Error loading public key \"%s\": %s",                  debug("load public \"%s\": %s", path, ssh_err(r));
                     identity_file, ssh_err(r));                  if ((r = sshkey_load_private(path, NULL,
         else {                      &public, &comment)) != 0) {
                 fp = sshkey_fingerprint(public, fptype, rep);                          debug("load private \"%s\": %s", path, ssh_err(r));
                 ra = sshkey_fingerprint(public, fingerprint_hash,                          fatal("%s is not a key file.", path);
                     SSH_FP_RANDOMART);                  }
                 if (fp == NULL || ra == NULL)  
                         fatal("%s: sshkey_fingerprint fail", __func__);  
                 printf("%u %s %s (%s)\n", sshkey_size(public), fp, comment,  
                     sshkey_type(public));  
                 if (log_level >= SYSLOG_LEVEL_VERBOSE)  
                         printf("%s\n", ra);  
                 sshkey_free(public);  
                 free(comment);  
                 free(ra);  
                 free(fp);  
                 exit(0);  
         }          }
         if (comment) {  
                 free(comment);  
                 comment = NULL;  
         }  
   
         if ((f = fopen(identity_file, "r")) == NULL)          fingerprint_one_key(public, comment);
                 fatal("%s: %s: %s", __progname, identity_file, strerror(errno));          sshkey_free(public);
           free(comment);
   }
   
         while (fgets(line, sizeof(line), f)) {  static void
                 if ((cp = strchr(line, '\n')) == NULL) {  do_fingerprint(struct passwd *pw)
                         error("line %d too long: %.40s...",  {
                             num + 1, line);          FILE *f;
                         skip = 1;          struct sshkey *public = NULL;
           char *comment = NULL, *cp, *ep, line[16*1024];
           int i, invalid = 1;
           const char *path;
           long int lnum = 0;
   
           if (!have_identity)
                   ask_filename(pw, "Enter file in which the key is");
           path = identity_file;
   
           if (strcmp(identity_file, "-") == 0) {
                   f = stdin;
                   path = "(stdin)";
           } else if ((f = fopen(path, "r")) == NULL)
                   fatal("%s: %s: %s", __progname, path, strerror(errno));
   
           while (read_keyfile_line(f, path, line, sizeof(line), &lnum) == 0) {
                   cp = line;
                   cp[strcspn(cp, "\n")] = '\0';
                   /* Trim leading space and comments */
                   cp = line + strspn(line, " \t");
                   if (*cp == '#' || *cp == '\0')
                         continue;                          continue;
   
                   /*
                    * Input may be plain keys, private keys, authorized_keys
                    * or known_hosts.
                    */
   
                   /*
                    * Try private keys first. Assume a key is private if
                    * "SSH PRIVATE KEY" appears on the first line and we're
                    * not reading from stdin (XXX support private keys on stdin).
                    */
                   if (lnum == 1 && strcmp(identity_file, "-") != 0 &&
                       strstr(cp, "PRIVATE KEY") != NULL) {
                           fclose(f);
                           fingerprint_private(path);
                           exit(0);
                 }                  }
                 num++;  
                 if (skip) {                  /*
                         skip = 0;                   * If it's not a private key, then this must be prepared to
                    * accept a public key prefixed with a hostname or options.
                    * Try a bare key first, otherwise skip the leading stuff.
                    */
                   if ((public = try_read_key(&cp)) == NULL) {
                           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';
                           }
                   }
                   /* Retry after parsing leading hostname/key options */
                   if (public == NULL && (public = try_read_key(&cp)) == NULL) {
                           debug("%s:%ld: not a public key", path, lnum);
                         continue;                          continue;
                 }                  }
                 *cp = '\0';  
   
                 /* Skip leading whitespace, empty and comment lines. */                  /* Find trailing comment, if any */
                 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)                  for (; *cp == ' ' || *cp == '\t'; cp++)
                         ;                          ;
                 if (!*cp || *cp == '\n' || *cp == '#')                  if (*cp != '\0' && *cp != '#')
                         continue;  
                 i = strtol(cp, &ep, 10);  
                 if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {  
                         int quoted = 0;  
                         comment = cp;                          comment = cp;
                         for (; *cp && (quoted || (*cp != ' ' &&  
                             *cp != '\t')); cp++) {                  fingerprint_one_key(public, comment);
                                 if (*cp == '\\' && cp[1] == '"')  
                                         cp++;   /* Skip both */  
                                 else if (*cp == '"')  
                                         quoted = !quoted;  
                         }  
                         if (!*cp)  
                                 continue;  
                         *cp++ = '\0';  
                 }  
                 ep = cp;  
                 if ((public = sshkey_new(KEY_RSA1)) == NULL)  
                         fatal("sshkey_new failed");  
                 if ((r = sshkey_read(public, &cp)) != 0) {  
                         cp = ep;  
                         sshkey_free(public);  
                         if ((public = sshkey_new(KEY_UNSPEC)) == NULL)  
                                 fatal("sshkey_new failed");  
                         if ((r = sshkey_read(public, &cp)) != 0) {  
                                 sshkey_free(public);  
                                 continue;  
                         }  
                 }  
                 comment = *cp ? cp : comment;  
                 fp = sshkey_fingerprint(public, fptype, rep);  
                 ra = sshkey_fingerprint(public, fingerprint_hash,  
                     SSH_FP_RANDOMART);  
                 if (fp == NULL || ra == NULL)  
                         fatal("%s: sshkey_fingerprint fail", __func__);  
                 printf("%u %s %s (%s)\n", sshkey_size(public), fp,  
                     comment ? comment : "no comment", sshkey_type(public));  
                 if (log_level >= SYSLOG_LEVEL_VERBOSE)  
                         printf("%s\n", ra);  
                 free(ra);  
                 free(fp);  
                 sshkey_free(public);                  sshkey_free(public);
                 invalid = 0;                  invalid = 0; /* One good key in the file is sufficient */
         }          }
         fclose(f);          fclose(f);
   
         if (invalid)          if (invalid)
                 fatal("%s is not a public key file.", identity_file);                  fatal("%s is not a public key file.", path);
         exit(0);          exit(0);
 }  }
   
Line 1186 
Line 1232 
                 exit(1);                  exit(1);
         } else if (delete_host && !ctx.found_key) {          } else if (delete_host && !ctx.found_key) {
                 logit("Host %s not found in %s", name, identity_file);                  logit("Host %s not found in %s", name, identity_file);
                 unlink(tmp);                  if (inplace)
                           unlink(tmp);
         } else if (inplace) {          } else if (inplace) {
                 /* Backup existing file */                  /* Backup existing file */
                 if (unlink(old) == -1 && errno != ENOENT)                  if (unlink(old) == -1 && errno != ENOENT)
Line 1835 
Line 1882 
 }  }
   
 static void  static void
 do_show_cert(struct passwd *pw)  print_cert(struct sshkey *key)
 {  {
         struct sshkey *key;  
         struct stat st;  
         char *key_fp, *ca_fp;          char *key_fp, *ca_fp;
         u_int i;          u_int i;
         int r;  
   
         if (!have_identity)  
                 ask_filename(pw, "Enter file in which the key is");  
         if (stat(identity_file, &st) < 0)  
                 fatal("%s: %s: %s", __progname, identity_file, strerror(errno));  
         if ((r = sshkey_load_public(identity_file, &key, NULL)) != 0)  
                 fatal("Cannot load public key \"%s\": %s",  
                     identity_file, ssh_err(r));  
         if (!sshkey_is_cert(key))  
                 fatal("%s is not a certificate", identity_file);  
   
         key_fp = sshkey_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT);          key_fp = sshkey_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT);
         ca_fp = sshkey_fingerprint(key->cert->signature_key,          ca_fp = sshkey_fingerprint(key->cert->signature_key,
             fingerprint_hash, SSH_FP_DEFAULT);              fingerprint_hash, SSH_FP_DEFAULT);
         if (key_fp == NULL || ca_fp == NULL)          if (key_fp == NULL || ca_fp == NULL)
                 fatal("%s: sshkey_fingerprint fail", __func__);                  fatal("%s: sshkey_fingerprint fail", __func__);
   
         printf("%s:\n", identity_file);  
         printf("        Type: %s %s certificate\n", sshkey_ssh_name(key),          printf("        Type: %s %s certificate\n", sshkey_ssh_name(key),
             sshkey_cert_type(key));              sshkey_cert_type(key));
         printf("        Public key: %s %s\n", sshkey_type(key), key_fp);          printf("        Public key: %s %s\n", sshkey_type(key), key_fp);
Line 1892 
Line 1925 
                 printf("\n");                  printf("\n");
                 show_options(key->cert->extensions, 0);                  show_options(key->cert->extensions, 0);
         }          }
         exit(0);  }
   
   static void
   do_show_cert(struct passwd *pw)
   {
           struct sshkey *key = NULL;
           struct stat st;
           int r, is_stdin = 0, ok = 0;
           FILE *f;
           char *cp, line[2048];
           const char *path;
           long int lnum = 0;
   
           if (!have_identity)
                   ask_filename(pw, "Enter file in which the key is");
           if (strcmp(identity_file, "-") != 0 && stat(identity_file, &st) < 0)
                   fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
   
           path = identity_file;
           if (strcmp(path, "-") == 0) {
                   f = stdin;
                   path = "(stdin)";
                   is_stdin = 1;
           } else if ((f = fopen(identity_file, "r")) == NULL)
                   fatal("fopen %s: %s", identity_file, strerror(errno));
   
           while (read_keyfile_line(f, path, line, sizeof(line), &lnum) == 0) {
                   sshkey_free(key);
                   key = NULL;
                   /* Trim leading space and comments */
                   cp = line + strspn(line, " \t");
                   if (*cp == '#' || *cp == '\0')
                           continue;
                   if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
                           fatal("key_new");
                   if ((r = sshkey_read(key, &cp)) != 0) {
                           error("%s:%lu: invalid key: %s", path,
                               lnum, ssh_err(r));
                           continue;
                   }
                   if (!sshkey_is_cert(key)) {
                           error("%s:%lu is not a certificate", path, lnum);
                           continue;
                   }
                   ok = 1;
                   if (!is_stdin && lnum == 1)
                           printf("%s:\n", path);
                   else
                           printf("%s:%lu:\n", path, lnum);
                   print_cert(key);
           }
           sshkey_free(key);
           fclose(f);
           exit(ok ? 0 : 1);
 }  }
   
 #ifdef WITH_OPENSSL  #ifdef WITH_OPENSSL

Legend:
Removed from v.1.275  
changed lines
  Added in v.1.280