diff options
-rw-r--r-- | auth-rsa.c | 5 | ||||
-rw-r--r-- | auth.c | 5 | ||||
-rw-r--r-- | auth2-hostbased.c | 7 | ||||
-rw-r--r-- | auth2-pubkey.c | 16 | ||||
-rw-r--r-- | digest-libc.c | 22 | ||||
-rw-r--r-- | digest-openssl.c | 22 | ||||
-rw-r--r-- | digest.h | 8 | ||||
-rw-r--r-- | dns.c | 11 | ||||
-rw-r--r-- | key.c | 7 | ||||
-rw-r--r-- | key.h | 4 | ||||
-rw-r--r-- | krl.c | 8 | ||||
-rw-r--r-- | readconf.c | 24 | ||||
-rw-r--r-- | readconf.h | 4 | ||||
-rw-r--r-- | servconf.c | 24 | ||||
-rw-r--r-- | servconf.h | 4 | ||||
-rw-r--r-- | ssh-add.1 | 13 | ||||
-rw-r--r-- | ssh-add.c | 54 | ||||
-rw-r--r-- | ssh-agent.1 | 13 | ||||
-rw-r--r-- | ssh-agent.c | 15 | ||||
-rw-r--r-- | ssh-keygen.1 | 13 | ||||
-rw-r--r-- | ssh-keygen.c | 58 | ||||
-rw-r--r-- | ssh-keysign.c | 5 | ||||
-rw-r--r-- | ssh.1 | 6 | ||||
-rw-r--r-- | sshconnect.c | 27 | ||||
-rw-r--r-- | sshconnect2.c | 6 | ||||
-rw-r--r-- | sshd_config.5 | 13 | ||||
-rw-r--r-- | sshkey.c | 113 | ||||
-rw-r--r-- | sshkey.h | 16 |
28 files changed, 374 insertions, 149 deletions
diff --git a/auth-rsa.c b/auth-rsa.c index e9f4ede26..ff7a13221 100644 --- a/auth-rsa.c +++ b/auth-rsa.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-rsa.c,v 1.88 2014/07/15 15:54:14 millert Exp $ */ | 1 | /* $OpenBSD: auth-rsa.c,v 1.89 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -236,7 +236,8 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file, | |||
236 | "actual %d vs. announced %d.", | 236 | "actual %d vs. announced %d.", |
237 | file, linenum, BN_num_bits(key->rsa->n), bits); | 237 | file, linenum, BN_num_bits(key->rsa->n), bits); |
238 | 238 | ||
239 | fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | 239 | fp = key_fingerprint(key, options.fingerprint_hash, |
240 | SSH_FP_DEFAULT); | ||
240 | debug("matching key found: file %s, line %lu %s %s", | 241 | debug("matching key found: file %s, line %lu %s %s", |
241 | file, linenum, key_type(key), fp); | 242 | file, linenum, key_type(key), fp); |
242 | free(fp); | 243 | free(fp); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth.c,v 1.107 2014/12/04 02:24:32 djm Exp $ */ | 1 | /* $OpenBSD: auth.c,v 1.108 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -679,7 +679,8 @@ auth_key_is_revoked(Key *key) | |||
679 | 679 | ||
680 | if (options.revoked_keys_file == NULL) | 680 | if (options.revoked_keys_file == NULL) |
681 | return 0; | 681 | return 0; |
682 | if ((fp = sshkey_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX)) == NULL) { | 682 | if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, |
683 | SSH_FP_DEFAULT)) == NULL) { | ||
683 | r = SSH_ERR_ALLOC_FAIL; | 684 | r = SSH_ERR_ALLOC_FAIL; |
684 | error("%s: fingerprint key: %s", __func__, ssh_err(r)); | 685 | error("%s: fingerprint key: %s", __func__, ssh_err(r)); |
685 | goto out; | 686 | goto out; |
diff --git a/auth2-hostbased.c b/auth2-hostbased.c index 6787e4ca4..b7ae35356 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-hostbased.c,v 1.18 2014/07/15 15:54:14 millert Exp $ */ | 1 | /* $OpenBSD: auth2-hostbased.c,v 1.19 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -208,13 +208,14 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, | |||
208 | if (host_status == HOST_OK) { | 208 | if (host_status == HOST_OK) { |
209 | if (key_is_cert(key)) { | 209 | if (key_is_cert(key)) { |
210 | fp = key_fingerprint(key->cert->signature_key, | 210 | fp = key_fingerprint(key->cert->signature_key, |
211 | SSH_FP_MD5, SSH_FP_HEX); | 211 | options.fingerprint_hash, SSH_FP_DEFAULT); |
212 | verbose("Accepted certificate ID \"%s\" signed by " | 212 | verbose("Accepted certificate ID \"%s\" signed by " |
213 | "%s CA %s from %s@%s", key->cert->key_id, | 213 | "%s CA %s from %s@%s", key->cert->key_id, |
214 | key_type(key->cert->signature_key), fp, | 214 | key_type(key->cert->signature_key), fp, |
215 | cuser, lookup); | 215 | cuser, lookup); |
216 | } else { | 216 | } else { |
217 | fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | 217 | fp = key_fingerprint(key, options.fingerprint_hash, |
218 | SSH_FP_DEFAULT); | ||
218 | verbose("Accepted %s public key %s from %s@%s", | 219 | verbose("Accepted %s public key %s from %s@%s", |
219 | key_type(key), fp, cuser, lookup); | 220 | key_type(key), fp, cuser, lookup); |
220 | } | 221 | } |
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 0a3c1deee..04b70e362 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-pubkey.c,v 1.42 2014/12/04 02:24:32 djm Exp $ */ | 1 | /* $OpenBSD: auth2-pubkey.c,v 1.43 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -213,7 +213,7 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) | |||
213 | 213 | ||
214 | if (key_is_cert(key)) { | 214 | if (key_is_cert(key)) { |
215 | fp = key_fingerprint(key->cert->signature_key, | 215 | fp = key_fingerprint(key->cert->signature_key, |
216 | SSH_FP_MD5, SSH_FP_HEX); | 216 | options.fingerprint_hash, SSH_FP_DEFAULT); |
217 | auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", | 217 | auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", |
218 | key_type(key), key->cert->key_id, | 218 | key_type(key), key->cert->key_id, |
219 | (unsigned long long)key->cert->serial, | 219 | (unsigned long long)key->cert->serial, |
@@ -221,7 +221,8 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) | |||
221 | extra == NULL ? "" : ", ", extra == NULL ? "" : extra); | 221 | extra == NULL ? "" : ", ", extra == NULL ? "" : extra); |
222 | free(fp); | 222 | free(fp); |
223 | } else { | 223 | } else { |
224 | fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | 224 | fp = key_fingerprint(key, options.fingerprint_hash, |
225 | SSH_FP_DEFAULT); | ||
225 | auth_info(authctxt, "%s %s%s%s", key_type(key), fp, | 226 | auth_info(authctxt, "%s %s%s%s", key_type(key), fp, |
226 | extra == NULL ? "" : ", ", extra == NULL ? "" : extra); | 227 | extra == NULL ? "" : ", ", extra == NULL ? "" : extra); |
227 | free(fp); | 228 | free(fp); |
@@ -365,8 +366,8 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) | |||
365 | continue; | 366 | continue; |
366 | if (!key_is_cert_authority) | 367 | if (!key_is_cert_authority) |
367 | continue; | 368 | continue; |
368 | fp = key_fingerprint(found, SSH_FP_MD5, | 369 | fp = key_fingerprint(found, options.fingerprint_hash, |
369 | SSH_FP_HEX); | 370 | SSH_FP_DEFAULT); |
370 | debug("matching CA found: file %s, line %lu, %s %s", | 371 | debug("matching CA found: file %s, line %lu, %s %s", |
371 | file, linenum, key_type(found), fp); | 372 | file, linenum, key_type(found), fp); |
372 | /* | 373 | /* |
@@ -406,7 +407,8 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) | |||
406 | if (key_is_cert_authority) | 407 | if (key_is_cert_authority) |
407 | continue; | 408 | continue; |
408 | found_key = 1; | 409 | found_key = 1; |
409 | fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); | 410 | fp = key_fingerprint(found, options.fingerprint_hash, |
411 | SSH_FP_DEFAULT); | ||
410 | debug("matching key found: file %s, line %lu %s %s", | 412 | debug("matching key found: file %s, line %lu %s %s", |
411 | file, linenum, key_type(found), fp); | 413 | file, linenum, key_type(found), fp); |
412 | free(fp); | 414 | free(fp); |
@@ -432,7 +434,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) | |||
432 | return 0; | 434 | return 0; |
433 | 435 | ||
434 | ca_fp = key_fingerprint(key->cert->signature_key, | 436 | ca_fp = key_fingerprint(key->cert->signature_key, |
435 | SSH_FP_MD5, SSH_FP_HEX); | 437 | options.fingerprint_hash, SSH_FP_DEFAULT); |
436 | 438 | ||
437 | if (sshkey_in_file(key->cert->signature_key, | 439 | if (sshkey_in_file(key->cert->signature_key, |
438 | options.trusted_user_ca_keys, 1, 0) != 0) { | 440 | options.trusted_user_ca_keys, 1, 0) != 0) { |
diff --git a/digest-libc.c b/digest-libc.c index 1b4423a05..169ded075 100644 --- a/digest-libc.c +++ b/digest-libc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: digest-libc.c,v 1.3 2014/06/24 01:13:21 djm Exp $ */ | 1 | /* $OpenBSD: digest-libc.c,v 1.4 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> |
4 | * Copyright (c) 2014 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2014 Markus Friedl. All rights reserved. |
@@ -126,6 +126,26 @@ ssh_digest_by_alg(int alg) | |||
126 | return &(digests[alg]); | 126 | return &(digests[alg]); |
127 | } | 127 | } |
128 | 128 | ||
129 | int | ||
130 | ssh_digest_alg_by_name(const char *name) | ||
131 | { | ||
132 | int alg; | ||
133 | |||
134 | for (alg = 0; alg < SSH_DIGEST_MAX; alg++) { | ||
135 | if (strcasecmp(name, digests[alg].name) == 0) | ||
136 | return digests[alg].id; | ||
137 | } | ||
138 | return -1; | ||
139 | } | ||
140 | |||
141 | const char * | ||
142 | ssh_digest_alg_name(int alg) | ||
143 | { | ||
144 | const struct ssh_digest *digest = ssh_digest_by_alg(alg); | ||
145 | |||
146 | return digest == NULL ? NULL : digest->name; | ||
147 | } | ||
148 | |||
129 | size_t | 149 | size_t |
130 | ssh_digest_bytes(int alg) | 150 | ssh_digest_bytes(int alg) |
131 | { | 151 | { |
diff --git a/digest-openssl.c b/digest-openssl.c index 02b170341..bb58ff226 100644 --- a/digest-openssl.c +++ b/digest-openssl.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: digest-openssl.c,v 1.4 2014/07/03 03:26:43 djm Exp $ */ | 1 | /* $OpenBSD: digest-openssl.c,v 1.5 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> |
4 | * | 4 | * |
@@ -74,6 +74,26 @@ ssh_digest_by_alg(int alg) | |||
74 | return &(digests[alg]); | 74 | return &(digests[alg]); |
75 | } | 75 | } |
76 | 76 | ||
77 | int | ||
78 | ssh_digest_alg_by_name(const char *name) | ||
79 | { | ||
80 | int alg; | ||
81 | |||
82 | for (alg = 0; digests[alg].id != -1; alg++) { | ||
83 | if (strcasecmp(name, digests[alg].name) == 0) | ||
84 | return digests[alg].id; | ||
85 | } | ||
86 | return -1; | ||
87 | } | ||
88 | |||
89 | const char * | ||
90 | ssh_digest_alg_name(int alg) | ||
91 | { | ||
92 | const struct ssh_digest *digest = ssh_digest_by_alg(alg); | ||
93 | |||
94 | return digest == NULL ? NULL : digest->name; | ||
95 | } | ||
96 | |||
77 | size_t | 97 | size_t |
78 | ssh_digest_bytes(int alg) | 98 | ssh_digest_bytes(int alg) |
79 | { | 99 | { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: digest.h,v 1.6 2014/07/03 04:36:45 djm Exp $ */ | 1 | /* $OpenBSD: digest.h,v 1.7 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> |
4 | * | 4 | * |
@@ -33,6 +33,12 @@ | |||
33 | struct sshbuf; | 33 | struct sshbuf; |
34 | struct ssh_digest_ctx; | 34 | struct ssh_digest_ctx; |
35 | 35 | ||
36 | /* Looks up a digest algorithm by name */ | ||
37 | int ssh_digest_alg_by_name(const char *name); | ||
38 | |||
39 | /* Returns the algorithm name for a digest identifier */ | ||
40 | const char *ssh_digest_alg_name(int alg); | ||
41 | |||
36 | /* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ | 42 | /* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ |
37 | size_t ssh_digest_bytes(int alg); | 43 | size_t ssh_digest_bytes(int alg); |
38 | 44 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: dns.c,v 1.31 2014/06/24 01:13:21 djm Exp $ */ | 1 | /* $OpenBSD: dns.c,v 1.32 2014/12/21 22:27:56 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2003 Wesley Griffin. All rights reserved. | 4 | * Copyright (c) 2003 Wesley Griffin. All rights reserved. |
@@ -41,6 +41,7 @@ | |||
41 | #include "key.h" | 41 | #include "key.h" |
42 | #include "dns.h" | 42 | #include "dns.h" |
43 | #include "log.h" | 43 | #include "log.h" |
44 | #include "digest.h" | ||
44 | 45 | ||
45 | static const char *errset_text[] = { | 46 | static const char *errset_text[] = { |
46 | "success", /* 0 ERRSET_SUCCESS */ | 47 | "success", /* 0 ERRSET_SUCCESS */ |
@@ -80,7 +81,7 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, | |||
80 | u_char **digest, u_int *digest_len, Key *key) | 81 | u_char **digest, u_int *digest_len, Key *key) |
81 | { | 82 | { |
82 | int success = 0; | 83 | int success = 0; |
83 | enum fp_type fp_type = 0; | 84 | int fp_alg = -1; |
84 | 85 | ||
85 | switch (key->type) { | 86 | switch (key->type) { |
86 | case KEY_RSA: | 87 | case KEY_RSA: |
@@ -110,17 +111,17 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, | |||
110 | 111 | ||
111 | switch (*digest_type) { | 112 | switch (*digest_type) { |
112 | case SSHFP_HASH_SHA1: | 113 | case SSHFP_HASH_SHA1: |
113 | fp_type = SSH_FP_SHA1; | 114 | fp_alg = SSH_DIGEST_SHA1; |
114 | break; | 115 | break; |
115 | case SSHFP_HASH_SHA256: | 116 | case SSHFP_HASH_SHA256: |
116 | fp_type = SSH_FP_SHA256; | 117 | fp_alg = SSH_DIGEST_SHA256; |
117 | break; | 118 | break; |
118 | default: | 119 | default: |
119 | *digest_type = SSHFP_HASH_RESERVED; /* 0 */ | 120 | *digest_type = SSHFP_HASH_RESERVED; /* 0 */ |
120 | } | 121 | } |
121 | 122 | ||
122 | if (*algorithm && *digest_type) { | 123 | if (*algorithm && *digest_type) { |
123 | *digest = key_fingerprint_raw(key, fp_type, digest_len); | 124 | *digest = key_fingerprint_raw(key, fp_alg, digest_len); |
124 | if (*digest == NULL) | 125 | if (*digest == NULL) |
125 | fatal("dns_read_key: null from key_fingerprint_raw()"); | 126 | fatal("dns_read_key: null from key_fingerprint_raw()"); |
126 | success = 1; | 127 | success = 1; |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: key.c,v 1.123 2014/12/04 20:47:36 djm Exp $ */ | 1 | /* $OpenBSD: key.c,v 1.124 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * placed in the public domain | 3 | * placed in the public domain |
4 | */ | 4 | */ |
@@ -40,8 +40,7 @@ key_new_private(int type) | |||
40 | } | 40 | } |
41 | 41 | ||
42 | u_char* | 42 | u_char* |
43 | key_fingerprint_raw(const Key *k, enum fp_type dgst_type, | 43 | key_fingerprint_raw(const Key *k, int dgst_alg, u_int *dgst_raw_length) |
44 | u_int *dgst_raw_length) | ||
45 | { | 44 | { |
46 | u_char *ret = NULL; | 45 | u_char *ret = NULL; |
47 | size_t dlen; | 46 | size_t dlen; |
@@ -49,7 +48,7 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type, | |||
49 | 48 | ||
50 | if (dgst_raw_length != NULL) | 49 | if (dgst_raw_length != NULL) |
51 | *dgst_raw_length = 0; | 50 | *dgst_raw_length = 0; |
52 | if ((r = sshkey_fingerprint_raw(k, dgst_type, &ret, &dlen)) != 0) | 51 | if ((r = sshkey_fingerprint_raw(k, dgst_alg, &ret, &dlen)) != 0) |
53 | fatal("%s: %s", __func__, ssh_err(r)); | 52 | fatal("%s: %s", __func__, ssh_err(r)); |
54 | if (dlen > INT_MAX) | 53 | if (dlen > INT_MAX) |
55 | fatal("%s: giant len %zu", __func__, dlen); | 54 | fatal("%s: giant len %zu", __func__, dlen); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: key.h,v 1.43 2014/12/04 20:47:36 djm Exp $ */ | 1 | /* $OpenBSD: key.h,v 1.44 2014/12/21 22:27:56 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -67,7 +67,7 @@ void key_add_private(Key *); | |||
67 | Key *key_new_private(int); | 67 | Key *key_new_private(int); |
68 | void key_free(Key *); | 68 | void key_free(Key *); |
69 | Key *key_demote(const Key *); | 69 | Key *key_demote(const Key *); |
70 | u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *); | 70 | u_char *key_fingerprint_raw(const Key *, int, u_int *); |
71 | int key_write(const Key *, FILE *); | 71 | int key_write(const Key *, FILE *); |
72 | int key_read(Key *, char **); | 72 | int key_read(Key *, char **); |
73 | 73 | ||
@@ -14,7 +14,7 @@ | |||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /* $OpenBSD: krl.c,v 1.20 2014/12/04 01:49:59 djm Exp $ */ | 17 | /* $OpenBSD: krl.c,v 1.21 2014/12/21 22:27:56 djm Exp $ */ |
18 | 18 | ||
19 | #include "includes.h" | 19 | #include "includes.h" |
20 | 20 | ||
@@ -36,6 +36,7 @@ | |||
36 | #include "misc.h" | 36 | #include "misc.h" |
37 | #include "log.h" | 37 | #include "log.h" |
38 | #include "ssherr.h" | 38 | #include "ssherr.h" |
39 | #include "digest.h" | ||
39 | 40 | ||
40 | #include "krl.h" | 41 | #include "krl.h" |
41 | 42 | ||
@@ -411,7 +412,8 @@ ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key) | |||
411 | int r; | 412 | int r; |
412 | 413 | ||
413 | debug3("%s: revoke type %s by sha1", __func__, sshkey_type(key)); | 414 | debug3("%s: revoke type %s by sha1", __func__, sshkey_type(key)); |
414 | if ((r = sshkey_fingerprint_raw(key, SSH_FP_SHA1, &blob, &len)) != 0) | 415 | if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1, |
416 | &blob, &len)) != 0) | ||
415 | return r; | 417 | return r; |
416 | return revoke_blob(&krl->revoked_sha1s, blob, len); | 418 | return revoke_blob(&krl->revoked_sha1s, blob, len); |
417 | } | 419 | } |
@@ -1151,7 +1153,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) | |||
1151 | 1153 | ||
1152 | /* Check explicitly revoked hashes first */ | 1154 | /* Check explicitly revoked hashes first */ |
1153 | memset(&rb, 0, sizeof(rb)); | 1155 | memset(&rb, 0, sizeof(rb)); |
1154 | if ((r = sshkey_fingerprint_raw(key, SSH_FP_SHA1, | 1156 | if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1, |
1155 | &rb.blob, &rb.len)) != 0) | 1157 | &rb.blob, &rb.len)) != 0) |
1156 | return r; | 1158 | return r; |
1157 | erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); | 1159 | erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); |
diff --git a/readconf.c b/readconf.c index e0386935f..399b73e98 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.c,v 1.223 2014/12/04 02:24:32 djm Exp $ */ | 1 | /* $OpenBSD: readconf.c,v 1.224 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -60,6 +60,7 @@ | |||
60 | #include "mac.h" | 60 | #include "mac.h" |
61 | #include "uidswap.h" | 61 | #include "uidswap.h" |
62 | #include "myproposal.h" | 62 | #include "myproposal.h" |
63 | #include "digest.h" | ||
63 | 64 | ||
64 | /* Format of the configuration file: | 65 | /* Format of the configuration file: |
65 | 66 | ||
@@ -155,6 +156,7 @@ typedef enum { | |||
155 | oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, | 156 | oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, |
156 | oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, | 157 | oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, |
157 | oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, | 158 | oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, |
159 | oFingerprintHash, | ||
158 | oIgnoredUnknownOption, oDeprecated, oUnsupported | 160 | oIgnoredUnknownOption, oDeprecated, oUnsupported |
159 | } OpCodes; | 161 | } OpCodes; |
160 | 162 | ||
@@ -270,6 +272,7 @@ static struct { | |||
270 | { "streamlocalbindmask", oStreamLocalBindMask }, | 272 | { "streamlocalbindmask", oStreamLocalBindMask }, |
271 | { "streamlocalbindunlink", oStreamLocalBindUnlink }, | 273 | { "streamlocalbindunlink", oStreamLocalBindUnlink }, |
272 | { "revokedhostkeys", oRevokedHostKeys }, | 274 | { "revokedhostkeys", oRevokedHostKeys }, |
275 | { "fingerprinthash", oFingerprintHash }, | ||
273 | { "ignoreunknown", oIgnoreUnknown }, | 276 | { "ignoreunknown", oIgnoreUnknown }, |
274 | 277 | ||
275 | { NULL, oBadOption } | 278 | { NULL, oBadOption } |
@@ -1460,6 +1463,18 @@ parse_int: | |||
1460 | charptr = &options->revoked_host_keys; | 1463 | charptr = &options->revoked_host_keys; |
1461 | goto parse_string; | 1464 | goto parse_string; |
1462 | 1465 | ||
1466 | case oFingerprintHash: | ||
1467 | arg = strdelim(&s); | ||
1468 | if (!arg || *arg == '\0') | ||
1469 | fatal("%.200s line %d: Missing argument.", | ||
1470 | filename, linenum); | ||
1471 | if ((value = ssh_digest_alg_by_name(arg)) == -1) | ||
1472 | fatal("%.200s line %d: Invalid hash algorithm \"%s\".", | ||
1473 | filename, linenum, arg); | ||
1474 | if (*activep) | ||
1475 | options->fingerprint_hash = value; | ||
1476 | break; | ||
1477 | |||
1463 | case oDeprecated: | 1478 | case oDeprecated: |
1464 | debug("%s line %d: Deprecated option \"%s\"", | 1479 | debug("%s line %d: Deprecated option \"%s\"", |
1465 | filename, linenum, keyword); | 1480 | filename, linenum, keyword); |
@@ -1637,6 +1652,7 @@ initialize_options(Options * options) | |||
1637 | options->canonicalize_fallback_local = -1; | 1652 | options->canonicalize_fallback_local = -1; |
1638 | options->canonicalize_hostname = -1; | 1653 | options->canonicalize_hostname = -1; |
1639 | options->revoked_host_keys = NULL; | 1654 | options->revoked_host_keys = NULL; |
1655 | options->fingerprint_hash = -1; | ||
1640 | } | 1656 | } |
1641 | 1657 | ||
1642 | /* | 1658 | /* |
@@ -1814,6 +1830,9 @@ fill_default_options(Options * options) | |||
1814 | options->canonicalize_fallback_local = 1; | 1830 | options->canonicalize_fallback_local = 1; |
1815 | if (options->canonicalize_hostname == -1) | 1831 | if (options->canonicalize_hostname == -1) |
1816 | options->canonicalize_hostname = SSH_CANONICALISE_NO; | 1832 | options->canonicalize_hostname = SSH_CANONICALISE_NO; |
1833 | if (options->fingerprint_hash == -1) | ||
1834 | options->fingerprint_hash = SSH_FP_HASH_DEFAULT; | ||
1835 | |||
1817 | #define CLEAR_ON_NONE(v) \ | 1836 | #define CLEAR_ON_NONE(v) \ |
1818 | do { \ | 1837 | do { \ |
1819 | if (option_clear_or_none(v)) { \ | 1838 | if (option_clear_or_none(v)) { \ |
@@ -2071,6 +2090,8 @@ fmt_intarg(OpCodes code, int val) | |||
2071 | return fmt_multistate_int(val, multistate_requesttty); | 2090 | return fmt_multistate_int(val, multistate_requesttty); |
2072 | case oCanonicalizeHostname: | 2091 | case oCanonicalizeHostname: |
2073 | return fmt_multistate_int(val, multistate_canonicalizehostname); | 2092 | return fmt_multistate_int(val, multistate_canonicalizehostname); |
2093 | case oFingerprintHash: | ||
2094 | return ssh_digest_alg_name(val); | ||
2074 | case oProtocol: | 2095 | case oProtocol: |
2075 | switch (val) { | 2096 | switch (val) { |
2076 | case SSH_PROTO_1: | 2097 | case SSH_PROTO_1: |
@@ -2205,6 +2226,7 @@ dump_client_config(Options *o, const char *host) | |||
2205 | dump_cfg_fmtint(oControlMaster, o->control_master); | 2226 | dump_cfg_fmtint(oControlMaster, o->control_master); |
2206 | dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); | 2227 | dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); |
2207 | dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); | 2228 | dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); |
2229 | dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); | ||
2208 | dump_cfg_fmtint(oForwardAgent, o->forward_agent); | 2230 | dump_cfg_fmtint(oForwardAgent, o->forward_agent); |
2209 | dump_cfg_fmtint(oForwardX11, o->forward_x11); | 2231 | dump_cfg_fmtint(oForwardX11, o->forward_x11); |
2210 | dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); | 2232 | dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); |
diff --git a/readconf.h b/readconf.h index 49858bff3..11a7332c2 100644 --- a/readconf.h +++ b/readconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.h,v 1.104 2014/12/04 02:24:32 djm Exp $ */ | 1 | /* $OpenBSD: readconf.h,v 1.105 2014/12/21 22:27:56 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -146,6 +146,8 @@ typedef struct { | |||
146 | 146 | ||
147 | char *revoked_host_keys; | 147 | char *revoked_host_keys; |
148 | 148 | ||
149 | int fingerprint_hash; | ||
150 | |||
149 | char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ | 151 | char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ |
150 | } Options; | 152 | } Options; |
151 | 153 | ||
diff --git a/servconf.c b/servconf.c index 99396fb1d..abc3c72fb 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | /* $OpenBSD: servconf.c,v 1.255 2014/11/24 03:39:22 jsg Exp $ */ | 2 | /* $OpenBSD: servconf.c,v 1.256 2014/12/21 22:27:56 djm Exp $ */ |
3 | /* | 3 | /* |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
5 | * All rights reserved | 5 | * All rights reserved |
@@ -55,6 +55,7 @@ | |||
55 | #include "hostfile.h" | 55 | #include "hostfile.h" |
56 | #include "auth.h" | 56 | #include "auth.h" |
57 | #include "myproposal.h" | 57 | #include "myproposal.h" |
58 | #include "digest.h" | ||
58 | 59 | ||
59 | static void add_listen_addr(ServerOptions *, char *, int); | 60 | static void add_listen_addr(ServerOptions *, char *, int); |
60 | static void add_one_listen_addr(ServerOptions *, char *, int); | 61 | static void add_one_listen_addr(ServerOptions *, char *, int); |
@@ -158,6 +159,7 @@ initialize_server_options(ServerOptions *options) | |||
158 | options->ip_qos_interactive = -1; | 159 | options->ip_qos_interactive = -1; |
159 | options->ip_qos_bulk = -1; | 160 | options->ip_qos_bulk = -1; |
160 | options->version_addendum = NULL; | 161 | options->version_addendum = NULL; |
162 | options->fingerprint_hash = -1; | ||
161 | } | 163 | } |
162 | 164 | ||
163 | void | 165 | void |
@@ -313,6 +315,8 @@ fill_default_server_options(ServerOptions *options) | |||
313 | options->fwd_opts.streamlocal_bind_mask = 0177; | 315 | options->fwd_opts.streamlocal_bind_mask = 0177; |
314 | if (options->fwd_opts.streamlocal_bind_unlink == -1) | 316 | if (options->fwd_opts.streamlocal_bind_unlink == -1) |
315 | options->fwd_opts.streamlocal_bind_unlink = 0; | 317 | options->fwd_opts.streamlocal_bind_unlink = 0; |
318 | if (options->fingerprint_hash == -1) | ||
319 | options->fingerprint_hash = SSH_FP_HASH_DEFAULT; | ||
316 | /* Turn privilege separation on by default */ | 320 | /* Turn privilege separation on by default */ |
317 | if (use_privsep == -1) | 321 | if (use_privsep == -1) |
318 | use_privsep = PRIVSEP_NOSANDBOX; | 322 | use_privsep = PRIVSEP_NOSANDBOX; |
@@ -362,7 +366,7 @@ typedef enum { | |||
362 | sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, | 366 | sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, |
363 | sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, | 367 | sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, |
364 | sStreamLocalBindMask, sStreamLocalBindUnlink, | 368 | sStreamLocalBindMask, sStreamLocalBindUnlink, |
365 | sAllowStreamLocalForwarding, | 369 | sAllowStreamLocalForwarding, sFingerprintHash, |
366 | sDeprecated, sUnsupported | 370 | sDeprecated, sUnsupported |
367 | } ServerOpCodes; | 371 | } ServerOpCodes; |
368 | 372 | ||
@@ -493,6 +497,7 @@ static struct { | |||
493 | { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL }, | 497 | { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL }, |
494 | { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL }, | 498 | { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL }, |
495 | { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, | 499 | { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, |
500 | { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, | ||
496 | { NULL, sBadOption, 0 } | 501 | { NULL, sBadOption, 0 } |
497 | }; | 502 | }; |
498 | 503 | ||
@@ -1670,6 +1675,18 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1670 | intptr = &options->fwd_opts.streamlocal_bind_unlink; | 1675 | intptr = &options->fwd_opts.streamlocal_bind_unlink; |
1671 | goto parse_flag; | 1676 | goto parse_flag; |
1672 | 1677 | ||
1678 | case sFingerprintHash: | ||
1679 | arg = strdelim(&cp); | ||
1680 | if (!arg || *arg == '\0') | ||
1681 | fatal("%.200s line %d: Missing argument.", | ||
1682 | filename, linenum); | ||
1683 | if ((value = ssh_digest_alg_by_name(arg)) == -1) | ||
1684 | fatal("%.200s line %d: Invalid hash algorithm \"%s\".", | ||
1685 | filename, linenum, arg); | ||
1686 | if (*activep) | ||
1687 | options->fingerprint_hash = value; | ||
1688 | break; | ||
1689 | |||
1673 | case sDeprecated: | 1690 | case sDeprecated: |
1674 | logit("%s line %d: Deprecated option %s", | 1691 | logit("%s line %d: Deprecated option %s", |
1675 | filename, linenum, arg); | 1692 | filename, linenum, arg); |
@@ -1912,6 +1929,8 @@ fmt_intarg(ServerOpCodes code, int val) | |||
1912 | return fmt_multistate_int(val, multistate_tcpfwd); | 1929 | return fmt_multistate_int(val, multistate_tcpfwd); |
1913 | case sAllowStreamLocalForwarding: | 1930 | case sAllowStreamLocalForwarding: |
1914 | return fmt_multistate_int(val, multistate_tcpfwd); | 1931 | return fmt_multistate_int(val, multistate_tcpfwd); |
1932 | case sFingerprintHash: | ||
1933 | return ssh_digest_alg_name(val); | ||
1915 | case sProtocol: | 1934 | case sProtocol: |
1916 | switch (val) { | 1935 | switch (val) { |
1917 | case SSH_PROTO_1: | 1936 | case SSH_PROTO_1: |
@@ -2073,6 +2092,7 @@ dump_config(ServerOptions *o) | |||
2073 | dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); | 2092 | dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); |
2074 | dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); | 2093 | dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); |
2075 | dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); | 2094 | dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); |
2095 | dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); | ||
2076 | 2096 | ||
2077 | /* string arguments */ | 2097 | /* string arguments */ |
2078 | dump_cfg_string(sPidFile, o->pid_file); | 2098 | dump_cfg_string(sPidFile, o->pid_file); |
diff --git a/servconf.h b/servconf.h index 766db3a3d..49b228bdf 100644 --- a/servconf.h +++ b/servconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: servconf.h,v 1.114 2014/07/15 15:54:14 millert Exp $ */ | 1 | /* $OpenBSD: servconf.h,v 1.115 2014/12/21 22:27:56 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -185,6 +185,8 @@ typedef struct { | |||
185 | 185 | ||
186 | u_int num_auth_methods; | 186 | u_int num_auth_methods; |
187 | char *auth_methods[MAX_AUTH_METHODS]; | 187 | char *auth_methods[MAX_AUTH_METHODS]; |
188 | |||
189 | int fingerprint_hash; | ||
188 | } ServerOptions; | 190 | } ServerOptions; |
189 | 191 | ||
190 | /* Information about the incoming connection as used by Match */ | 192 | /* Information about the incoming connection as used by Match */ |
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: ssh-add.1,v 1.60 2014/08/30 15:33:50 sobrado Exp $ | 1 | .\" $OpenBSD: ssh-add.1,v 1.61 2014/12/21 22:27:56 djm Exp $ |
2 | .\" | 2 | .\" |
3 | .\" Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | .\" Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -35,7 +35,7 @@ | |||
35 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 35 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
36 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 36 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
37 | .\" | 37 | .\" |
38 | .Dd $Mdocdate: August 30 2014 $ | 38 | .Dd $Mdocdate: December 21 2014 $ |
39 | .Dt SSH-ADD 1 | 39 | .Dt SSH-ADD 1 |
40 | .Os | 40 | .Os |
41 | .Sh NAME | 41 | .Sh NAME |
@@ -44,6 +44,7 @@ | |||
44 | .Sh SYNOPSIS | 44 | .Sh SYNOPSIS |
45 | .Nm ssh-add | 45 | .Nm ssh-add |
46 | .Op Fl cDdkLlXx | 46 | .Op Fl cDdkLlXx |
47 | .Op Fl E Ar fingerprint_hash | ||
47 | .Op Fl t Ar life | 48 | .Op Fl t Ar life |
48 | .Op Ar | 49 | .Op Ar |
49 | .Nm ssh-add | 50 | .Nm ssh-add |
@@ -108,6 +109,14 @@ If no public key is found at a given path, | |||
108 | will append | 109 | will append |
109 | .Pa .pub | 110 | .Pa .pub |
110 | and retry. | 111 | and retry. |
112 | .It Fl E Ar fingerprint_hash | ||
113 | Specifies the hash algorithm used when displaying key fingerprints. | ||
114 | Valid options are: | ||
115 | .Dq md5 | ||
116 | and | ||
117 | .Dq sha256 . | ||
118 | The default is | ||
119 | .Dq sha256 . | ||
111 | .It Fl e Ar pkcs11 | 120 | .It Fl e Ar pkcs11 |
112 | Remove keys provided by the PKCS#11 shared library | 121 | Remove keys provided by the PKCS#11 shared library |
113 | .Ar pkcs11 . | 122 | .Ar pkcs11 . |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-add.c,v 1.114 2014/11/26 18:34:51 millert Exp $ */ | 1 | /* $OpenBSD: ssh-add.c,v 1.115 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -63,6 +63,7 @@ | |||
63 | #include "pathnames.h" | 63 | #include "pathnames.h" |
64 | #include "misc.h" | 64 | #include "misc.h" |
65 | #include "ssherr.h" | 65 | #include "ssherr.h" |
66 | #include "digest.h" | ||
66 | 67 | ||
67 | /* argv0 */ | 68 | /* argv0 */ |
68 | extern char *__progname; | 69 | extern char *__progname; |
@@ -79,6 +80,8 @@ static char *default_files[] = { | |||
79 | NULL | 80 | NULL |
80 | }; | 81 | }; |
81 | 82 | ||
83 | static int fingerprint_hash = SSH_FP_HASH_DEFAULT; | ||
84 | |||
82 | /* Default lifetime (0 == forever) */ | 85 | /* Default lifetime (0 == forever) */ |
83 | static int lifetime = 0; | 86 | static int lifetime = 0; |
84 | 87 | ||
@@ -340,8 +343,8 @@ list_identities(AuthenticationConnection *ac, int do_fp) | |||
340 | key = ssh_get_next_identity(ac, &comment, version)) { | 343 | key = ssh_get_next_identity(ac, &comment, version)) { |
341 | had_identities = 1; | 344 | had_identities = 1; |
342 | if (do_fp) { | 345 | if (do_fp) { |
343 | fp = key_fingerprint(key, SSH_FP_MD5, | 346 | fp = key_fingerprint(key, fingerprint_hash, |
344 | SSH_FP_HEX); | 347 | SSH_FP_DEFAULT); |
345 | printf("%d %s %s (%s)\n", | 348 | printf("%d %s %s (%s)\n", |
346 | key_size(key), fp, comment, key_type(key)); | 349 | key_size(key), fp, comment, key_type(key)); |
347 | free(fp); | 350 | free(fp); |
@@ -408,6 +411,7 @@ usage(void) | |||
408 | fprintf(stderr, "usage: %s [options] [file ...]\n", __progname); | 411 | fprintf(stderr, "usage: %s [options] [file ...]\n", __progname); |
409 | fprintf(stderr, "Options:\n"); | 412 | fprintf(stderr, "Options:\n"); |
410 | fprintf(stderr, " -l List fingerprints of all identities.\n"); | 413 | fprintf(stderr, " -l List fingerprints of all identities.\n"); |
414 | fprintf(stderr, " -E hash Specify hash algorithm used for fingerprints.\n"); | ||
411 | fprintf(stderr, " -L List public key parameters of all identities.\n"); | 415 | fprintf(stderr, " -L List public key parameters of all identities.\n"); |
412 | fprintf(stderr, " -k Load only keys and not certificates.\n"); | 416 | fprintf(stderr, " -k Load only keys and not certificates.\n"); |
413 | fprintf(stderr, " -c Require confirmation to sign using identities\n"); | 417 | fprintf(stderr, " -c Require confirmation to sign using identities\n"); |
@@ -428,6 +432,7 @@ main(int argc, char **argv) | |||
428 | AuthenticationConnection *ac = NULL; | 432 | AuthenticationConnection *ac = NULL; |
429 | char *pkcs11provider = NULL; | 433 | char *pkcs11provider = NULL; |
430 | int i, ch, deleting = 0, ret = 0, key_only = 0; | 434 | int i, ch, deleting = 0, ret = 0, key_only = 0; |
435 | int xflag = 0, lflag = 0, Dflag = 0; | ||
431 | 436 | ||
432 | /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ | 437 | /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
433 | sanitise_stdfd(); | 438 | sanitise_stdfd(); |
@@ -446,21 +451,28 @@ main(int argc, char **argv) | |||
446 | "Could not open a connection to your authentication agent.\n"); | 451 | "Could not open a connection to your authentication agent.\n"); |
447 | exit(2); | 452 | exit(2); |
448 | } | 453 | } |
449 | while ((ch = getopt(argc, argv, "klLcdDxXe:s:t:")) != -1) { | 454 | while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:t:")) != -1) { |
450 | switch (ch) { | 455 | switch (ch) { |
456 | case 'E': | ||
457 | fingerprint_hash = ssh_digest_alg_by_name(optarg); | ||
458 | if (fingerprint_hash == -1) | ||
459 | fatal("Invalid hash algorithm \"%s\"", optarg); | ||
460 | break; | ||
451 | case 'k': | 461 | case 'k': |
452 | key_only = 1; | 462 | key_only = 1; |
453 | break; | 463 | break; |
454 | case 'l': | 464 | case 'l': |
455 | case 'L': | 465 | case 'L': |
456 | if (list_identities(ac, ch == 'l' ? 1 : 0) == -1) | 466 | if (lflag != 0) |
457 | ret = 1; | 467 | fatal("-%c flag already specified", lflag); |
458 | goto done; | 468 | lflag = ch; |
469 | break; | ||
459 | case 'x': | 470 | case 'x': |
460 | case 'X': | 471 | case 'X': |
461 | if (lock_agent(ac, ch == 'x' ? 1 : 0) == -1) | 472 | if (xflag != 0) |
462 | ret = 1; | 473 | fatal("-%c flag already specified", xflag); |
463 | goto done; | 474 | xflag = ch; |
475 | break; | ||
464 | case 'c': | 476 | case 'c': |
465 | confirm = 1; | 477 | confirm = 1; |
466 | break; | 478 | break; |
@@ -468,9 +480,8 @@ main(int argc, char **argv) | |||
468 | deleting = 1; | 480 | deleting = 1; |
469 | break; | 481 | break; |
470 | case 'D': | 482 | case 'D': |
471 | if (delete_all(ac) == -1) | 483 | Dflag = 1; |
472 | ret = 1; | 484 | break; |
473 | goto done; | ||
474 | case 's': | 485 | case 's': |
475 | pkcs11provider = optarg; | 486 | pkcs11provider = optarg; |
476 | break; | 487 | break; |
@@ -491,6 +502,23 @@ main(int argc, char **argv) | |||
491 | goto done; | 502 | goto done; |
492 | } | 503 | } |
493 | } | 504 | } |
505 | |||
506 | if ((xflag != 0) + (lflag != 0) + (Dflag != 0) > 1) | ||
507 | fatal("Invalid combination of actions"); | ||
508 | else if (xflag) { | ||
509 | if (lock_agent(ac, xflag == 'x' ? 1 : 0) == -1) | ||
510 | ret = 1; | ||
511 | goto done; | ||
512 | } else if (lflag) { | ||
513 | if (list_identities(ac, lflag == 'l' ? 1 : 0) == -1) | ||
514 | ret = 1; | ||
515 | goto done; | ||
516 | } else if (Dflag) { | ||
517 | if (delete_all(ac) == -1) | ||
518 | ret = 1; | ||
519 | goto done; | ||
520 | } | ||
521 | |||
494 | argc -= optind; | 522 | argc -= optind; |
495 | argv += optind; | 523 | argv += optind; |
496 | if (pkcs11provider != NULL) { | 524 | if (pkcs11provider != NULL) { |
diff --git a/ssh-agent.1 b/ssh-agent.1 index b55065327..6759afec3 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: ssh-agent.1,v 1.56 2014/08/30 15:33:50 sobrado Exp $ | 1 | .\" $OpenBSD: ssh-agent.1,v 1.57 2014/12/21 22:27:56 djm Exp $ |
2 | .\" | 2 | .\" |
3 | .\" Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | .\" Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -34,7 +34,7 @@ | |||
34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
36 | .\" | 36 | .\" |
37 | .Dd $Mdocdate: August 30 2014 $ | 37 | .Dd $Mdocdate: December 21 2014 $ |
38 | .Dt SSH-AGENT 1 | 38 | .Dt SSH-AGENT 1 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -45,6 +45,7 @@ | |||
45 | .Op Fl c | s | 45 | .Op Fl c | s |
46 | .Op Fl d | 46 | .Op Fl d |
47 | .Op Fl a Ar bind_address | 47 | .Op Fl a Ar bind_address |
48 | .Op Fl E Ar fingerprint_hash | ||
48 | .Op Fl t Ar life | 49 | .Op Fl t Ar life |
49 | .Op Ar command Op Ar arg ... | 50 | .Op Ar command Op Ar arg ... |
50 | .Nm ssh-agent | 51 | .Nm ssh-agent |
@@ -96,6 +97,14 @@ Debug mode. | |||
96 | When this option is specified | 97 | When this option is specified |
97 | .Nm | 98 | .Nm |
98 | will not fork. | 99 | will not fork. |
100 | .It Fl E Ar fingerprint_hash | ||
101 | Specifies the hash algorithm used when displaying key fingerprints. | ||
102 | Valid options are: | ||
103 | .Dq md5 | ||
104 | and | ||
105 | .Dq sha256 . | ||
106 | The default is | ||
107 | .Dq sha256 . | ||
99 | .It Fl k | 108 | .It Fl k |
100 | Kill the current agent (given by the | 109 | Kill the current agent (given by the |
101 | .Ev SSH_AGENT_PID | 110 | .Ev SSH_AGENT_PID |
diff --git a/ssh-agent.c b/ssh-agent.c index 9c11d48d1..c2dc1fa0c 100644 --- a/ssh-agent.c +++ b/ssh-agent.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-agent.c,v 1.191 2014/11/18 20:54:28 krw Exp $ */ | 1 | /* $OpenBSD: ssh-agent.c,v 1.192 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -142,6 +142,8 @@ extern char *__progname; | |||
142 | /* Default lifetime in seconds (0 == forever) */ | 142 | /* Default lifetime in seconds (0 == forever) */ |
143 | static long lifetime = 0; | 143 | static long lifetime = 0; |
144 | 144 | ||
145 | static int fingerprint_hash = SSH_FP_HASH_DEFAULT; | ||
146 | |||
145 | static void | 147 | static void |
146 | close_socket(SocketEntry *e) | 148 | close_socket(SocketEntry *e) |
147 | { | 149 | { |
@@ -203,7 +205,7 @@ confirm_key(Identity *id) | |||
203 | char *p; | 205 | char *p; |
204 | int ret = -1; | 206 | int ret = -1; |
205 | 207 | ||
206 | p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); | 208 | p = key_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT); |
207 | if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", | 209 | if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", |
208 | id->comment, p)) | 210 | id->comment, p)) |
209 | ret = 0; | 211 | ret = 0; |
@@ -1026,7 +1028,7 @@ usage(void) | |||
1026 | { | 1028 | { |
1027 | fprintf(stderr, | 1029 | fprintf(stderr, |
1028 | "usage: ssh-agent [-c | -s] [-d] [-a bind_address] [-t life]\n" | 1030 | "usage: ssh-agent [-c | -s] [-d] [-a bind_address] [-t life]\n" |
1029 | " [command [arg ...]]\n" | 1031 | " [-E fingerprint_hash] [command [arg ...]]\n" |
1030 | " ssh-agent [-c | -s] -k\n"); | 1032 | " ssh-agent [-c | -s] -k\n"); |
1031 | exit(1); | 1033 | exit(1); |
1032 | } | 1034 | } |
@@ -1069,8 +1071,13 @@ main(int ac, char **av) | |||
1069 | __progname = ssh_get_progname(av[0]); | 1071 | __progname = ssh_get_progname(av[0]); |
1070 | seed_rng(); | 1072 | seed_rng(); |
1071 | 1073 | ||
1072 | while ((ch = getopt(ac, av, "cdksa:t:")) != -1) { | 1074 | while ((ch = getopt(ac, av, "cdksE:a:t:")) != -1) { |
1073 | switch (ch) { | 1075 | switch (ch) { |
1076 | case 'E': | ||
1077 | fingerprint_hash = ssh_digest_alg_by_name(optarg); | ||
1078 | if (fingerprint_hash == -1) | ||
1079 | fatal("Invalid hash algorithm \"%s\"", optarg); | ||
1080 | break; | ||
1074 | case 'c': | 1081 | case 'c': |
1075 | if (s_flag) | 1082 | if (s_flag) |
1076 | usage(); | 1083 | usage(); |
diff --git a/ssh-keygen.1 b/ssh-keygen.1 index bf5f87bd3..b73c4606e 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: ssh-keygen.1,v 1.123 2014/08/30 15:33:50 sobrado Exp $ | 1 | .\" $OpenBSD: ssh-keygen.1,v 1.124 2014/12/21 22:27:56 djm Exp $ |
2 | .\" | 2 | .\" |
3 | .\" Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | .\" Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -35,7 +35,7 @@ | |||
35 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 35 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
36 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 36 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
37 | .\" | 37 | .\" |
38 | .Dd $Mdocdate: August 30 2014 $ | 38 | .Dd $Mdocdate: December 21 2014 $ |
39 | .Dt SSH-KEYGEN 1 | 39 | .Dt SSH-KEYGEN 1 |
40 | .Os | 40 | .Os |
41 | .Sh NAME | 41 | .Sh NAME |
@@ -73,6 +73,7 @@ | |||
73 | .Op Fl f Ar keyfile | 73 | .Op Fl f Ar keyfile |
74 | .Nm ssh-keygen | 74 | .Nm ssh-keygen |
75 | .Fl l | 75 | .Fl l |
76 | .Op Fl E Ar fingerprint_hash | ||
76 | .Op Fl f Ar input_keyfile | 77 | .Op Fl f Ar input_keyfile |
77 | .Nm ssh-keygen | 78 | .Nm ssh-keygen |
78 | .Fl B | 79 | .Fl B |
@@ -269,6 +270,14 @@ When used in combination with | |||
269 | this option indicates that a CA key resides in a PKCS#11 token (see the | 270 | this option indicates that a CA key resides in a PKCS#11 token (see the |
270 | .Sx CERTIFICATES | 271 | .Sx CERTIFICATES |
271 | section for details). | 272 | section for details). |
273 | .It Fl E Ar fingerprint_hash | ||
274 | Specifies the hash algorithm used when displaying key fingerprints. | ||
275 | Valid options are: | ||
276 | .Dq md5 | ||
277 | and | ||
278 | .Dq sha256 . | ||
279 | The default is | ||
280 | .Dq sha256 . | ||
272 | .It Fl e | 281 | .It Fl e |
273 | This option will read a private or public OpenSSH key file and | 282 | This option will read a private or public OpenSSH key file and |
274 | print to stdout the key in one of the formats specified by the | 283 | print to stdout the key in one of the formats specified by the |
diff --git a/ssh-keygen.c b/ssh-keygen.c index e149eda3e..8daea7f76 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keygen.c,v 1.250 2014/08/21 01:08:52 doug Exp $ */ | 1 | /* $OpenBSD: ssh-keygen.c,v 1.251 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -53,6 +53,7 @@ | |||
53 | #include "ssh-pkcs11.h" | 53 | #include "ssh-pkcs11.h" |
54 | #include "atomicio.h" | 54 | #include "atomicio.h" |
55 | #include "krl.h" | 55 | #include "krl.h" |
56 | #include "digest.h" | ||
56 | 57 | ||
57 | /* Number of bits in the RSA/DSA key. This value can be set on the command line. */ | 58 | /* Number of bits in the RSA/DSA key. This value can be set on the command line. */ |
58 | #define DEFAULT_BITS 2048 | 59 | #define DEFAULT_BITS 2048 |
@@ -90,6 +91,9 @@ int show_cert = 0; | |||
90 | int print_fingerprint = 0; | 91 | int print_fingerprint = 0; |
91 | int print_bubblebabble = 0; | 92 | int print_bubblebabble = 0; |
92 | 93 | ||
94 | /* Hash algorithm to use for fingerprints. */ | ||
95 | int fingerprint_hash = SSH_FP_HASH_DEFAULT; | ||
96 | |||
93 | /* The identity file name, given on the command line or entered by the user. */ | 97 | /* The identity file name, given on the command line or entered by the user. */ |
94 | char identity_file[1024]; | 98 | char identity_file[1024]; |
95 | int have_identity = 0; | 99 | int have_identity = 0; |
@@ -749,11 +753,11 @@ do_download(struct passwd *pw) | |||
749 | Key **keys = NULL; | 753 | Key **keys = NULL; |
750 | int i, nkeys; | 754 | int i, nkeys; |
751 | enum fp_rep rep; | 755 | enum fp_rep rep; |
752 | enum fp_type fptype; | 756 | int fptype; |
753 | char *fp, *ra; | 757 | char *fp, *ra; |
754 | 758 | ||
755 | fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; | 759 | fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; |
756 | rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; | 760 | rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; |
757 | 761 | ||
758 | pkcs11_init(0); | 762 | pkcs11_init(0); |
759 | nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); | 763 | nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); |
@@ -762,7 +766,7 @@ do_download(struct passwd *pw) | |||
762 | for (i = 0; i < nkeys; i++) { | 766 | for (i = 0; i < nkeys; i++) { |
763 | if (print_fingerprint) { | 767 | if (print_fingerprint) { |
764 | fp = key_fingerprint(keys[i], fptype, rep); | 768 | fp = key_fingerprint(keys[i], fptype, rep); |
765 | ra = key_fingerprint(keys[i], SSH_FP_MD5, | 769 | ra = key_fingerprint(keys[i], fingerprint_hash, |
766 | SSH_FP_RANDOMART); | 770 | SSH_FP_RANDOMART); |
767 | printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), | 771 | printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), |
768 | fp, key_type(keys[i])); | 772 | fp, key_type(keys[i])); |
@@ -792,12 +796,11 @@ do_fingerprint(struct passwd *pw) | |||
792 | char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; | 796 | char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; |
793 | int i, skip = 0, num = 0, invalid = 1; | 797 | int i, skip = 0, num = 0, invalid = 1; |
794 | enum fp_rep rep; | 798 | enum fp_rep rep; |
795 | enum fp_type fptype; | 799 | int fptype; |
796 | struct stat st; | 800 | struct stat st; |
797 | 801 | ||
798 | fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; | 802 | fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; |
799 | rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; | 803 | rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; |
800 | |||
801 | if (!have_identity) | 804 | if (!have_identity) |
802 | ask_filename(pw, "Enter file in which the key is"); | 805 | ask_filename(pw, "Enter file in which the key is"); |
803 | if (stat(identity_file, &st) < 0) { | 806 | if (stat(identity_file, &st) < 0) { |
@@ -807,7 +810,8 @@ do_fingerprint(struct passwd *pw) | |||
807 | public = key_load_public(identity_file, &comment); | 810 | public = key_load_public(identity_file, &comment); |
808 | if (public != NULL) { | 811 | if (public != NULL) { |
809 | fp = key_fingerprint(public, fptype, rep); | 812 | fp = key_fingerprint(public, fptype, rep); |
810 | ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); | 813 | ra = key_fingerprint(public, fingerprint_hash, |
814 | SSH_FP_RANDOMART); | ||
811 | printf("%u %s %s (%s)\n", key_size(public), fp, comment, | 815 | printf("%u %s %s (%s)\n", key_size(public), fp, comment, |
812 | key_type(public)); | 816 | key_type(public)); |
813 | if (log_level >= SYSLOG_LEVEL_VERBOSE) | 817 | if (log_level >= SYSLOG_LEVEL_VERBOSE) |
@@ -873,7 +877,8 @@ do_fingerprint(struct passwd *pw) | |||
873 | } | 877 | } |
874 | comment = *cp ? cp : comment; | 878 | comment = *cp ? cp : comment; |
875 | fp = key_fingerprint(public, fptype, rep); | 879 | fp = key_fingerprint(public, fptype, rep); |
876 | ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); | 880 | ra = key_fingerprint(public, fingerprint_hash, |
881 | SSH_FP_RANDOMART); | ||
877 | printf("%u %s %s (%s)\n", key_size(public), fp, | 882 | printf("%u %s %s (%s)\n", key_size(public), fp, |
878 | comment ? comment : "no comment", key_type(public)); | 883 | comment ? comment : "no comment", key_type(public)); |
879 | if (log_level >= SYSLOG_LEVEL_VERBOSE) | 884 | if (log_level >= SYSLOG_LEVEL_VERBOSE) |
@@ -993,13 +998,15 @@ printhost(FILE *f, const char *name, Key *public, int ca, int revoked, int hash) | |||
993 | { | 998 | { |
994 | if (print_fingerprint) { | 999 | if (print_fingerprint) { |
995 | enum fp_rep rep; | 1000 | enum fp_rep rep; |
996 | enum fp_type fptype; | 1001 | int fptype; |
997 | char *fp, *ra; | 1002 | char *fp, *ra; |
998 | 1003 | ||
999 | fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; | 1004 | fptype = print_bubblebabble ? |
1000 | rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; | 1005 | SSH_DIGEST_SHA1 : fingerprint_hash; |
1006 | rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; | ||
1001 | fp = key_fingerprint(public, fptype, rep); | 1007 | fp = key_fingerprint(public, fptype, rep); |
1002 | ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); | 1008 | ra = key_fingerprint(public, fingerprint_hash, |
1009 | SSH_FP_RANDOMART); | ||
1003 | printf("%u %s %s (%s)\n", key_size(public), fp, name, | 1010 | printf("%u %s %s (%s)\n", key_size(public), fp, name, |
1004 | key_type(public)); | 1011 | key_type(public)); |
1005 | if (log_level >= SYSLOG_LEVEL_VERBOSE) | 1012 | if (log_level >= SYSLOG_LEVEL_VERBOSE) |
@@ -1908,9 +1915,9 @@ do_show_cert(struct passwd *pw) | |||
1908 | fatal("%s is not a certificate", identity_file); | 1915 | fatal("%s is not a certificate", identity_file); |
1909 | v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00; | 1916 | v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00; |
1910 | 1917 | ||
1911 | key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | 1918 | key_fp = key_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT); |
1912 | ca_fp = key_fingerprint(key->cert->signature_key, | 1919 | ca_fp = key_fingerprint(key->cert->signature_key, |
1913 | SSH_FP_MD5, SSH_FP_HEX); | 1920 | fingerprint_hash, SSH_FP_DEFAULT); |
1914 | 1921 | ||
1915 | printf("%s:\n", identity_file); | 1922 | printf("%s:\n", identity_file); |
1916 | printf(" Type: %s %s certificate\n", key_ssh_name(key), | 1923 | printf(" Type: %s %s certificate\n", key_ssh_name(key), |
@@ -2189,7 +2196,7 @@ usage(void) | |||
2189 | " ssh-keygen -e [-m key_format] [-f input_keyfile]\n" | 2196 | " ssh-keygen -e [-m key_format] [-f input_keyfile]\n" |
2190 | " ssh-keygen -y [-f input_keyfile]\n" | 2197 | " ssh-keygen -y [-f input_keyfile]\n" |
2191 | " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n" | 2198 | " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n" |
2192 | " ssh-keygen -l [-f input_keyfile]\n" | 2199 | " ssh-keygen -l [-E fingerprint_hash] [-f input_keyfile]\n" |
2193 | " ssh-keygen -B [-f input_keyfile]\n"); | 2200 | " ssh-keygen -B [-f input_keyfile]\n"); |
2194 | #ifdef ENABLE_PKCS11 | 2201 | #ifdef ENABLE_PKCS11 |
2195 | fprintf(stderr, | 2202 | fprintf(stderr, |
@@ -2258,9 +2265,10 @@ main(int argc, char **argv) | |||
2258 | exit(1); | 2265 | exit(1); |
2259 | } | 2266 | } |
2260 | 2267 | ||
2261 | /* Remaining characters: EUYdw */ | 2268 | /* Remaining characters: UYdw */ |
2262 | while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy" | 2269 | while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy" |
2263 | "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:a:b:f:g:j:m:n:r:s:t:z:")) != -1) { | 2270 | "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:" |
2271 | "a:b:f:g:j:m:n:r:s:t:z:")) != -1) { | ||
2264 | switch (opt) { | 2272 | switch (opt) { |
2265 | case 'A': | 2273 | case 'A': |
2266 | gen_all_hostkeys = 1; | 2274 | gen_all_hostkeys = 1; |
@@ -2271,6 +2279,11 @@ main(int argc, char **argv) | |||
2271 | fatal("Bits has bad value %s (%s)", | 2279 | fatal("Bits has bad value %s (%s)", |
2272 | optarg, errstr); | 2280 | optarg, errstr); |
2273 | break; | 2281 | break; |
2282 | case 'E': | ||
2283 | fingerprint_hash = ssh_digest_alg_by_name(optarg); | ||
2284 | if (fingerprint_hash == -1) | ||
2285 | fatal("Invalid hash algorithm \"%s\"", optarg); | ||
2286 | break; | ||
2274 | case 'F': | 2287 | case 'F': |
2275 | find_host = 1; | 2288 | find_host = 1; |
2276 | rr_hostname = optarg; | 2289 | rr_hostname = optarg; |
@@ -2702,8 +2715,9 @@ passphrase_again: | |||
2702 | fclose(f); | 2715 | fclose(f); |
2703 | 2716 | ||
2704 | if (!quiet) { | 2717 | if (!quiet) { |
2705 | char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); | 2718 | char *fp = key_fingerprint(public, fingerprint_hash, |
2706 | char *ra = key_fingerprint(public, SSH_FP_MD5, | 2719 | SSH_FP_DEFAULT); |
2720 | char *ra = key_fingerprint(public, fingerprint_hash, | ||
2707 | SSH_FP_RANDOMART); | 2721 | SSH_FP_RANDOMART); |
2708 | printf("Your public key has been saved in %s.\n", | 2722 | printf("Your public key has been saved in %s.\n", |
2709 | identity_file); | 2723 | identity_file); |
diff --git a/ssh-keysign.c b/ssh-keysign.c index 6b73319e0..b86e18d8c 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keysign.c,v 1.43 2014/10/08 22:20:25 djm Exp $ */ | 1 | /* $OpenBSD: ssh-keysign.c,v 1.44 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2002 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2002 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -246,7 +246,8 @@ main(int argc, char **argv) | |||
246 | } | 246 | } |
247 | } | 247 | } |
248 | if (!found) { | 248 | if (!found) { |
249 | fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | 249 | fp = key_fingerprint(key, options.fingerprint_hash, |
250 | SSH_FP_DEFAULT); | ||
250 | fatal("no matching hostkey found for key %s %s", | 251 | fatal("no matching hostkey found for key %s %s", |
251 | key_type(key), fp); | 252 | key_type(key), fp); |
252 | } | 253 | } |
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: ssh.1,v 1.351 2014/10/09 06:21:31 jmc Exp $ | 36 | .\" $OpenBSD: ssh.1,v 1.352 2014/12/21 22:27:56 djm Exp $ |
37 | .Dd $Mdocdate: October 9 2014 $ | 37 | .Dd $Mdocdate: December 21 2014 $ |
38 | .Dt SSH 1 | 38 | .Dt SSH 1 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -1091,7 +1091,7 @@ Fingerprints can be determined using | |||
1091 | If the fingerprint is already known, it can be matched | 1091 | If the fingerprint is already known, it can be matched |
1092 | and the key can be accepted or rejected. | 1092 | and the key can be accepted or rejected. |
1093 | Because of the difficulty of comparing host keys | 1093 | Because of the difficulty of comparing host keys |
1094 | just by looking at hex strings, | 1094 | just by looking at fingerprint strings, |
1095 | there is also support to compare host keys visually, | 1095 | there is also support to compare host keys visually, |
1096 | using | 1096 | using |
1097 | .Em random art . | 1097 | .Em random art . |
diff --git a/sshconnect.c b/sshconnect.c index 4b9681a5b..176a20a87 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.c,v 1.253 2014/12/11 08:20:09 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect.c,v 1.254 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -918,9 +918,10 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
918 | "key for IP address '%.128s' to the list " | 918 | "key for IP address '%.128s' to the list " |
919 | "of known hosts.", type, ip); | 919 | "of known hosts.", type, ip); |
920 | } else if (options.visual_host_key) { | 920 | } else if (options.visual_host_key) { |
921 | fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); | 921 | fp = key_fingerprint(host_key, |
922 | ra = key_fingerprint(host_key, SSH_FP_MD5, | 922 | options.fingerprint_hash, SSH_FP_DEFAULT); |
923 | SSH_FP_RANDOMART); | 923 | ra = key_fingerprint(host_key, |
924 | options.fingerprint_hash, SSH_FP_RANDOMART); | ||
924 | logit("Host key fingerprint is %s\n%s\n", fp, ra); | 925 | logit("Host key fingerprint is %s\n%s\n", fp, ra); |
925 | free(ra); | 926 | free(ra); |
926 | free(fp); | 927 | free(fp); |
@@ -959,9 +960,10 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
959 | else | 960 | else |
960 | snprintf(msg1, sizeof(msg1), "."); | 961 | snprintf(msg1, sizeof(msg1), "."); |
961 | /* The default */ | 962 | /* The default */ |
962 | fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); | 963 | fp = key_fingerprint(host_key, |
963 | ra = key_fingerprint(host_key, SSH_FP_MD5, | 964 | options.fingerprint_hash, SSH_FP_DEFAULT); |
964 | SSH_FP_RANDOMART); | 965 | ra = key_fingerprint(host_key, |
966 | options.fingerprint_hash, SSH_FP_RANDOMART); | ||
965 | msg2[0] = '\0'; | 967 | msg2[0] = '\0'; |
966 | if (options.verify_host_key_dns) { | 968 | if (options.verify_host_key_dns) { |
967 | if (matching_host_key_dns) | 969 | if (matching_host_key_dns) |
@@ -1226,7 +1228,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) | |||
1226 | struct sshkey *plain = NULL; | 1228 | struct sshkey *plain = NULL; |
1227 | 1229 | ||
1228 | if ((fp = sshkey_fingerprint(host_key, | 1230 | if ((fp = sshkey_fingerprint(host_key, |
1229 | SSH_FP_MD5, SSH_FP_HEX)) == NULL) { | 1231 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { |
1230 | error("%s: fingerprint host key: %s", __func__, ssh_err(r)); | 1232 | error("%s: fingerprint host key: %s", __func__, ssh_err(r)); |
1231 | r = -1; | 1233 | r = -1; |
1232 | goto out; | 1234 | goto out; |
@@ -1387,8 +1389,10 @@ show_other_keys(struct hostkeys *hostkeys, Key *key) | |||
1387 | continue; | 1389 | continue; |
1388 | if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) | 1390 | if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) |
1389 | continue; | 1391 | continue; |
1390 | fp = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_HEX); | 1392 | fp = key_fingerprint(found->key, |
1391 | ra = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_RANDOMART); | 1393 | options.fingerprint_hash, SSH_FP_DEFAULT); |
1394 | ra = key_fingerprint(found->key, | ||
1395 | options.fingerprint_hash, SSH_FP_RANDOMART); | ||
1392 | logit("WARNING: %s key found for host %s\n" | 1396 | logit("WARNING: %s key found for host %s\n" |
1393 | "in %s:%lu\n" | 1397 | "in %s:%lu\n" |
1394 | "%s key fingerprint %s.", | 1398 | "%s key fingerprint %s.", |
@@ -1409,7 +1413,8 @@ warn_changed_key(Key *host_key) | |||
1409 | { | 1413 | { |
1410 | char *fp; | 1414 | char *fp; |
1411 | 1415 | ||
1412 | fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); | 1416 | fp = key_fingerprint(host_key, options.fingerprint_hash, |
1417 | SSH_FP_DEFAULT); | ||
1413 | 1418 | ||
1414 | error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); | 1419 | error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); |
1415 | error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); | 1420 | error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); |
diff --git a/sshconnect2.c b/sshconnect2.c index 6884d6be1..ad20fae6a 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.211 2014/12/11 05:13:28 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.212 2014/12/21 22:27:56 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2008 Damien Miller. All rights reserved. |
@@ -582,7 +582,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) | |||
582 | key->type, pktype); | 582 | key->type, pktype); |
583 | goto done; | 583 | goto done; |
584 | } | 584 | } |
585 | fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | 585 | fp = key_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT); |
586 | debug2("input_userauth_pk_ok: fp %s", fp); | 586 | debug2("input_userauth_pk_ok: fp %s", fp); |
587 | free(fp); | 587 | free(fp); |
588 | 588 | ||
@@ -991,7 +991,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) | |||
991 | int have_sig = 1; | 991 | int have_sig = 1; |
992 | char *fp; | 992 | char *fp; |
993 | 993 | ||
994 | fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); | 994 | fp = key_fingerprint(id->key, options.fingerprint_hash, SSH_FP_DEFAULT); |
995 | debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); | 995 | debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); |
996 | free(fp); | 996 | free(fp); |
997 | 997 | ||
diff --git a/sshd_config.5 b/sshd_config.5 index ef36d3338..69d3be2b8 100644 --- a/sshd_config.5 +++ b/sshd_config.5 | |||
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: sshd_config.5,v 1.182 2014/12/12 00:02:17 djm Exp $ | 36 | .\" $OpenBSD: sshd_config.5,v 1.183 2014/12/21 22:27:55 djm Exp $ |
37 | .Dd $Mdocdate: December 12 2014 $ | 37 | .Dd $Mdocdate: December 21 2014 $ |
38 | .Dt SSHD_CONFIG 5 | 38 | .Dt SSHD_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -485,6 +485,15 @@ and finally | |||
485 | See PATTERNS in | 485 | See PATTERNS in |
486 | .Xr ssh_config 5 | 486 | .Xr ssh_config 5 |
487 | for more information on patterns. | 487 | for more information on patterns. |
488 | .It Cm FingerprintHash | ||
489 | Specifies the hash algorithm used when logging key fingerprints. | ||
490 | Valid options are: | ||
491 | .Dq md5 | ||
492 | and | ||
493 | .Dq sha256 . | ||
494 | The default is | ||
495 | .Dq sha256 . | ||
496 | .Pp | ||
488 | .It Cm ForceCommand | 497 | .It Cm ForceCommand |
489 | Forces the execution of the command specified by | 498 | Forces the execution of the command specified by |
490 | .Cm ForceCommand , | 499 | .Cm ForceCommand , |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshkey.c,v 1.6 2014/12/10 01:24:09 djm Exp $ */ | 1 | /* $OpenBSD: sshkey.c,v 1.7 2014/12/21 22:27:55 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Alexander von Gernler. All rights reserved. | 4 | * Copyright (c) 2008 Alexander von Gernler. All rights reserved. |
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <sys/param.h> | 30 | #include <sys/param.h> |
31 | #include <sys/types.h> | 31 | #include <sys/types.h> |
32 | #include <netinet/in.h> | ||
32 | 33 | ||
33 | #include <openssl/evp.h> | 34 | #include <openssl/evp.h> |
34 | #include <openssl/err.h> | 35 | #include <openssl/err.h> |
@@ -852,29 +853,18 @@ sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp) | |||
852 | } | 853 | } |
853 | 854 | ||
854 | int | 855 | int |
855 | sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, | 856 | sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg, |
856 | u_char **retp, size_t *lenp) | 857 | u_char **retp, size_t *lenp) |
857 | { | 858 | { |
858 | u_char *blob = NULL, *ret = NULL; | 859 | u_char *blob = NULL, *ret = NULL; |
859 | size_t blob_len = 0; | 860 | size_t blob_len = 0; |
860 | int hash_alg = -1, r = SSH_ERR_INTERNAL_ERROR; | 861 | int r = SSH_ERR_INTERNAL_ERROR; |
861 | 862 | ||
862 | if (retp != NULL) | 863 | if (retp != NULL) |
863 | *retp = NULL; | 864 | *retp = NULL; |
864 | if (lenp != NULL) | 865 | if (lenp != NULL) |
865 | *lenp = 0; | 866 | *lenp = 0; |
866 | 867 | if (ssh_digest_bytes(dgst_alg) == 0) { | |
867 | switch (dgst_type) { | ||
868 | case SSH_FP_MD5: | ||
869 | hash_alg = SSH_DIGEST_MD5; | ||
870 | break; | ||
871 | case SSH_FP_SHA1: | ||
872 | hash_alg = SSH_DIGEST_SHA1; | ||
873 | break; | ||
874 | case SSH_FP_SHA256: | ||
875 | hash_alg = SSH_DIGEST_SHA256; | ||
876 | break; | ||
877 | default: | ||
878 | r = SSH_ERR_INVALID_ARGUMENT; | 868 | r = SSH_ERR_INVALID_ARGUMENT; |
879 | goto out; | 869 | goto out; |
880 | } | 870 | } |
@@ -899,7 +889,7 @@ sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, | |||
899 | r = SSH_ERR_ALLOC_FAIL; | 889 | r = SSH_ERR_ALLOC_FAIL; |
900 | goto out; | 890 | goto out; |
901 | } | 891 | } |
902 | if ((r = ssh_digest_memory(hash_alg, blob, blob_len, | 892 | if ((r = ssh_digest_memory(dgst_alg, blob, blob_len, |
903 | ret, SSH_DIGEST_MAX_LENGTH)) != 0) | 893 | ret, SSH_DIGEST_MAX_LENGTH)) != 0) |
904 | goto out; | 894 | goto out; |
905 | /* success */ | 895 | /* success */ |
@@ -908,7 +898,7 @@ sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, | |||
908 | ret = NULL; | 898 | ret = NULL; |
909 | } | 899 | } |
910 | if (lenp != NULL) | 900 | if (lenp != NULL) |
911 | *lenp = ssh_digest_bytes(hash_alg); | 901 | *lenp = ssh_digest_bytes(dgst_alg); |
912 | r = 0; | 902 | r = 0; |
913 | out: | 903 | out: |
914 | free(ret); | 904 | free(ret); |
@@ -920,21 +910,45 @@ sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, | |||
920 | } | 910 | } |
921 | 911 | ||
922 | static char * | 912 | static char * |
923 | fingerprint_hex(u_char *dgst_raw, size_t dgst_raw_len) | 913 | fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) |
924 | { | 914 | { |
925 | char *retval; | 915 | char *ret; |
926 | size_t i; | 916 | size_t plen = strlen(alg) + 1; |
917 | size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1; | ||
918 | int r; | ||
927 | 919 | ||
928 | if ((retval = calloc(1, dgst_raw_len * 3 + 1)) == NULL) | 920 | if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL) |
921 | return NULL; | ||
922 | strlcpy(ret, alg, rlen); | ||
923 | strlcat(ret, ":", rlen); | ||
924 | if (dgst_raw_len == 0) | ||
925 | return ret; | ||
926 | if ((r = b64_ntop(dgst_raw, dgst_raw_len, | ||
927 | ret + plen, rlen - plen)) == -1) { | ||
928 | explicit_bzero(ret, rlen); | ||
929 | free(ret); | ||
929 | return NULL; | 930 | return NULL; |
930 | for (i = 0; i < dgst_raw_len; i++) { | ||
931 | char hex[4]; | ||
932 | snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]); | ||
933 | strlcat(retval, hex, dgst_raw_len * 3 + 1); | ||
934 | } | 931 | } |
932 | /* Trim padding characters from end */ | ||
933 | ret[strcspn(ret, "=")] = '\0'; | ||
934 | return ret; | ||
935 | } | ||
935 | 936 | ||
936 | /* Remove the trailing ':' character */ | 937 | static char * |
937 | retval[(dgst_raw_len * 3) - 1] = '\0'; | 938 | fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) |
939 | { | ||
940 | char *retval, hex[5]; | ||
941 | size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2; | ||
942 | |||
943 | if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL) | ||
944 | return NULL; | ||
945 | strlcpy(retval, alg, rlen); | ||
946 | strlcat(retval, ":", rlen); | ||
947 | for (i = 0; i < dgst_raw_len; i++) { | ||
948 | snprintf(hex, sizeof(hex), "%s%02x", | ||
949 | i > 0 ? ":" : "", dgst_raw[i]); | ||
950 | strlcat(retval, hex, rlen); | ||
951 | } | ||
938 | return retval; | 952 | return retval; |
939 | } | 953 | } |
940 | 954 | ||
@@ -1020,7 +1034,7 @@ fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len) | |||
1020 | #define FLDSIZE_Y (FLDBASE + 1) | 1034 | #define FLDSIZE_Y (FLDBASE + 1) |
1021 | #define FLDSIZE_X (FLDBASE * 2 + 1) | 1035 | #define FLDSIZE_X (FLDBASE * 2 + 1) |
1022 | static char * | 1036 | static char * |
1023 | fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, | 1037 | fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len, |
1024 | const struct sshkey *k) | 1038 | const struct sshkey *k) |
1025 | { | 1039 | { |
1026 | /* | 1040 | /* |
@@ -1028,9 +1042,9 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, | |||
1028 | * intersects with itself. Matter of taste. | 1042 | * intersects with itself. Matter of taste. |
1029 | */ | 1043 | */ |
1030 | char *augmentation_string = " .o+=*BOX@%&#/^SE"; | 1044 | char *augmentation_string = " .o+=*BOX@%&#/^SE"; |
1031 | char *retval, *p, title[FLDSIZE_X]; | 1045 | char *retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X]; |
1032 | u_char field[FLDSIZE_X][FLDSIZE_Y]; | 1046 | u_char field[FLDSIZE_X][FLDSIZE_Y]; |
1033 | size_t i, tlen; | 1047 | size_t i, tlen, hlen; |
1034 | u_int b; | 1048 | u_int b; |
1035 | int x, y, r; | 1049 | int x, y, r; |
1036 | size_t len = strlen(augmentation_string) - 1; | 1050 | size_t len = strlen(augmentation_string) - 1; |
@@ -1075,8 +1089,12 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, | |||
1075 | sshkey_type(k), sshkey_size(k)); | 1089 | sshkey_type(k), sshkey_size(k)); |
1076 | /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */ | 1090 | /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */ |
1077 | if (r < 0 || r > (int)sizeof(title)) | 1091 | if (r < 0 || r > (int)sizeof(title)) |
1078 | snprintf(title, sizeof(title), "[%s]", sshkey_type(k)); | 1092 | r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k)); |
1079 | tlen = strlen(title); | 1093 | tlen = (r <= 0) ? 0 : strlen(title); |
1094 | |||
1095 | /* assemble hash ID. */ | ||
1096 | r = snprintf(hash, sizeof(hash), "[%s]", alg); | ||
1097 | hlen = (r <= 0) ? 0 : strlen(hash); | ||
1080 | 1098 | ||
1081 | /* output upper border */ | 1099 | /* output upper border */ |
1082 | p = retval; | 1100 | p = retval; |
@@ -1085,7 +1103,7 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, | |||
1085 | *p++ = '-'; | 1103 | *p++ = '-'; |
1086 | memcpy(p, title, tlen); | 1104 | memcpy(p, title, tlen); |
1087 | p += tlen; | 1105 | p += tlen; |
1088 | for (i = p - retval - 1; i < FLDSIZE_X; i++) | 1106 | for (i += tlen; i < FLDSIZE_X; i++) |
1089 | *p++ = '-'; | 1107 | *p++ = '-'; |
1090 | *p++ = '+'; | 1108 | *p++ = '+'; |
1091 | *p++ = '\n'; | 1109 | *p++ = '\n'; |
@@ -1101,7 +1119,11 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, | |||
1101 | 1119 | ||
1102 | /* output lower border */ | 1120 | /* output lower border */ |
1103 | *p++ = '+'; | 1121 | *p++ = '+'; |
1104 | for (i = 0; i < FLDSIZE_X; i++) | 1122 | for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++) |
1123 | *p++ = '-'; | ||
1124 | memcpy(p, hash, hlen); | ||
1125 | p += hlen; | ||
1126 | for (i += hlen; i < FLDSIZE_X; i++) | ||
1105 | *p++ = '-'; | 1127 | *p++ = '-'; |
1106 | *p++ = '+'; | 1128 | *p++ = '+'; |
1107 | 1129 | ||
@@ -1109,24 +1131,39 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, | |||
1109 | } | 1131 | } |
1110 | 1132 | ||
1111 | char * | 1133 | char * |
1112 | sshkey_fingerprint(const struct sshkey *k, enum sshkey_fp_type dgst_type, | 1134 | sshkey_fingerprint(const struct sshkey *k, int dgst_alg, |
1113 | enum sshkey_fp_rep dgst_rep) | 1135 | enum sshkey_fp_rep dgst_rep) |
1114 | { | 1136 | { |
1115 | char *retval = NULL; | 1137 | char *retval = NULL; |
1116 | u_char *dgst_raw; | 1138 | u_char *dgst_raw; |
1117 | size_t dgst_raw_len; | 1139 | size_t dgst_raw_len; |
1118 | 1140 | ||
1119 | if (sshkey_fingerprint_raw(k, dgst_type, &dgst_raw, &dgst_raw_len) != 0) | 1141 | if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0) |
1120 | return NULL; | 1142 | return NULL; |
1121 | switch (dgst_rep) { | 1143 | switch (dgst_rep) { |
1144 | case SSH_FP_DEFAULT: | ||
1145 | if (dgst_alg == SSH_DIGEST_MD5) { | ||
1146 | retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), | ||
1147 | dgst_raw, dgst_raw_len); | ||
1148 | } else { | ||
1149 | retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), | ||
1150 | dgst_raw, dgst_raw_len); | ||
1151 | } | ||
1152 | break; | ||
1122 | case SSH_FP_HEX: | 1153 | case SSH_FP_HEX: |
1123 | retval = fingerprint_hex(dgst_raw, dgst_raw_len); | 1154 | retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), |
1155 | dgst_raw, dgst_raw_len); | ||
1156 | break; | ||
1157 | case SSH_FP_BASE64: | ||
1158 | retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), | ||
1159 | dgst_raw, dgst_raw_len); | ||
1124 | break; | 1160 | break; |
1125 | case SSH_FP_BUBBLEBABBLE: | 1161 | case SSH_FP_BUBBLEBABBLE: |
1126 | retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len); | 1162 | retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len); |
1127 | break; | 1163 | break; |
1128 | case SSH_FP_RANDOMART: | 1164 | case SSH_FP_RANDOMART: |
1129 | retval = fingerprint_randomart(dgst_raw, dgst_raw_len, k); | 1165 | retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg), |
1166 | dgst_raw, dgst_raw_len, k); | ||
1130 | break; | 1167 | break; |
1131 | default: | 1168 | default: |
1132 | explicit_bzero(dgst_raw, dgst_raw_len); | 1169 | explicit_bzero(dgst_raw, dgst_raw_len); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshkey.h,v 1.1 2014/06/24 01:16:58 djm Exp $ */ | 1 | /* $OpenBSD: sshkey.h,v 1.2 2014/12/21 22:27:55 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -67,16 +67,14 @@ enum sshkey_types { | |||
67 | KEY_UNSPEC | 67 | KEY_UNSPEC |
68 | }; | 68 | }; |
69 | 69 | ||
70 | /* Fingerprint hash algorithms */ | 70 | /* Default fingerprint hash */ |
71 | enum sshkey_fp_type { | 71 | #define SSH_FP_HASH_DEFAULT SSH_DIGEST_SHA256 |
72 | SSH_FP_SHA1, | ||
73 | SSH_FP_MD5, | ||
74 | SSH_FP_SHA256 | ||
75 | }; | ||
76 | 72 | ||
77 | /* Fingerprint representation formats */ | 73 | /* Fingerprint representation formats */ |
78 | enum sshkey_fp_rep { | 74 | enum sshkey_fp_rep { |
75 | SSH_FP_DEFAULT = 0, | ||
79 | SSH_FP_HEX, | 76 | SSH_FP_HEX, |
77 | SSH_FP_BASE64, | ||
80 | SSH_FP_BUBBLEBABBLE, | 78 | SSH_FP_BUBBLEBABBLE, |
81 | SSH_FP_RANDOMART | 79 | SSH_FP_RANDOMART |
82 | }; | 80 | }; |
@@ -124,9 +122,9 @@ int sshkey_equal_public(const struct sshkey *, | |||
124 | const struct sshkey *); | 122 | const struct sshkey *); |
125 | int sshkey_equal(const struct sshkey *, const struct sshkey *); | 123 | int sshkey_equal(const struct sshkey *, const struct sshkey *); |
126 | char *sshkey_fingerprint(const struct sshkey *, | 124 | char *sshkey_fingerprint(const struct sshkey *, |
127 | enum sshkey_fp_type, enum sshkey_fp_rep); | 125 | int, enum sshkey_fp_rep); |
128 | int sshkey_fingerprint_raw(const struct sshkey *k, | 126 | int sshkey_fingerprint_raw(const struct sshkey *k, |
129 | enum sshkey_fp_type dgst_type, u_char **retp, size_t *lenp); | 127 | int, u_char **retp, size_t *lenp); |
130 | const char *sshkey_type(const struct sshkey *); | 128 | const char *sshkey_type(const struct sshkey *); |
131 | const char *sshkey_cert_type(const struct sshkey *); | 129 | const char *sshkey_cert_type(const struct sshkey *); |
132 | int sshkey_write(const struct sshkey *, FILE *); | 130 | int sshkey_write(const struct sshkey *, FILE *); |