/*

ssh-keygen.c

Author: Tatu Ylonen <ylo@cs.hut.fi>

Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                   All rights reserved

Created: Mon Mar 27 02:26:40 1995 ylo

Identity and host key generation and maintenance.

*/

#include "includes.h"
RCSID("$Id: ssh-keygen.c,v 1.3 1999/11/12 04:19:27 damien Exp $");

#include "rsa.h"
#include "ssh.h"
#include "xmalloc.h"

/* Generated private key. */
RSA *private_key;

/* Generated public key. */
RSA *public_key;

/* Number of bits in the RSA key.  This value can be changed on the command
   line. */
int bits = 1024;

/* Flag indicating that we just want to change the passphrase.  This can be
   set on the command line. */
int change_passphrase = 0;

/* Flag indicating that we just want to change the comment.  This can be set
   on the command line. */
int change_comment = 0;

int quiet = 0;

/* This is set to the identity file name if given on the command line. */
char *identity_file = NULL;

/* This is set to the passphrase if given on the command line. */
char *identity_passphrase = NULL;

/* This is set to the new passphrase if given on the command line. */
char *identity_new_passphrase = NULL;

/* This is set to the new comment if given on the command line. */
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 buf[1024], *comment;
  char *old_passphrase, *passphrase1, *passphrase2;
  struct stat st;
  RSA *private_key;

  /* Read key file name. */
  if (identity_file != NULL) {
      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. */
  if (stat(buf, &st) < 0)
    {
      perror(buf);
      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))
    {
      printf("%s is not a valid key file.\n", buf);
      exit(1);
    }
  /* Clear the public key since we are just about to load the whole file. */
  RSA_free(public_key);

  /* Try to load the file with empty passphrase. */
  private_key = RSA_new();
  if (!load_private_key(buf, "", 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))
      {
	memset(old_passphrase, 0, strlen(old_passphrase));
	xfree(old_passphrase);
	printf("Bad passphrase.\n");
	exit(1);
      }
    /* Destroy the passphrase. */
    memset(old_passphrase, 0, strlen(old_passphrase));
    xfree(old_passphrase);
  }
  printf("Key has comment '%s'\n", comment);
  
  /* Ask the new passphrase (twice). */
  if (identity_new_passphrase)
    {
      passphrase1 = xstrdup(identity_new_passphrase);
      passphrase2 = NULL;
    }
  else
    {
      passphrase1 = 
	read_passphrase("Enter new passphrase (empty for no passphrase): ", 1);
      passphrase2 = read_passphrase("Enter same passphrase again: ", 1);

      /* Verify that they are the same. */
      if (strcmp(passphrase1, passphrase2) != 0)
	{
	  memset(passphrase1, 0, strlen(passphrase1));
	  memset(passphrase2, 0, strlen(passphrase2));
	  xfree(passphrase1);
	  xfree(passphrase2);
	  printf("Pass phrases do not match.  Try again.\n");
	  exit(1);
	}
      /* Destroy the other copy. */
      memset(passphrase2, 0, strlen(passphrase2));
      xfree(passphrase2);
    }

  /* Save the file using the new passphrase. */
  if (!save_private_key(buf, passphrase1, private_key, comment))
    {
      printf("Saving the key failed: %s: %s.\n",
	     buf, strerror(errno));
      memset(passphrase1, 0, strlen(passphrase1));
      xfree(passphrase1);
      RSA_free(private_key);
      xfree(comment);
      exit(1);
    }
  /* Destroy the passphrase and the copy of the key in memory. */
  memset(passphrase1, 0, strlen(passphrase1));
  xfree(passphrase1);
  RSA_free(private_key); /* Destroys contents */
  xfree(comment);

  printf("Your identification has been saved with the new passphrase.\n");
  exit(0);
}

/* Change the comment of a private key file. */

void
do_change_comment(struct passwd *pw)
{
  char buf[1024], new_comment[1024], *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);
    }

  /* Check if the file exists. */
  if (stat(buf, &st) < 0)
    {
      perror(buf);
      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))
    {
      printf("%s is not a valid key file.\n", buf);
      exit(1);
    }

  private_key = RSA_new();
  /* Try to load the file with empty passphrase. */
  if (load_private_key(buf, "", private_key, &comment))
    passphrase = xstrdup("");
  else
    {
      /* Read passphrase from the user. */
      if (identity_passphrase)
	passphrase = xstrdup(identity_passphrase);
      else
	if (identity_new_passphrase)
	  passphrase = xstrdup(identity_new_passphrase);
	else
	  passphrase = read_passphrase("Enter passphrase: ", 1);
      /* Try to load using the passphrase. */
      if (!load_private_key(buf, passphrase, private_key, &comment))
	{
	  memset(passphrase, 0, strlen(passphrase));
	  xfree(passphrase);
	  printf("Bad passphrase.\n");
	  exit(1);
	}
    }
  printf("Key now has comment '%s'\n", comment);

  if (identity_comment)
    {
      strncpy(new_comment, identity_comment, sizeof(new_comment));
      new_comment[sizeof(new_comment) - 1] = '\0';
    }
  else
    {
      printf("Enter new comment: ");
      fflush(stdout);
      if (!fgets(new_comment, sizeof(new_comment), stdin))
	{
	  memset(passphrase, 0, strlen(passphrase));
	  RSA_free(private_key);
	  exit(1);
	}
      
      /* Remove terminating newline from comment. */
      if (strchr(new_comment, '\n'))
	*strchr(new_comment, '\n') = 0;
    }
      
  /* Save the file using the new passphrase. */
  if (!save_private_key(buf, passphrase, private_key, new_comment))
    {
      printf("Saving the key failed: %s: %s.\n",
	     buf, strerror(errno));
      memset(passphrase, 0, strlen(passphrase));
      xfree(passphrase);
      RSA_free(private_key);
      xfree(comment);
      exit(1);
    }

  /* Destroy the passphrase and the private key in memory. */
  memset(passphrase, 0, strlen(passphrase));
  xfree(passphrase);
  RSA_free(private_key);

  /* Save the public key in text format in a file with the same name but
     .pub appended. */
  strcat(buf, ".pub");
  f = fopen(buf, "w");
  if (!f)
    {
      printf("Could not save your public key in %s\n", buf);
      exit(1);
    }
  fprintf(f, "%d ", BN_num_bits(public_key->n));
  tmpbuf = BN_bn2dec(public_key->e);
  fprintf(f, "%s ", tmpbuf);
  free (tmpbuf);
  tmpbuf = BN_bn2dec(public_key->n);
  fprintf(f, "%s %s\n", tmpbuf, new_comment);
  free (tmpbuf);
  fclose(f);

  xfree(comment);

  printf("The comment in your key file has been changed.\n");
  exit(0);
}

/* Main program for key management. */

int
main(int ac, char **av)
{
  char buf[16384], buf2[1024], *passphrase1, *passphrase2;
  struct passwd *pw;
  char *tmpbuf;
  int opt;
  struct stat st;
  FILE *f;
  char hostname[MAXHOSTNAMELEN];
  extern int optind;
  extern char *optarg;

  /* 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",
      __progname);
    exit(1);
  }

  /* Get user\'s passwd structure.  We need this for the home directory. */
  pw = getpwuid(getuid());
  if (!pw)
    {
      printf("You don't exist, go away!\n");
      exit(1);
    }

  /* Create ~/.ssh directory if it doesn\'t already exist. */
  snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_USER_DIR);
  if (stat(buf, &st) < 0)
    if (mkdir(buf, 0755) < 0)
      error("Could not create directory '%s'.", buf);

  /* Parse command line arguments. */
  while ((opt = getopt(ac, av, "qpcb:f:P:N:C:")) != EOF)
    {
      switch (opt)
	{
	case 'b':
	  bits = atoi(optarg);
	  if (bits < 512 || bits > 32768)
	    {
	      printf("Bits has bad value.\n");
	      exit(1);
	    }
	  break;

	case 'p':
	  change_passphrase = 1;
	  break;

	case 'c':
	  change_comment = 1;
	  break;

	case 'f':
	  identity_file = optarg;
	  break;
	  
	case 'P':
	  identity_passphrase = optarg;
	  break;

	case 'N':
	  identity_new_passphrase = optarg;
	  break;

	case 'C':
	  identity_comment = optarg;
	  break;

        case 'q':
	  quiet = 1;
	  break;

	case '?':
	default:
	  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", av[0]);
	  exit(1);
	}
    }
  if (optind < ac)
    {
      printf("Too many arguments.\n");
      exit(1);
    }
  if (change_passphrase && change_comment)
    {
      printf("Can only have one of -p and -c.\n");
      exit(1);
    }

  /* If the user requested to change the passphrase, do it now.  This
     function never returns. */
  if (change_passphrase)
    do_change_passphrase(pw);

  /* If the user requested to change the comment, do it now.  This function
     never returns. */
  if (change_comment)
    do_change_comment(pw);

  arc4random_stir();

  if (quiet)
    rsa_set_verbose(0);

  /* Generate the rsa key pair. */
  private_key = RSA_new();
  public_key = RSA_new();
  rsa_generate_key(private_key, public_key, bits);

 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);
    }

  /* If the file aready exists, ask the user to confirm. */
  if (stat(buf, &st) >= 0)
    {
      printf("%s already exists.\n", buf);
      printf("Overwrite (y/n)? ");
      fflush(stdout);
      if (fgets(buf2, sizeof(buf2), stdin) == NULL)
	exit(1);
      if (buf2[0] != 'y' && buf2[0] != 'Y')
	exit(1);
    }
  
  /* Ask for a passphrase (twice). */
  if (identity_passphrase)
    passphrase1 = xstrdup(identity_passphrase);
  else
    if (identity_new_passphrase)
      passphrase1 = xstrdup(identity_new_passphrase);
    else
      {
      passphrase_again:
	passphrase1 = 
	  read_passphrase("Enter passphrase (empty for no passphrase): ", 1);
	passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
	if (strcmp(passphrase1, passphrase2) != 0)
	  {
	    /* The passphrases do not match.  Clear them and retry. */
	    memset(passphrase1, 0, strlen(passphrase1));
	    memset(passphrase2, 0, strlen(passphrase2));
	    xfree(passphrase1);
	    xfree(passphrase2);
	    printf("Passphrases do not match.  Try again.\n");
	    goto passphrase_again;
	  }
	/* Clear the other copy of the passphrase. */
	memset(passphrase2, 0, strlen(passphrase2));
	xfree(passphrase2);
      }

  /* Create default commend field for the passphrase.  The user can later
     edit this field. */
  if (identity_comment)
    {
      strlcpy(buf2, identity_comment, sizeof(buf2));
    }
  else
    {
      if (gethostname(hostname, sizeof(hostname)) < 0)
	{
	  perror("gethostname");
	  exit(1);
	}
      snprintf(buf2, sizeof buf2, "%s@%s", pw->pw_name, hostname);
    }

  /* Save the key with the given passphrase and comment. */
  if (!save_private_key(buf, passphrase1, private_key, buf2))
    {
      printf("Saving the key failed: %s: %s.\n",
	     buf, strerror(errno));
      memset(passphrase1, 0, strlen(passphrase1));
      xfree(passphrase1);
      goto ask_file_again;
    }
  /* Clear the passphrase. */
  memset(passphrase1, 0, strlen(passphrase1));
  xfree(passphrase1);

  /* Clear the private key and the random number generator. */
  RSA_free(private_key);
  arc4random_stir();

  if (!quiet)
    printf("Your identification has been saved in %s.\n", buf);

  /* Display the public key on the screen. */
  if (!quiet) {
    printf("Your public key is:\n");
    printf("%d ", BN_num_bits(public_key->n));
    tmpbuf = BN_bn2dec(public_key->e);
    printf("%s ", tmpbuf);
    free(tmpbuf);
    tmpbuf = BN_bn2dec(public_key->n);
    printf("%s %s\n", tmpbuf, buf2);
    free(tmpbuf);
  }

  /* Save the public key in text format in a file with the same name but
     .pub appended. */
  strcat(buf, ".pub");
  f = fopen(buf, "w");
  if (!f)
    {
      printf("Could not save your public key in %s\n", buf);
      exit(1);
    }
  fprintf(f, "%d ", BN_num_bits(public_key->n));
  tmpbuf = BN_bn2dec(public_key->e);
  fprintf(f, "%s ", tmpbuf);
  free(tmpbuf);
  tmpbuf = BN_bn2dec(public_key->n);
  fprintf(f, "%s %s\n", tmpbuf, buf2);
  free(tmpbuf);
  fclose(f);

  if (!quiet)
    printf("Your public key has been saved in %s\n", buf);
  
  exit(0);
}
