[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.5 and 1.10

version 1.5, 1999/09/29 21:14:16 version 1.10, 1999/11/20 19:53:40
Line 19 
Line 19 
 #include "rsa.h"  #include "rsa.h"
 #include "ssh.h"  #include "ssh.h"
 #include "xmalloc.h"  #include "xmalloc.h"
   #include "fingerprint.h"
   
 /* Generated private key. */  /* Generated private key. */
 RSA *private_key;  RSA *private_key;
Line 40 
Line 41 
   
 int quiet = 0;  int quiet = 0;
   
 /* This is set to the identity file name if given on the command line. */  /* Flag indicating that we just want to see the key fingerprint */
 char *identity_file = NULL;  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. */  /* This is set to the passphrase if given on the command line. */
 char *identity_passphrase = NULL;  char *identity_passphrase = NULL;
   
Line 52 
Line 57 
 /* This is set to the new comment if given on the command line. */  /* This is set to the new comment if given on the command line. */
 char *identity_comment = NULL;  char *identity_comment = NULL;
   
   /* argv0 */
   extern char *__progname;
   
   void
   ask_filename(struct passwd *pw, const char *prompt)
   {
     char buf[1024];
     snprintf(identity_file, sizeof(identity_file), "%s/%s",
              pw->pw_dir, 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;
   }
   
   void
   do_fingerprint(struct passwd *pw)
   {
     char *comment;
     RSA *public_key;
     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 = RSA_new();
     if (!load_public_key(identity_file, public_key, &comment)) {
       char *cp, line[1024];
       BIGNUM *e, *n;
       int dummy, invalid = 0;
       FILE *f = fopen(identity_file, "r");
       n = BN_new();
       e = BN_new();
       if (f && fgets(line, sizeof(line), f)) {
         cp = line;
         line[strlen(line)-1] = '\0';
         if (auth_rsa_read_key(&cp, &dummy, e, n)) {
           public_key->e = e;
           public_key->n = n;
           comment = xstrdup(cp ? cp : "no comment");
         } else {
           invalid = 1;
         }
       } else {
         invalid = 1;
       }
       if (invalid) {
         printf("%s is not a valid key file.\n", identity_file);
         BN_free(e);
         BN_free(n);
         exit(1);
       }
     }
   
     printf("%d %s %s\n", BN_num_bits(public_key->n),
            fingerprint(public_key->e, public_key->n),
            comment);
     RSA_free(public_key);
     exit(0);
   }
   
 /* Perform changing a passphrase.  The argument is the passwd structure  /* Perform changing a passphrase.  The argument is the passwd structure
    for the current user. */     for the current user. */
   
 void  void
 do_change_passphrase(struct passwd *pw)  do_change_passphrase(struct passwd *pw)
 {  {
   char buf[1024], *comment;    char *comment;
   char *old_passphrase, *passphrase1, *passphrase2;    char *old_passphrase, *passphrase1, *passphrase2;
   struct stat st;    struct stat st;
   RSA *private_key;    RSA *private_key;
   
   /* Read key file name. */    if (!have_identity)
   if (identity_file != NULL) {      ask_filename(pw, "Enter file in which the key is");
       strncpy(buf, identity_file, sizeof(buf));  
       buf[sizeof(buf) - 1] = '\0';  
   } else {  
     printf("Enter file in which the key is ($HOME/%s): ", SSH_CLIENT_IDENTITY);  
     fflush(stdout);  
     if (fgets(buf, sizeof(buf), stdin) == NULL)  
       exit(1);  
     if (strchr(buf, '\n'))  
       *strchr(buf, '\n') = 0;  
     if (strcmp(buf, "") == 0)  
       snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY);  
   }  
   
   /* Check if the file exists. */    /* Check if the file exists. */
   if (stat(buf, &st) < 0)    if (stat(identity_file, &st) < 0)
     {      {
       perror(buf);        perror(identity_file);
       exit(1);        exit(1);
     }      }
   
   /* Try to load the public key from the file the verify that it is    /* Try to load the public key from the file the verify that it is
      readable and of the proper format. */       readable and of the proper format. */
   public_key = RSA_new();    public_key = RSA_new();
   if (!load_public_key(buf, public_key, NULL))    if (!load_public_key(identity_file, public_key, NULL))
     {      {
       printf("%s is not a valid key file.\n", buf);        printf("%s is not a valid key file.\n", identity_file);
       exit(1);        exit(1);
     }      }
   /* Clear the public key since we are just about to load the whole file. */    /* Clear the public key since we are just about to load the whole file. */
Line 98 
Line 160 
   
   /* Try to load the file with empty passphrase. */    /* Try to load the file with empty passphrase. */
   private_key = RSA_new();    private_key = RSA_new();
   if (!load_private_key(buf, "", private_key, &comment)) {    if (!load_private_key(identity_file, "", private_key, &comment)) {
     /* Read passphrase from the user. */      /* Read passphrase from the user. */
     if (identity_passphrase)      if (identity_passphrase)
       old_passphrase = xstrdup(identity_passphrase);        old_passphrase = xstrdup(identity_passphrase);
     else      else
       old_passphrase = read_passphrase("Enter old passphrase: ", 1);        old_passphrase = read_passphrase("Enter old passphrase: ", 1);
     /* Try to load using the passphrase. */      /* Try to load using the passphrase. */
     if (!load_private_key(buf, old_passphrase, private_key, &comment))      if (!load_private_key(identity_file, old_passphrase, private_key, &comment))
       {        {
         memset(old_passphrase, 0, strlen(old_passphrase));          memset(old_passphrase, 0, strlen(old_passphrase));
         xfree(old_passphrase);          xfree(old_passphrase);
Line 146 
Line 208 
     }      }
   
   /* Save the file using the new passphrase. */    /* Save the file using the new passphrase. */
   if (!save_private_key(buf, passphrase1, private_key, comment))    if (!save_private_key(identity_file, passphrase1, private_key, comment))
     {      {
       printf("Saving the key failed: %s: %s.\n",        printf("Saving the key failed: %s: %s.\n",
              buf, strerror(errno));               identity_file, strerror(errno));
       memset(passphrase1, 0, strlen(passphrase1));        memset(passphrase1, 0, strlen(passphrase1));
       xfree(passphrase1);        xfree(passphrase1);
       RSA_free(private_key);        RSA_free(private_key);
Line 171 
Line 233 
 void  void
 do_change_comment(struct passwd *pw)  do_change_comment(struct passwd *pw)
 {  {
   char buf[1024], new_comment[1024], *comment;    char new_comment[1024], *comment;
   RSA *private_key;    RSA *private_key;
   char *passphrase;    char *passphrase;
   struct stat st;    struct stat st;
   FILE *f;    FILE *f;
   char *tmpbuf;    char *tmpbuf;
   
   /* Read key file name. */    if (!have_identity)
   if (identity_file)      ask_filename(pw, "Enter file in which the key is");
     {  
       strncpy(buf, identity_file, sizeof(buf));  
       buf[sizeof(buf) - 1] = '\0';  
     }  
   else  
     {  
       printf("Enter file in which the key is ($HOME/%s): ",  
              SSH_CLIENT_IDENTITY);  
       fflush(stdout);  
       if (fgets(buf, sizeof(buf), stdin) == NULL)  
         exit(1);  
       if (strchr(buf, '\n'))  
         *strchr(buf, '\n') = 0;  
       if (strcmp(buf, "") == 0)  
         snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY);  
     }  
   
   /* Check if the file exists. */    /* Check if the file exists. */
   if (stat(buf, &st) < 0)    if (stat(identity_file, &st) < 0)
     {      {
       perror(buf);        perror(identity_file);
       exit(1);        exit(1);
     }      }
   
   /* Try to load the public key from the file the verify that it is    /* Try to load the public key from the file the verify that it is
      readable and of the proper format. */       readable and of the proper format. */
   public_key = RSA_new();    public_key = RSA_new();
   if (!load_public_key(buf, public_key, NULL))    if (!load_public_key(identity_file, public_key, NULL))
     {      {
       printf("%s is not a valid key file.\n", buf);        printf("%s is not a valid key file.\n", identity_file);
       exit(1);        exit(1);
     }      }
   
   private_key = RSA_new();    private_key = RSA_new();
   /* Try to load the file with empty passphrase. */    /* Try to load the file with empty passphrase. */
   if (load_private_key(buf, "", private_key, &comment))    if (load_private_key(identity_file, "", private_key, &comment))
     passphrase = xstrdup("");      passphrase = xstrdup("");
   else    else
     {      {
Line 228 
Line 273 
         else          else
           passphrase = read_passphrase("Enter passphrase: ", 1);            passphrase = read_passphrase("Enter passphrase: ", 1);
       /* Try to load using the passphrase. */        /* Try to load using the passphrase. */
       if (!load_private_key(buf, passphrase, private_key, &comment))        if (!load_private_key(identity_file, passphrase, private_key, &comment))
         {          {
           memset(passphrase, 0, strlen(passphrase));            memset(passphrase, 0, strlen(passphrase));
           xfree(passphrase);            xfree(passphrase);
Line 240 
Line 285 
   
   if (identity_comment)    if (identity_comment)
     {      {
       strncpy(new_comment, identity_comment, sizeof(new_comment));        strlcpy(new_comment, identity_comment, sizeof(new_comment));
       new_comment[sizeof(new_comment) - 1] = '\0';  
     }      }
   else    else
     {      {
Line 260 
Line 304 
     }      }
   
   /* Save the file using the new passphrase. */    /* Save the file using the new passphrase. */
   if (!save_private_key(buf, passphrase, private_key, new_comment))    if (!save_private_key(identity_file, passphrase, private_key, new_comment))
     {      {
       printf("Saving the key failed: %s: %s.\n",        printf("Saving the key failed: %s: %s.\n",
              buf, strerror(errno));               identity_file, strerror(errno));
       memset(passphrase, 0, strlen(passphrase));        memset(passphrase, 0, strlen(passphrase));
       xfree(passphrase);        xfree(passphrase);
       RSA_free(private_key);        RSA_free(private_key);
Line 278 
Line 322 
   
   /* Save the public key in text format in a file with the same name but    /* Save the public key in text format in a file with the same name but
      .pub appended. */       .pub appended. */
   strcat(buf, ".pub");    strlcat(identity_file, ".pub", sizeof(identity_file));
   f = fopen(buf, "w");    f = fopen(identity_file, "w");
   if (!f)    if (!f)
     {      {
       printf("Could not save your public key in %s\n", buf);        printf("Could not save your public key in %s\n", identity_file);
       exit(1);        exit(1);
     }      }
   fprintf(f, "%d ", BN_num_bits(public_key->n));    fprintf(f, "%d ", BN_num_bits(public_key->n));
Line 300 
Line 344 
   exit(0);    exit(0);
 }  }
   
   void
   usage(void)
   {
     printf("ssh-keygen version %s\n", SSH_VERSION);
     printf("Usage: %s [-b bits] [-p] [-c] [-f file] [-P pass] [-N new-pass] [-C comment]\n", __progname);
     exit(1);
   }
   
 /* Main program for key management. */  /* Main program for key management. */
   
 int  int
Line 340 
Line 392 
       error("Could not create directory '%s'.", buf);        error("Could not create directory '%s'.", buf);
   
   /* Parse command line arguments. */    /* Parse command line arguments. */
   while ((opt = getopt(ac, av, "qpcb:f:P:N:C:")) != EOF)    while ((opt = getopt(ac, av, "qpclb:f:P:N:C:")) != EOF)
     {      {
       switch (opt)        switch (opt)
         {          {
Line 353 
Line 405 
             }              }
           break;            break;
   
           case 'l':
             print_fingerprint = 1;
             break;
   
         case 'p':          case 'p':
           change_passphrase = 1;            change_passphrase = 1;
           break;            break;
Line 362 
Line 418 
           break;            break;
   
         case 'f':          case 'f':
           identity_file = optarg;            strlcpy(identity_file, optarg, sizeof(identity_file));
             have_identity = 1;
           break;            break;
   
         case 'P':          case 'P':
Line 383 
Line 440 
   
         case '?':          case '?':
         default:          default:
           printf("ssh-keygen version %s\n", SSH_VERSION);            usage();
           printf("Usage: %s [-b bits] [-p] [-c] [-f file] [-P pass] [-N new-pass] [-C comment]\n", av[0]);  
           exit(1);  
         }          }
     }      }
   if (optind < ac)    if (optind < ac)
     {      {
       printf("Too many arguments.\n");        printf("Too many arguments.\n");
       exit(1);        usage();
     }      }
   if (change_passphrase && change_comment)    if (change_passphrase && change_comment)
     {      {
       printf("Can only have one of -p and -c.\n");        printf("Can only have one of -p and -c.\n");
       exit(1);        usage();
     }      }
   
     if (print_fingerprint)
       do_fingerprint(pw);
   
   /* If the user requested to change the passphrase, do it now.  This    /* If the user requested to change the passphrase, do it now.  This
      function never returns. */       function never returns. */
   if (change_passphrase)    if (change_passphrase)
Line 409 
Line 467 
   if (change_comment)    if (change_comment)
     do_change_comment(pw);      do_change_comment(pw);
   
   /* Initialize random number generator.  This may take a while if the  
      user has no seed file, so display a message to the user. */  
   if (!quiet)  
     printf("Initializing random number generator...\n");  
   arc4random_stir();    arc4random_stir();
   
   if (quiet)    if (quiet)
Line 423 
Line 477 
   public_key = RSA_new();    public_key = RSA_new();
   rsa_generate_key(private_key, public_key, bits);    rsa_generate_key(private_key, public_key, bits);
   
  ask_file_again:    if (!have_identity)
       ask_filename(pw, "Enter file in which to save the key");
   
   /* Ask for a file to save the key in. */  
   if (identity_file)  
     {  
       strncpy(buf, identity_file, sizeof(buf));  
       buf[sizeof(buf) - 1] = '\0';  
     }  
   else  
     {  
       printf("Enter file in which to save the key ($HOME/%s): ",  
              SSH_CLIENT_IDENTITY);  
       fflush(stdout);  
       if (fgets(buf, sizeof(buf), stdin) == NULL)  
         exit(1);  
       if (strchr(buf, '\n'))  
         *strchr(buf, '\n') = 0;  
       if (strcmp(buf, "") == 0)  
         snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY);  
     }  
   
   /* If the file aready exists, ask the user to confirm. */    /* If the file aready exists, ask the user to confirm. */
   if (stat(buf, &st) >= 0)    if (stat(identity_file, &st) >= 0)
     {      {
       printf("%s already exists.\n", buf);        printf("%s already exists.\n", identity_file);
       printf("Overwrite (y/n)? ");        printf("Overwrite (y/n)? ");
       fflush(stdout);        fflush(stdout);
       if (fgets(buf2, sizeof(buf2), stdin) == NULL)        if (fgets(buf2, sizeof(buf2), stdin) == NULL)
Line 500 
Line 536 
     }      }
   
   /* Save the key with the given passphrase and comment. */    /* Save the key with the given passphrase and comment. */
   if (!save_private_key(buf, passphrase1, private_key, buf2))    if (!save_private_key(identity_file, passphrase1, private_key, buf2))
     {      {
       printf("Saving the key failed: %s: %s.\n",        printf("Saving the key failed: %s: %s.\n",
              buf, strerror(errno));               identity_file, strerror(errno));
       memset(passphrase1, 0, strlen(passphrase1));        memset(passphrase1, 0, strlen(passphrase1));
       xfree(passphrase1);        xfree(passphrase1);
       goto ask_file_again;        exit(1);
     }      }
   /* Clear the passphrase. */    /* Clear the passphrase. */
   memset(passphrase1, 0, strlen(passphrase1));    memset(passphrase1, 0, strlen(passphrase1));
Line 517 
Line 553 
   arc4random_stir();    arc4random_stir();
   
   if (!quiet)    if (!quiet)
     printf("Your identification has been saved in %s.\n", buf);      printf("Your identification has been saved in %s.\n", identity_file);
   
   /* Display the public key on the screen. */    /* Display the public key on the screen. */
   if (!quiet) {    if (!quiet) {
Line 533 
Line 569 
   
   /* Save the public key in text format in a file with the same name but    /* Save the public key in text format in a file with the same name but
      .pub appended. */       .pub appended. */
   strcat(buf, ".pub");    strlcat(identity_file, ".pub", sizeof(identity_file));
   f = fopen(buf, "w");    f = fopen(identity_file, "w");
   if (!f)    if (!f)
     {      {
       printf("Could not save your public key in %s\n", buf);        printf("Could not save your public key in %s\n", identity_file);
       exit(1);        exit(1);
     }      }
   fprintf(f, "%d ", BN_num_bits(public_key->n));    fprintf(f, "%d ", BN_num_bits(public_key->n));
Line 550 
Line 586 
   fclose(f);    fclose(f);
   
   if (!quiet)    if (!quiet)
     printf("Your public key has been saved in %s\n", buf);      printf("Your public key has been saved in %s\n", identity_file);
   
   exit(0);    exit(0);
 }  }

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.10