# HG changeset patch # Parent 8b2615db484b7061edd15f3bee36958f790f790e # select fingerprint hash algorithms based on the environment variable # SSH_FP_TYPE_ENVVAR and append it to hex and randomart fingerprints # Petr Cerny diff --git a/openssh-6.6p1/auth-rsa.c b/openssh-6.6p1/auth-rsa.c --- a/openssh-6.6p1/auth-rsa.c +++ b/openssh-6.6p1/auth-rsa.c @@ -230,17 +230,17 @@ rsa_key_allowed_in_file(struct passwd *p /* check the real bits */ keybits = BN_num_bits(key->rsa->n); if (keybits < 0 || bits != keybits) logit("Warning: %s, line %lu: keysize mismatch: " "actual %d vs. announced %d.", file, linenum, BN_num_bits(key->rsa->n), bits); - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX); debug("matching key found: file %s, line %lu %s %s", file, linenum, key_type(key), fp); free(fp); /* Never accept a revoked key */ if (auth_key_is_revoked(key)) break; diff --git a/openssh-6.6p1/auth.c b/openssh-6.6p1/auth.c --- a/openssh-6.6p1/auth.c +++ b/openssh-6.6p1/auth.c @@ -680,17 +680,17 @@ auth_key_is_revoked(Key *key) case -1: /* Error opening revoked_keys_file: refuse all keys */ error("Revoked keys file is unreadable: refusing public key " "authentication"); return 1; case 1: revoked: /* Key revoked */ - key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + key_fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX); error("WARNING: authentication attempt with a revoked " "%s key %s ", key_type(key), key_fp); free(key_fp); return 1; } fatal("key_in_file returned junk"); } diff --git a/openssh-6.6p1/auth2-hostbased.c b/openssh-6.6p1/auth2-hostbased.c --- a/openssh-6.6p1/auth2-hostbased.c +++ b/openssh-6.6p1/auth2-hostbased.c @@ -202,23 +202,23 @@ hostbased_key_allowed(struct passwd *pw, _PATH_SSH_SYSTEM_HOSTFILE2, options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE2); } if (host_status == HOST_OK) { if (key_is_cert(key)) { fp = key_fingerprint(key->cert->signature_key, - SSH_FP_MD5, SSH_FP_HEX); + key_fp_type_select(), SSH_FP_HEX); verbose("Accepted certificate ID \"%s\" signed by " "%s CA %s from %s@%s", key->cert->key_id, key_type(key->cert->signature_key), fp, cuser, lookup); } else { - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX); verbose("Accepted %s public key %s from %s@%s", key_type(key), fp, cuser, lookup); } free(fp); } return (host_status == HOST_OK); } diff --git a/openssh-6.6p1/auth2-pubkey.c b/openssh-6.6p1/auth2-pubkey.c --- a/openssh-6.6p1/auth2-pubkey.c +++ b/openssh-6.6p1/auth2-pubkey.c @@ -208,25 +208,25 @@ pubkey_auth_info(Authctxt *authctxt, con i = vasprintf(&extra, fmt, ap); va_end(ap); if (i < 0 || extra == NULL) fatal("%s: vasprintf failed", __func__); } if (key_is_cert(key)) { fp = key_fingerprint(key->cert->signature_key, - SSH_FP_MD5, SSH_FP_HEX); + key_fp_type_select(), SSH_FP_HEX); auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", key_type(key), key->cert->key_id, (unsigned long long)key->cert->serial, key_type(key->cert->signature_key), fp, extra == NULL ? "" : ", ", extra == NULL ? "" : extra); free(fp); } else { - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX); auth_info(authctxt, "%s %s%s%s", key_type(key), fp, extra == NULL ? "" : ", ", extra == NULL ? "" : extra); free(fp); } free(extra); } static int @@ -360,17 +360,17 @@ check_authkeys_file(FILE *f, char *file, if (key_is_cert(key)) { if (!key_equal(found, key->cert->signature_key)) continue; if (auth_parse_options(pw, key_options, file, linenum) != 1) continue; if (!key_is_cert_authority) continue; - fp = key_fingerprint(found, SSH_FP_MD5, + fp = key_fingerprint(found, key_fp_type_select(), SSH_FP_HEX); debug("matching CA found: file %s, line %lu, %s %s", file, linenum, key_type(found), fp); /* * If the user has specified a list of principals as * a key option, then prefer that list to matching * their username in the certificate principals list. */ @@ -401,17 +401,17 @@ check_authkeys_file(FILE *f, char *file, break; } else if (key_equal(found, key)) { if (auth_parse_options(pw, key_options, file, linenum) != 1) continue; if (key_is_cert_authority) continue; found_key = 1; - fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(found, key_fp_type_select(), SSH_FP_HEX); debug("matching key found: file %s, line %lu %s %s", file, linenum, key_type(found), fp); free(fp); break; } } if (found != NULL) key_free(found); @@ -427,17 +427,17 @@ user_cert_trusted_ca(struct passwd *pw, char *ca_fp, *principals_file = NULL; const char *reason; int ret = 0; if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) return 0; ca_fp = key_fingerprint(key->cert->signature_key, - SSH_FP_MD5, SSH_FP_HEX); + key_fp_type_select(), SSH_FP_HEX); if (key_in_file(key->cert->signature_key, options.trusted_user_ca_keys, 1) != 1) { debug2("%s: CA %s %s is not listed in %s", __func__, key_type(key->cert->signature_key), ca_fp, options.trusted_user_ca_keys); goto out; } diff --git a/openssh-6.6p1/key.c b/openssh-6.6p1/key.c --- a/openssh-6.6p1/key.c +++ b/openssh-6.6p1/key.c @@ -420,30 +420,39 @@ key_fingerprint_raw(const Key *k, enum f *dgst_raw_length = ssh_digest_bytes(hash_alg); } else { fatal("%s: blob is null", __func__); } return retval; } static char * -key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len) +key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len, enum fp_type dgst_type) { char *retval; u_int i; - retval = xcalloc(1, dgst_raw_len * 3 + 1); + /* reserve space for both the key hash and the string for the hash type */ + retval = xcalloc(1, dgst_raw_len * 3 + 1 + SSH_FP_TYPE_STRLEN + 2); for (i = 0; i < dgst_raw_len; i++) { char hex[4]; snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]); strlcat(retval, hex, dgst_raw_len * 3 + 1); } /* Remove the trailing ':' character */ - retval[(dgst_raw_len * 3) - 1] = '\0'; + retval[(dgst_raw_len * 3) - 1] = ' '; + + /* Append hash type */ + { + char hash[SSH_FP_TYPE_STRLEN + 2 + 1]; + snprintf(hash, sizeof(hash), "[%s]", key_fp_type_str(dgst_type)); + strlcat(retval, hash, dgst_raw_len * 3 + 1 + SSH_FP_TYPE_STRLEN + 2); + } + return retval; } static char * key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len) { char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', @@ -518,17 +527,18 @@ key_fingerprint_bubblebabble(u_char *dgs * can be in the exact middle of the picture, and FLDBASE should be >=8 . * Else pictures would be too dense, and drawing the frame would * fail, too, because the key type would not fit in anymore. */ #define FLDBASE 8 #define FLDSIZE_Y (FLDBASE + 1) #define FLDSIZE_X (FLDBASE * 2 + 1) static char * -key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k) +key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k, + enum fp_type dgst_type) { /* * Chars to be used after each other every time the worm * intersects with itself. Matter of taste. */ char *augmentation_string = " .o+=*BOX@%&#/^SE"; char *retval, *p; u_char field[FLDSIZE_X][FLDSIZE_Y]; @@ -585,18 +595,19 @@ key_fingerprint_randomart(u_char *dgst_r *p++ = '|'; for (x = 0; x < FLDSIZE_X; x++) *p++ = augmentation_string[MIN(field[x][y], len)]; *p++ = '|'; *p++ = '\n'; } /* output lower border */ - *p++ = '+'; - for (i = 0; i < FLDSIZE_X; i++) + i = snprintf(p, FLDSIZE_X, "+--[%s]", key_fp_type_str(dgst_type)); + p += i; + for (i--; i < FLDSIZE_X; i++) *p++ = '-'; *p++ = '+'; return retval; } char * key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) @@ -605,34 +616,91 @@ key_fingerprint(const Key *k, enum fp_ty u_char *dgst_raw; u_int dgst_raw_len; dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len); if (!dgst_raw) fatal("key_fingerprint: null from key_fingerprint_raw()"); switch (dgst_rep) { case SSH_FP_HEX: - retval = key_fingerprint_hex(dgst_raw, dgst_raw_len); + retval = key_fingerprint_hex(dgst_raw, dgst_raw_len, dgst_type); break; case SSH_FP_BUBBLEBABBLE: retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); break; case SSH_FP_RANDOMART: - retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k); + retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k, dgst_type); break; default: fatal("key_fingerprint: bad digest representation %d", dgst_rep); break; } explicit_bzero(dgst_raw, dgst_raw_len); free(dgst_raw); return retval; } +enum fp_type +key_fp_type_select(void) +{ + static enum fp_type fp; + static char fp_defined = 0; + char *env; + + if (!fp_defined) { + env = getenv(SSH_FP_TYPE_ENVVAR); + if (env) { + if (!strcasecmp(env, "md5") || + !strcasecmp(env, "md-5")) + fp = SSH_FP_MD5; + else if (!strcasecmp(env, "sha1") || + !strcasecmp(env, "sha-1")) + fp = SSH_FP_SHA1; +#ifdef HAVE_EVP_SHA256 + else if (!strcasecmp(env, "sha256") || + !strcasecmp(env, "sha-256")) + fp = SSH_FP_SHA256; +#endif + else { + error("invalid key type in environment variable " + SSH_FP_TYPE_ENVVAR ": '%s' - falling back to MD5.", + env); + fp = SSH_FP_MD5; + } + } else + fp = SSH_FP_MD5; + + fp_defined = 1; + } + return fp; +} + +/* + * string lengths must be less or equal to SSH_FP_TYPE_STRLEN (defined in + * key.h) as to fit into the fingerprint string buffer + */ +char * +key_fp_type_str(enum fp_type dgst_type) +{ + switch (dgst_type) { + case SSH_FP_MD5: + return "MD5"; + case SSH_FP_SHA1: + return "SHA-1"; +#ifdef HAVE_EVP_SHA256 + case SSH_FP_SHA256: + return "SHA-256"; +#endif + default: + fatal("%s: unknown key fingerprint hash algorithm requested", __func__); + } +} + + /* * Reads a multiple-precision integer in decimal from the buffer, and advances * the pointer. The integer must already be initialized. This function is * permitted to modify the buffer. This leaves *cpp to point just beyond the * last processed (and maybe modified) character. Note that this may modify * the buffer containing the number. */ static int diff --git a/openssh-6.6p1/key.h b/openssh-6.6p1/key.h --- a/openssh-6.6p1/key.h +++ b/openssh-6.6p1/key.h @@ -53,16 +53,18 @@ enum fp_type { SSH_FP_MD5, SSH_FP_SHA256 }; enum fp_rep { SSH_FP_HEX, SSH_FP_BUBBLEBABBLE, SSH_FP_RANDOMART }; +#define SSH_FP_TYPE_ENVVAR "SSH_FINGERPRINT_TYPE" +#define SSH_FP_TYPE_STRLEN 8 /* key is stored in external hardware */ #define KEY_FLAG_EXT 0x0001 #define CERT_MAX_PRINCIPALS 256 struct KeyCert { Buffer certblob; /* Kept around for use on wire */ u_int type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */ @@ -104,16 +106,18 @@ int key_equal_public(const Key *, cons int key_equal(const Key *, const Key *); char *key_fingerprint(const Key *, enum fp_type, enum fp_rep); u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *); const char *key_type(const Key *); const char *key_cert_type(const Key *); int key_write(const Key *, FILE *); int key_read(Key *, char **); u_int key_size(const Key *); +enum fp_type key_fp_type_select(void); +char *key_fp_type_str(enum fp_type); Key *key_generate(int, u_int); Key *key_from_private(const Key *); int key_type_from_name(char *); int key_is_cert(const Key *); int key_type_is_cert(int); int key_type_plain(int); int key_to_certified(Key *, int); diff --git a/openssh-6.6p1/ssh-add.c b/openssh-6.6p1/ssh-add.c --- a/openssh-6.6p1/ssh-add.c +++ b/openssh-6.6p1/ssh-add.c @@ -325,17 +325,17 @@ list_identities(AuthenticationConnection int version; for (version = 1; version <= 2; version++) { for (key = ssh_get_first_identity(ac, &comment, version); key != NULL; key = ssh_get_next_identity(ac, &comment, version)) { had_identities = 1; if (do_fp) { - fp = key_fingerprint(key, SSH_FP_MD5, + fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX); printf("%d %s %s (%s)\n", key_size(key), fp, comment, key_type(key)); free(fp); } else { if (!key_write(key, stdout)) fprintf(stderr, "key_write failed"); fprintf(stdout, " %s\n", comment); diff --git a/openssh-6.6p1/ssh-agent.c b/openssh-6.6p1/ssh-agent.c --- a/openssh-6.6p1/ssh-agent.c +++ b/openssh-6.6p1/ssh-agent.c @@ -193,17 +193,17 @@ lookup_identity(Key *key, int version) /* Check confirmation of keysign request */ static int confirm_key(Identity *id) { char *p; int ret = -1; - p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); + p = key_fingerprint(id->key, key_fp_type_select(), SSH_FP_HEX); if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", id->comment, p)) ret = 0; free(p); return (ret); } diff --git a/openssh-6.6p1/ssh-keygen.c b/openssh-6.6p1/ssh-keygen.c --- a/openssh-6.6p1/ssh-keygen.c +++ b/openssh-6.6p1/ssh-keygen.c @@ -741,27 +741,27 @@ do_download(struct passwd *pw) { #ifdef ENABLE_PKCS11 Key **keys = NULL; int i, nkeys; enum fp_rep rep; enum fp_type fptype; char *fp, *ra; - fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; + fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fp_type_select(); rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; pkcs11_init(0); nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); if (nkeys <= 0) fatal("cannot read public key from pkcs11"); for (i = 0; i < nkeys; i++) { if (print_fingerprint) { fp = key_fingerprint(keys[i], fptype, rep); - ra = key_fingerprint(keys[i], SSH_FP_MD5, + ra = key_fingerprint(keys[i], key_fp_type_select(), SSH_FP_RANDOMART); printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), fp, key_type(keys[i])); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); free(ra); free(fp); } else { @@ -784,29 +784,29 @@ do_fingerprint(struct passwd *pw) FILE *f; Key *public; char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; int i, skip = 0, num = 0, invalid = 1; enum fp_rep rep; enum fp_type fptype; struct stat st; - fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; + fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fp_type_select(); rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); if (stat(identity_file, &st) < 0) { perror(identity_file); exit(1); } public = key_load_public(identity_file, &comment); if (public != NULL) { fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); + ra = key_fingerprint(public, key_fp_type_select(), SSH_FP_RANDOMART); printf("%u %s %s (%s)\n", key_size(public), fp, comment, key_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); key_free(public); free(comment); free(ra); free(fp); @@ -862,17 +862,17 @@ do_fingerprint(struct passwd *pw) public = key_new(KEY_UNSPEC); if (key_read(public, &cp) != 1) { key_free(public); continue; } } comment = *cp ? cp : comment; fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); + ra = key_fingerprint(public, key_fp_type_select(), SSH_FP_RANDOMART); printf("%u %s %s (%s)\n", key_size(public), fp, comment ? comment : "no comment", key_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); free(ra); free(fp); key_free(public); invalid = 0; @@ -983,20 +983,20 @@ do_gen_all_hostkeys(struct passwd *pw) static void printhost(FILE *f, const char *name, Key *public, int ca, int hash) { if (print_fingerprint) { enum fp_rep rep; enum fp_type fptype; char *fp, *ra; - fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; + fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fp_type_select(); rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); + ra = key_fingerprint(public, key_fp_type_select(), SSH_FP_RANDOMART); printf("%u %s %s (%s)\n", key_size(public), fp, name, key_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); free(ra); free(fp); } else { if (hash && (name = host_hash(name, NULL, 0)) == NULL) @@ -1873,19 +1873,19 @@ do_show_cert(struct passwd *pw) if (stat(identity_file, &st) < 0) fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); if ((key = key_load_public(identity_file, NULL)) == NULL) fatal("%s is not a public key", identity_file); if (!key_is_cert(key)) fatal("%s is not a certificate", identity_file); v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00; - key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + key_fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX); ca_fp = key_fingerprint(key->cert->signature_key, - SSH_FP_MD5, SSH_FP_HEX); + key_fp_type_select(), SSH_FP_HEX); printf("%s:\n", identity_file); printf(" Type: %s %s certificate\n", key_ssh_name(key), key_cert_type(key)); printf(" Public key: %s %s\n", key_type(key), key_fp); printf(" Signing CA: %s %s\n", key_type(key->cert->signature_key), ca_fp); printf(" Key ID: \"%s\"\n", key->cert->key_id); @@ -2681,18 +2681,18 @@ passphrase_again: exit(1); } if (!key_write(public, f)) fprintf(stderr, "write key failed\n"); fprintf(f, " %s\n", comment); fclose(f); if (!quiet) { - char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); - char *ra = key_fingerprint(public, SSH_FP_MD5, + char *fp = key_fingerprint(public, key_fp_type_select(), SSH_FP_HEX); + char *ra = key_fingerprint(public, key_fp_type_select(), SSH_FP_RANDOMART); printf("Your public key has been saved in %s.\n", identity_file); printf("The key fingerprint is:\n"); printf("%s %s\n", fp, comment); printf("The key's randomart image is:\n"); printf("%s\n", ra); free(ra); diff --git a/openssh-6.6p1/sshconnect.c b/openssh-6.6p1/sshconnect.c --- a/openssh-6.6p1/sshconnect.c +++ b/openssh-6.6p1/sshconnect.c @@ -909,18 +909,18 @@ check_host_key(char *hostname, struct so "address '%.128s' to the list of known " "hosts (%.30s).", type, ip, user_hostfiles[0]); else logit("Warning: Permanently added the %s host " "key for IP address '%.128s' to the list " "of known hosts.", type, ip); } else if (options.visual_host_key) { - fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); - ra = key_fingerprint(host_key, SSH_FP_MD5, + fp = key_fingerprint(host_key, key_fp_type_select(), SSH_FP_HEX); + ra = key_fingerprint(host_key, key_fp_type_select(), SSH_FP_RANDOMART); logit("Host key fingerprint is %s\n%s\n", fp, ra); free(ra); free(fp); } break; case HOST_NEW: if (options.host_key_alias == NULL && port != 0 && @@ -950,18 +950,18 @@ check_host_key(char *hostname, struct so if (show_other_keys(host_hostkeys, host_key)) snprintf(msg1, sizeof(msg1), "\nbut keys of different type are already" " known for this host."); else snprintf(msg1, sizeof(msg1), "."); /* The default */ - fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); - ra = key_fingerprint(host_key, SSH_FP_MD5, + fp = key_fingerprint(host_key, key_fp_type_select(), SSH_FP_HEX); + ra = key_fingerprint(host_key, key_fp_type_select(), SSH_FP_RANDOMART); msg2[0] = '\0'; if (options.verify_host_key_dns) { if (matching_host_key_dns) snprintf(msg2, sizeof(msg2), "Matching host key fingerprint" " found in DNS.\n"); else @@ -1215,17 +1215,17 @@ fail: /* returns 0 if key verifies or -1 if key does NOT verify */ int verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) { int flags = 0; char *fp; - fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(host_key, key_fp_type_select(), SSH_FP_HEX); debug("Server host key: %s %s", key_type(host_key), fp); free(fp); /* XXX certs are not yet supported for DNS */ if (!key_is_cert(host_key) && options.verify_host_key_dns && verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { if (flags & DNS_VERIFY_FOUND) { @@ -1322,18 +1322,18 @@ show_other_keys(struct hostkeys *hostkey char *fp, *ra; const struct hostkey_entry *found; for (i = 0; type[i] != -1; i++) { if (type[i] == key->type) continue; if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) continue; - fp = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_HEX); - ra = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_RANDOMART); + fp = key_fingerprint(found->key, key_fp_type_select(), SSH_FP_HEX); + ra = key_fingerprint(found->key, key_fp_type_select(), SSH_FP_RANDOMART); logit("WARNING: %s key found for host %s\n" "in %s:%lu\n" "%s key fingerprint %s.", key_type(found->key), found->host, found->file, found->line, key_type(found->key), fp); if (options.visual_host_key) logit("%s", ra); @@ -1344,17 +1344,17 @@ show_other_keys(struct hostkeys *hostkey return ret; } static void warn_changed_key(Key *host_key) { char *fp; - fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(host_key, key_fp_type_select(), SSH_FP_HEX); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); error("It is also possible that a host key has just been changed."); error("The fingerprint for the %s key sent by the remote host is\n%s.", diff --git a/openssh-6.6p1/sshconnect2.c b/openssh-6.6p1/sshconnect2.c --- a/openssh-6.6p1/sshconnect2.c +++ b/openssh-6.6p1/sshconnect2.c @@ -579,17 +579,17 @@ input_userauth_pk_ok(int type, u_int32_t goto done; } if (key->type != pktype) { error("input_userauth_pk_ok: type mismatch " "for decoded key (received %d, expected %d)", key->type, pktype); goto done; } - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX); debug2("input_userauth_pk_ok: fp %s", fp); free(fp); /* * search keys in the reverse order, because last candidate has been * moved to the end of the queue. this also avoids confusion by * duplicate keys */ @@ -990,17 +990,17 @@ sign_and_send_pubkey(Authctxt *authctxt, Buffer b; u_char *blob, *signature; u_int bloblen, slen; u_int skip = 0; int ret = -1; int have_sig = 1; char *fp; - fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(id->key, key_fp_type_select(), SSH_FP_HEX); debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); free(fp); if (key_to_blob(id->key, &blob, &bloblen) == 0) { /* we cannot handle this key */ debug3("sign_and_send_pubkey: cannot handle key"); return 0; }