forked from pool/openssh
08f9072513
- Update of the underlying OpenSSH to 6.5p1 - Update to 6.5p1 Features since 6.4p1: * ssh(1), sshd(8): support for key exchange using ECDH in Daniel Bernstein's Curve25519; default when both the client and server support it. * ssh(1), sshd(8): support for Ed25519 as a public key type fo rboth server and client. Ed25519 is an EC signature offering better security than ECDSA and DSA and good performance. * Add a new private key format that uses a bcrypt KDF to better protect keys at rest. Used unconditionally for Ed25519 keys, on demand for other key types via the -o ssh-keygen(1) option. Intended to become default in the near future. Details documented in PROTOCOL.key. * ssh(1), sshd(8): new transport cipher "chacha20-poly1305@openssh.com" combining Daniel Bernstein's ChaCha20 stream cipher and Poly1305 MAC to build an authenticated encryption mode. Details documented PROTOCOL.chacha20poly1305. * ssh(1), sshd(8): refuse RSA keys from old proprietary clients and servers that use the obsolete RSA+MD5 signature scheme. It will still be possible to connect with these clients/servers but only DSA keys will be accepted, and OpenSSH will refuse connection entirely in a future release. * ssh(1), sshd(8): refuse old proprietary clients and servers that use a weaker key exchange hash calculation. * ssh(1): increase the size of the Diffie-Hellman groups requested for each symmetric key size. New values from NIST Special Publication 800-57 with the upper limit specified by OBS-URL: https://build.opensuse.org/request/show/222365 OBS-URL: https://build.opensuse.org/package/show/network/openssh?expand=0&rev=63
731 lines
24 KiB
Diff
731 lines
24 KiB
Diff
# HG changeset patch
|
|
# Parent 450c3933f35c6801a682ea32c588e4c9ff73414a
|
|
|
|
# select fingerprint hash algorithms based on the environment variable
|
|
# SSH_FP_TYPE_ENVVAR and append it to hex and randomart fingerprints
|
|
# Petr Cerny <pcerny@suse.cz>
|
|
|
|
diff --git a/openssh-6.5p1/auth-rsa.c b/openssh-6.5p1/auth-rsa.c
|
|
--- a/openssh-6.5p1/auth-rsa.c
|
|
+++ b/openssh-6.5p1/auth-rsa.c
|
|
@@ -226,17 +226,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.5p1/auth.c b/openssh-6.5p1/auth.c
|
|
--- a/openssh-6.5p1/auth.c
|
|
+++ b/openssh-6.5p1/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.5p1/auth2-hostbased.c b/openssh-6.5p1/auth2-hostbased.c
|
|
--- a/openssh-6.5p1/auth2-hostbased.c
|
|
+++ b/openssh-6.5p1/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.5p1/auth2-pubkey.c b/openssh-6.5p1/auth2-pubkey.c
|
|
--- a/openssh-6.5p1/auth2-pubkey.c
|
|
+++ b/openssh-6.5p1/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.5p1/key.c b/openssh-6.5p1/key.c
|
|
--- a/openssh-6.5p1/key.c
|
|
+++ b/openssh-6.5p1/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;
|
|
}
|
|
memset(dgst_raw, 0, 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.5p1/key.h b/openssh-6.5p1/key.h
|
|
--- a/openssh-6.5p1/key.h
|
|
+++ b/openssh-6.5p1/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.5p1/ssh-add.c b/openssh-6.5p1/ssh-add.c
|
|
--- a/openssh-6.5p1/ssh-add.c
|
|
+++ b/openssh-6.5p1/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.5p1/ssh-agent.c b/openssh-6.5p1/ssh-agent.c
|
|
--- a/openssh-6.5p1/ssh-agent.c
|
|
+++ b/openssh-6.5p1/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.5p1/ssh-keygen.c b/openssh-6.5p1/ssh-keygen.c
|
|
--- a/openssh-6.5p1/ssh-keygen.c
|
|
+++ b/openssh-6.5p1/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.5p1/sshconnect.c b/openssh-6.5p1/sshconnect.c
|
|
--- a/openssh-6.5p1/sshconnect.c
|
|
+++ b/openssh-6.5p1/sshconnect.c
|
|
@@ -906,18 +906,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 &&
|
|
@@ -947,18 +947,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
|
|
@@ -1212,17 +1212,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) {
|
|
|
|
@@ -1319,18 +1319,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);
|
|
@@ -1341,17 +1341,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.5p1/sshconnect2.c b/openssh-6.5p1/sshconnect2.c
|
|
--- a/openssh-6.5p1/sshconnect2.c
|
|
+++ b/openssh-6.5p1/sshconnect2.c
|
|
@@ -592,17 +592,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
|
|
*/
|
|
@@ -1206,17 +1206,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;
|
|
}
|