]> andersk Git - openssh.git/blobdiff - ssh-keygen.c
- Merged OpenBSD CVS changes
[openssh.git] / ssh-keygen.c
index e4e1ee53e508ae511978651b53f99393be01ea49..b1baeced11b598a3b6d29ba4f487377de36f6f1c 100644 (file)
@@ -19,6 +19,7 @@ RCSID("$Id$");
 #include "rsa.h"
 #include "ssh.h"
 #include "xmalloc.h"
+#include "fingerprint.h"
 
 #ifdef HAVE___PROGNAME
 extern char *__progname;
@@ -46,6 +47,9 @@ int change_comment = 0;
 
 int quiet = 0;
 
+/* Flag indicating that we just want to see the key fingerprint */
+int print_fingerprint = 0;
+
 /* This is set to the identity file name if given on the command line. */
 char *identity_file = NULL;
 
@@ -61,42 +65,101 @@ char *identity_comment = NULL;
 /* Perform changing a passphrase.  The argument is the passwd structure
    for the current user. */
 
-void
-do_change_passphrase(struct passwd *pw)
+char *
+get_filename(struct passwd *pw, const char *prompt)
 {
-  char buf[1024], *comment;
-  char *old_passphrase, *passphrase1, *passphrase2;
-  struct stat st;
-  RSA *private_key;
+  char buf[1024], default_file[1024];
 
   /* Read key file name. */
   if (identity_file != NULL) {
-      strncpy(buf, identity_file, sizeof(buf));
-      buf[sizeof(buf) - 1] = '\0';
+    return xstrdup(identity_file);
   } else {
-    printf("Enter file in which the key is ($HOME/%s): ", SSH_CLIENT_IDENTITY);
+    snprintf(default_file, sizeof default_file, "%s/%s",
+             pw->pw_dir, SSH_CLIENT_IDENTITY);
+    printf("%s (%s): ", prompt, default_file);
     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);
+      return xstrdup(default_file);
   }
+  return xstrdup(buf);
+}
 
+void
+do_fingerprint(struct passwd *pw)
+{
+  char *file, *comment;
+  RSA *public_key;
+  struct stat st;
+
+  file = get_filename(pw, "Enter file in which the key is");
+  if (stat(file, &st) < 0)
+    {
+      perror(file);
+      exit(1);
+    }
+  public_key = RSA_new();
+  if (!load_public_key(file, public_key, &comment)) {
+    char *cp, line[1024];
+    BIGNUM *e, *n;
+    int dummy, invalid = 0;
+    FILE *f = fopen(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", 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);
+}
+
+
+void
+do_change_passphrase(struct passwd *pw)
+{
+  char *file, *comment;
+  char *old_passphrase, *passphrase1, *passphrase2;
+  struct stat st;
+  RSA *private_key;
+
+  file = get_filename(pw, "Enter file in which the key is");
   /* Check if the file exists. */
-  if (stat(buf, &st) < 0)
+  if (stat(file, &st) < 0)
     {
-      perror(buf);
+      perror(file);
       exit(1);
     }
   
   /* Try to load the public key from the file the verify that it is
      readable and of the proper format. */
   public_key = RSA_new();
-  if (!load_public_key(buf, public_key, NULL))
+  if (!load_public_key(file, public_key, NULL))
     {
-      printf("%s is not a valid key file.\n", buf);
+      printf("%s is not a valid key file.\n", file);
       exit(1);
     }
   /* Clear the public key since we are just about to load the whole file. */
@@ -104,14 +167,14 @@ do_change_passphrase(struct passwd *pw)
 
   /* Try to load the file with empty passphrase. */
   private_key = RSA_new();
-  if (!load_private_key(buf, "", private_key, &comment)) {
+  if (!load_private_key(file, "", private_key, &comment)) {
     /* Read passphrase from the user. */
     if (identity_passphrase)
       old_passphrase = xstrdup(identity_passphrase);
     else
       old_passphrase = read_passphrase("Enter old passphrase: ", 1);
     /* Try to load using the passphrase. */
-    if (!load_private_key(buf, old_passphrase, private_key, &comment))
+    if (!load_private_key(file, old_passphrase, private_key, &comment))
       {
        memset(old_passphrase, 0, strlen(old_passphrase));
        xfree(old_passphrase);
@@ -152,10 +215,10 @@ do_change_passphrase(struct passwd *pw)
     }
 
   /* Save the file using the new passphrase. */
-  if (!save_private_key(buf, passphrase1, private_key, comment))
+  if (!save_private_key(file, passphrase1, private_key, comment))
     {
       printf("Saving the key failed: %s: %s.\n",
-            buf, strerror(errno));
+            file, strerror(errno));
       memset(passphrase1, 0, strlen(passphrase1));
       xfree(passphrase1);
       RSA_free(private_key);
@@ -177,51 +240,33 @@ do_change_passphrase(struct passwd *pw)
 void
 do_change_comment(struct passwd *pw)
 {
-  char buf[1024], new_comment[1024], *comment;
+  char new_comment[1024], *file, *comment;
   RSA *private_key;
   char *passphrase;
   struct stat st;
   FILE *f;
   char *tmpbuf;
 
-  /* Read key file name. */
-  if (identity_file)
-    {
-      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);
-    }
-
+  file = get_filename(pw, "Enter file in which the key is");
   /* Check if the file exists. */
-  if (stat(buf, &st) < 0)
+  if (stat(file, &st) < 0)
     {
-      perror(buf);
+      perror(file);
       exit(1);
     }
   
   /* Try to load the public key from the file the verify that it is
      readable and of the proper format. */
   public_key = RSA_new();
-  if (!load_public_key(buf, public_key, NULL))
+  if (!load_public_key(file, public_key, NULL))
     {
-      printf("%s is not a valid key file.\n", buf);
+      printf("%s is not a valid key file.\n", file);
       exit(1);
     }
 
   private_key = RSA_new();
   /* Try to load the file with empty passphrase. */
-  if (load_private_key(buf, "", private_key, &comment))
+  if (load_private_key(file, "", private_key, &comment))
     passphrase = xstrdup("");
   else
     {
@@ -234,7 +279,7 @@ do_change_comment(struct passwd *pw)
        else
          passphrase = read_passphrase("Enter passphrase: ", 1);
       /* Try to load using the passphrase. */
-      if (!load_private_key(buf, passphrase, private_key, &comment))
+      if (!load_private_key(file, passphrase, private_key, &comment))
        {
          memset(passphrase, 0, strlen(passphrase));
          xfree(passphrase);
@@ -246,8 +291,7 @@ do_change_comment(struct passwd *pw)
 
   if (identity_comment)
     {
-      strncpy(new_comment, identity_comment, sizeof(new_comment));
-      new_comment[sizeof(new_comment) - 1] = '\0';
+      strlcpy(new_comment, identity_comment, sizeof(new_comment));
     }
   else
     {
@@ -266,10 +310,10 @@ do_change_comment(struct passwd *pw)
     }
       
   /* Save the file using the new passphrase. */
-  if (!save_private_key(buf, passphrase, private_key, new_comment))
+  if (!save_private_key(file, passphrase, private_key, new_comment))
     {
       printf("Saving the key failed: %s: %s.\n",
-            buf, strerror(errno));
+            file, strerror(errno));
       memset(passphrase, 0, strlen(passphrase));
       xfree(passphrase);
       RSA_free(private_key);
@@ -284,11 +328,11 @@ do_change_comment(struct passwd *pw)
 
   /* Save the public key in text format in a file with the same name but
      .pub appended. */
-  strcat(buf, ".pub");
-  f = fopen(buf, "w");
+  strcat(file, ".pub");
+  f = fopen(file, "w");
   if (!f)
     {
-      printf("Could not save your public key in %s\n", buf);
+      printf("Could not save your public key in %s\n", file);
       exit(1);
     }
   fprintf(f, "%d ", BN_num_bits(public_key->n));
@@ -313,7 +357,7 @@ main(int ac, char **av)
 {
   char buf[16384], buf2[1024], *passphrase1, *passphrase2;
   struct passwd *pw;
-  char *tmpbuf;
+  char *file, *tmpbuf;
   int opt;
   struct stat st;
   FILE *f;
@@ -323,6 +367,7 @@ main(int ac, char **av)
 
   /* check if RSA support exists */
   if (rsa_alive() == 0) {
+    extern char *__progname;
 
     fprintf(stderr,
       "%s: no RSA support in libssl and libcrypto.  See ssl(8).\n",
@@ -345,7 +390,7 @@ main(int ac, char **av)
       error("Could not create directory '%s'.", buf);
 
   /* 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)
        {
@@ -358,6 +403,10 @@ main(int ac, char **av)
            }
          break;
 
+       case 'l':
+         print_fingerprint = 1;
+         break;
+
        case 'p':
          change_passphrase = 1;
          break;
@@ -404,6 +453,9 @@ main(int ac, char **av)
       exit(1);
     }
 
+  if (print_fingerprint)
+    do_fingerprint(pw);
+
   /* If the user requested to change the passphrase, do it now.  This
      function never returns. */
   if (change_passphrase)
@@ -426,29 +478,12 @@ main(int ac, char **av)
 
  ask_file_again:
 
-  /* 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);
-    }
+  file = get_filename(pw, "Enter file in which to save the key");
 
   /* If the file aready exists, ask the user to confirm. */
-  if (stat(buf, &st) >= 0)
+  if (stat(file, &st) >= 0)
     {
-      printf("%s already exists.\n", buf);
+      printf("%s already exists.\n", file);
       printf("Overwrite (y/n)? ");
       fflush(stdout);
       if (fgets(buf2, sizeof(buf2), stdin) == NULL)
@@ -501,12 +536,13 @@ main(int ac, char **av)
     }
 
   /* Save the key with the given passphrase and comment. */
-  if (!save_private_key(buf, passphrase1, private_key, buf2))
+  if (!save_private_key(file, passphrase1, private_key, buf2))
     {
       printf("Saving the key failed: %s: %s.\n",
-            buf, strerror(errno));
+            file, strerror(errno));
       memset(passphrase1, 0, strlen(passphrase1));
       xfree(passphrase1);
+      xfree(file);
       goto ask_file_again;
     }
   /* Clear the passphrase. */
@@ -518,7 +554,7 @@ main(int ac, char **av)
   arc4random_stir();
 
   if (!quiet)
-    printf("Your identification has been saved in %s.\n", buf);
+    printf("Your identification has been saved in %s.\n", file);
 
   /* Display the public key on the screen. */
   if (!quiet) {
@@ -534,11 +570,11 @@ main(int ac, char **av)
 
   /* Save the public key in text format in a file with the same name but
      .pub appended. */
-  strcat(buf, ".pub");
-  f = fopen(buf, "w");
+  strcat(file, ".pub");
+  f = fopen(file, "w");
   if (!f)
     {
-      printf("Could not save your public key in %s\n", buf);
+      printf("Could not save your public key in %s\n", file);
       exit(1);
     }
   fprintf(f, "%d ", BN_num_bits(public_key->n));
@@ -551,7 +587,7 @@ main(int ac, char **av)
   fclose(f);
 
   if (!quiet)
-    printf("Your public key has been saved in %s\n", buf);
+    printf("Your public key has been saved in %s\n", file);
   
   exit(0);
 }
This page took 0.052108 seconds and 4 git commands to generate.