diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 1999-11-16 22:49:30 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 1999-11-16 22:49:30 +0000 |
commit | 4801565298dead76938c1aae65a3a67469c3a17b (patch) | |
tree | e1a48e7d1891f7c2b221f6b4233ca4843f4fd8b7 | |
parent | b999bdce7084d4bac3384205184960ec397f8c99 (diff) |
rsa key fingerprints, idea from Bjoern Groenvall <bg@sics.se>
-rw-r--r-- | usr.bin/ssh/fingerprint.c | 39 | ||||
-rw-r--r-- | usr.bin/ssh/fingerprint.h | 6 | ||||
-rw-r--r-- | usr.bin/ssh/lib/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-add.1 | 8 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-add.c | 42 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-keygen.1 | 12 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-keygen.c | 65 | ||||
-rw-r--r-- | usr.bin/ssh/sshconnect.c | 8 |
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"); } |