summaryrefslogtreecommitdiffstats
path: root/ssh-keygen.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-11-17 17:29:08 +1100
committerDamien Miller <djm@mindrot.org>1999-11-17 17:29:08 +1100
commit10f6f6ba9ee14d306f8780edee8a10640c1643e0 (patch)
tree859600c705d582b147162d73746cb2f39b59ed58 /ssh-keygen.c
parentd743bba481056ba3d1c229c18fd42c6bdc3f8d74 (diff)
- Merged OpenBSD CVS changes
- [ChangeLog.Ylonen] noone needs this anymore - [authfd.c] close-on-exec for auth-socket, ok deraadt - [hostfile.c] in known_hosts key lookup the entry for the bits does not need to match, all the information is contained in n and e. This solves the problem with buggy servers announcing the wrong modulus length. markus and me. - [serverloop.c] bugfix: check for space if child has terminated, from: iedowse@maths.tcd.ie - [ssh-add.1 ssh-add.c ssh-keygen.1 ssh-keygen.c sshconnect.c] [fingerprint.c fingerprint.h] rsa key fingerprints, idea from Bjoern Groenvall <bg@sics.se> - [ssh-agent.1] typo - [ssh.1] add OpenSSH information to AUTHOR section. okay markus@ - [sshd.c] force logging to stderr while loading private key file (lost while converting to new log-levels)
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c198
1 files changed, 117 insertions, 81 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 10289cab..deb08dd9 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -14,11 +14,12 @@ Identity and host key generation and maintenance.
*/
#include "includes.h"
-RCSID("$Id: ssh-keygen.c,v 1.4 1999/11/15 06:10:57 damien Exp $");
+RCSID("$Id: ssh-keygen.c,v 1.5 1999/11/17 06:29:08 damien Exp $");
#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);
}