summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>1999-11-16 22:49:30 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>1999-11-16 22:49:30 +0000
commit4801565298dead76938c1aae65a3a67469c3a17b (patch)
treee1a48e7d1891f7c2b221f6b4233ca4843f4fd8b7
parentb999bdce7084d4bac3384205184960ec397f8c99 (diff)
rsa key fingerprints, idea from Bjoern Groenvall <bg@sics.se>
-rw-r--r--usr.bin/ssh/fingerprint.c39
-rw-r--r--usr.bin/ssh/fingerprint.h6
-rw-r--r--usr.bin/ssh/lib/Makefile6
-rw-r--r--usr.bin/ssh/ssh-add.18
-rw-r--r--usr.bin/ssh/ssh-add.c42
-rw-r--r--usr.bin/ssh/ssh-keygen.112
-rw-r--r--usr.bin/ssh/ssh-keygen.c65
-rw-r--r--usr.bin/ssh/sshconnect.c8
8 files changed, 156 insertions, 30 deletions
diff --git a/usr.bin/ssh/fingerprint.c b/usr.bin/ssh/fingerprint.c
new file mode 100644
index 00000000000..c319fa2301f
--- /dev/null
+++ b/usr.bin/ssh/fingerprint.c
@@ -0,0 +1,39 @@
+#include "includes.h"
+RCSID("$Id: fingerprint.c,v 1.1 1999/11/16 22:49:28 markus Exp $");
+
+#include "ssh.h"
+#include "xmalloc.h"
+#include <ssl/md5.h>
+
+#define FPRINT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
+
+/* Generate key fingerprint in ascii format.
+ Based on ideas and code from Bjoern Groenvall <bg@sics.se> */
+
+char *
+fingerprint(BIGNUM *e, BIGNUM *n)
+{
+ static char retval[80];
+ MD5_CTX md;
+ unsigned char d[16];
+ char *buf;
+ int nlen, elen;
+
+ nlen = BN_num_bytes(n);
+ elen = BN_num_bytes(e);
+
+ buf = xmalloc(nlen + elen);
+
+ BN_bn2bin(n, buf);
+ BN_bn2bin(e, buf + nlen);
+
+ MD5_Init(&md);
+ MD5_Update(&md, buf, nlen + elen);
+ MD5_Final(d, &md);
+ snprintf(retval, sizeof(retval), FPRINT,
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
+ d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+ memset(buf, 0, nlen + elen);
+ xfree(buf);
+ return retval;
+}
diff --git a/usr.bin/ssh/fingerprint.h b/usr.bin/ssh/fingerprint.h
new file mode 100644
index 00000000000..c4ec22fc419
--- /dev/null
+++ b/usr.bin/ssh/fingerprint.h
@@ -0,0 +1,6 @@
+/* RCSID("$Id: fingerprint.h,v 1.1 1999/11/16 22:49:28 markus Exp $"); */
+
+#ifndef FINGERPRINT_H
+#define FINGERPRINT_H
+char * fingerprint(BIGNUM *e, BIGNUM *n);
+#endif
diff --git a/usr.bin/ssh/lib/Makefile b/usr.bin/ssh/lib/Makefile
index 21b2bbacf12..0212ae79343 100644
--- a/usr.bin/ssh/lib/Makefile
+++ b/usr.bin/ssh/lib/Makefile
@@ -2,9 +2,9 @@
LIB= ssh
SRCS= authfd.c authfile.c bufaux.c buffer.c canohost.c channels.c \
- cipher.c compat.c compress.c crc32.c deattack.c hostfile.c \
- log.c match.c mpaux.c nchan.c packet.c readpass.c rsa.c \
- tildexpand.c ttymodes.c uidswap.c xmalloc.c
+ cipher.c compat.c compress.c crc32.c deattack.c fingerprint.c \
+ hostfile.c log.c match.c mpaux.c nchan.c packet.c readpass.c \
+ rsa.c tildexpand.c ttymodes.c uidswap.c xmalloc.c
NOPROFILE= yes
NOPIC= yes
diff --git a/usr.bin/ssh/ssh-add.1 b/usr.bin/ssh/ssh-add.1
index 4e09929ff72..1d56e6ba4ce 100644
--- a/usr.bin/ssh/ssh-add.1
+++ b/usr.bin/ssh/ssh-add.1
@@ -9,7 +9,7 @@
.\"
.\" Created: Sat Apr 22 23:55:14 1995 ylo
.\"
-.\" $Id: ssh-add.1,v 1.6 1999/10/17 20:35:46 aaron Exp $
+.\" $Id: ssh-add.1,v 1.7 1999/11/16 22:49:28 markus Exp $
.\"
.Dd September 25, 1999
.Dt SSH-ADD 1
@@ -19,7 +19,7 @@
.Nd adds identities for the authentication agent
.Sh SYNOPSIS
.Nm ssh-add
-.Op Fl ldD
+.Op Fl lLdD
.Op Ar
.Sh DESCRIPTION
.Nm
@@ -41,7 +41,9 @@ to work.
The options are as follows:
.Bl -tag -width Ds
.It Fl l
-Lists all identities currently represented by the agent.
+Lists fingerprints of all identities currently represented by the agent.
+.It Fl L
+Lists public key parameters of all identities currently represented by the agent.
.It Fl d
Instead of adding the identity, removes the identity from the agent.
.It Fl D
diff --git a/usr.bin/ssh/ssh-add.c b/usr.bin/ssh/ssh-add.c
index 75e584b2cdd..4971f815211 100644
--- a/usr.bin/ssh/ssh-add.c
+++ b/usr.bin/ssh/ssh-add.c
@@ -14,12 +14,13 @@ Adds an identity to the authentication server, or removes an identity.
*/
#include "includes.h"
-RCSID("$Id: ssh-add.c,v 1.10 1999/11/15 20:53:24 markus Exp $");
+RCSID("$Id: ssh-add.c,v 1.11 1999/11/16 22:49:28 markus Exp $");
#include "rsa.h"
#include "ssh.h"
#include "xmalloc.h"
#include "authfd.h"
+#include "fingerprint.h"
void
delete_file(AuthenticationConnection *ac, const char *filename)
@@ -103,7 +104,7 @@ add_file(AuthenticationConnection *ac, const char *filename)
}
void
-list_identities(AuthenticationConnection *ac)
+list_identities(AuthenticationConnection *ac, int fp)
{
BIGNUM *e, *n;
int status;
@@ -117,21 +118,25 @@ list_identities(AuthenticationConnection *ac)
status;
status = ssh_get_next_identity(ac, e, n, &comment))
{
- char *ebuf, *nbuf;
+ unsigned int bits = BN_num_bits(n);
had_identities = 1;
- ebuf = BN_bn2dec(e);
- if (ebuf == NULL) {
- error("list_identities: BN_bn2dec(e) failed.");
- }else{
- nbuf = BN_bn2dec(n);
- if (nbuf == NULL) {
- error("list_identities: BN_bn2dec(n) failed.");
- }else{
- unsigned int bits = BN_num_bits(n);
- printf("%d %s %s %s\n", bits, ebuf, nbuf, comment);
- free(nbuf);
- }
- free(ebuf);
+ if (fp) {
+ printf("%d %s %s\n", bits, fingerprint(e, n), comment);
+ } else {
+ char *ebuf, *nbuf;
+ ebuf = BN_bn2dec(e);
+ if (ebuf == NULL) {
+ error("list_identities: BN_bn2dec(e) failed.");
+ }else{
+ nbuf = BN_bn2dec(n);
+ if (nbuf == NULL) {
+ error("list_identities: BN_bn2dec(n) failed.");
+ }else{
+ printf("%d %s %s %s\n", bits, ebuf, nbuf, comment);
+ free(nbuf);
+ }
+ free(ebuf);
+ }
}
xfree(comment);
}
@@ -170,9 +175,10 @@ main(int argc, char **argv)
for (i = 1; i < argc; i++)
{
- if (strcmp(argv[i], "-l") == 0)
+ if ((strcmp(argv[i], "-l") == 0) ||
+ (strcmp(argv[i], "-L") == 0))
{
- list_identities(ac);
+ list_identities(ac, argv[i][1] == 'l' ? 1 : 0);
no_files = 0; /* Don't default-add/delete if -l. */
continue;
}
diff --git a/usr.bin/ssh/ssh-keygen.1 b/usr.bin/ssh/ssh-keygen.1
index 4c40dc21efc..7d50025533d 100644
--- a/usr.bin/ssh/ssh-keygen.1
+++ b/usr.bin/ssh/ssh-keygen.1
@@ -9,7 +9,7 @@
.\"
.\" Created: Sat Apr 22 23:55:14 1995 ylo
.\"
-.\" $Id: ssh-keygen.1,v 1.8 1999/11/15 07:18:46 ericj Exp $
+.\" $Id: ssh-keygen.1,v 1.9 1999/11/16 22:49:28 markus Exp $
.\"
.Dd September 25, 1999
.Dt SSH-KEYGEN 1
@@ -23,14 +23,20 @@
.Op Fl b Ar bits
.Op Fl N Ar new_passphrase
.Op Fl C Ar comment
+.Op Fl f Ar keyfile
.Nm ssh-keygen
.Fl p
.Op Fl P Ar old_passphrase
.Op Fl N Ar new_passphrase
+.Op Fl f Ar keyfile
.Nm ssh-keygen
.Fl c
.Op Fl P Ar passphrase
.Op Fl C Ar comment
+.Op Fl f Ar keyfile
+.Nm ssh-keygen
+.Fl l
+.Op Fl f Ar keyfile
.Sh DESCRIPTION
.Nm
generates and manages authentication keys for
@@ -79,6 +85,10 @@ default is 1024 bits.
Requests changing the comment in the private and public key files.
The program will prompt for the file containing the private keys, for
passphrase if the key has one, and for the new comment.
+.It Fl f
+Specifies the filename of the key file.
+.It Fl l
+Show fingerprint of specified private or public key file.
.It Fl p
Requests changing the passphrase of a private key file instead of
creating a new private key. The program will prompt for the file
diff --git a/usr.bin/ssh/ssh-keygen.c b/usr.bin/ssh/ssh-keygen.c
index ead2696daf0..2d4c4a71111 100644
--- a/usr.bin/ssh/ssh-keygen.c
+++ b/usr.bin/ssh/ssh-keygen.c
@@ -14,11 +14,12 @@ Identity and host key generation and maintenance.
*/
#include "includes.h"
-RCSID("$Id: ssh-keygen.c,v 1.7 1999/11/16 22:27:54 markus Exp $");
+RCSID("$Id: ssh-keygen.c,v 1.8 1999/11/16 22:49:28 markus Exp $");
#include "rsa.h"
#include "ssh.h"
#include "xmalloc.h"
+#include "fingerprint.h"
/* Generated private key. */
RSA *private_key;
@@ -40,6 +41,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;
@@ -79,6 +83,56 @@ get_filename(struct passwd *pw, const char *prompt)
}
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;
@@ -330,7 +384,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)
{
@@ -343,6 +397,10 @@ main(int ac, char **av)
}
break;
+ case 'l':
+ print_fingerprint = 1;
+ break;
+
case 'p':
change_passphrase = 1;
break;
@@ -389,6 +447,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)
diff --git a/usr.bin/ssh/sshconnect.c b/usr.bin/ssh/sshconnect.c
index ed3758cc68e..c5559629f2e 100644
--- a/usr.bin/ssh/sshconnect.c
+++ b/usr.bin/ssh/sshconnect.c
@@ -15,7 +15,7 @@ login (authentication) dialog.
*/
#include "includes.h"
-RCSID("$Id: sshconnect.c,v 1.32 1999/11/16 20:44:42 markus Exp $");
+RCSID("$Id: sshconnect.c,v 1.33 1999/11/16 22:49:28 markus Exp $");
#include <ssl/bn.h>
#include "xmalloc.h"
@@ -1199,10 +1199,12 @@ void ssh_login(int host_key_valid,
fatal("No host key is known for %.200s and you have requested strict checking.", host);
} else if (options.strict_host_key_checking == 2) { /* The default */
char prompt[1024];
+ char *fp = fingerprint(host_key->e, host_key->n);
snprintf(prompt, sizeof(prompt),
"The authenticity of host '%.200s' can't be established.\n"
- "Are you sure you want to continue connecting (yes/no)? ",
- host);
+ "Key fingerprint is %d %s.\n"
+ "Are you sure you want to continue connecting (yes/no)? ",
+ host, BN_num_bits(host_key->n), fp);
if (!read_yes_or_no(prompt, -1))
fatal("Aborted by user!\n");
}