Skip to content

Commit

Permalink
upstream commit
Browse files Browse the repository at this point in the history
Add FingerprintHash option to control algorithm used for
 key fingerprints. Default changes from MD5 to SHA256 and format from hex to
 base64.

Feedback and ok naddy@ markus@
  • Loading branch information
djmdjm committed Dec 21, 2014
1 parent 058f839 commit 56d1c83
Show file tree
Hide file tree
Showing 28 changed files with 374 additions and 149 deletions.
5 changes: 3 additions & 2 deletions auth-rsa.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: auth-rsa.c,v 1.88 2014/07/15 15:54:14 millert Exp $ */
/* $OpenBSD: auth-rsa.c,v 1.89 2014/12/21 22:27:56 djm Exp $ */
/*
* Author: Tatu Ylonen <[email protected]>
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -236,7 +236,8 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file,
"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, options.fingerprint_hash,
SSH_FP_DEFAULT);
debug("matching key found: file %s, line %lu %s %s",
file, linenum, key_type(key), fp);
free(fp);
Expand Down
5 changes: 3 additions & 2 deletions auth.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: auth.c,v 1.107 2014/12/04 02:24:32 djm Exp $ */
/* $OpenBSD: auth.c,v 1.108 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
Expand Down Expand Up @@ -679,7 +679,8 @@ auth_key_is_revoked(Key *key)

if (options.revoked_keys_file == NULL)
return 0;
if ((fp = sshkey_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX)) == NULL) {
if ((fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
error("%s: fingerprint key: %s", __func__, ssh_err(r));
goto out;
Expand Down
7 changes: 4 additions & 3 deletions auth2-hostbased.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: auth2-hostbased.c,v 1.18 2014/07/15 15:54:14 millert Exp $ */
/* $OpenBSD: auth2-hostbased.c,v 1.19 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
Expand Down Expand Up @@ -208,13 +208,14 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
if (host_status == HOST_OK) {
if (key_is_cert(key)) {
fp = key_fingerprint(key->cert->signature_key,
SSH_FP_MD5, SSH_FP_HEX);
options.fingerprint_hash, SSH_FP_DEFAULT);
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, options.fingerprint_hash,
SSH_FP_DEFAULT);
verbose("Accepted %s public key %s from %s@%s",
key_type(key), fp, cuser, lookup);
}
Expand Down
16 changes: 9 additions & 7 deletions auth2-pubkey.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: auth2-pubkey.c,v 1.42 2014/12/04 02:24:32 djm Exp $ */
/* $OpenBSD: auth2-pubkey.c,v 1.43 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
Expand Down Expand Up @@ -213,15 +213,16 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)

if (key_is_cert(key)) {
fp = key_fingerprint(key->cert->signature_key,
SSH_FP_MD5, SSH_FP_HEX);
options.fingerprint_hash, SSH_FP_DEFAULT);
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, options.fingerprint_hash,
SSH_FP_DEFAULT);
auth_info(authctxt, "%s %s%s%s", key_type(key), fp,
extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
free(fp);
Expand Down Expand Up @@ -365,8 +366,8 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
continue;
if (!key_is_cert_authority)
continue;
fp = key_fingerprint(found, SSH_FP_MD5,
SSH_FP_HEX);
fp = key_fingerprint(found, options.fingerprint_hash,
SSH_FP_DEFAULT);
debug("matching CA found: file %s, line %lu, %s %s",
file, linenum, key_type(found), fp);
/*
Expand Down Expand Up @@ -406,7 +407,8 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
if (key_is_cert_authority)
continue;
found_key = 1;
fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
fp = key_fingerprint(found, options.fingerprint_hash,
SSH_FP_DEFAULT);
debug("matching key found: file %s, line %lu %s %s",
file, linenum, key_type(found), fp);
free(fp);
Expand All @@ -432,7 +434,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
return 0;

ca_fp = key_fingerprint(key->cert->signature_key,
SSH_FP_MD5, SSH_FP_HEX);
options.fingerprint_hash, SSH_FP_DEFAULT);

if (sshkey_in_file(key->cert->signature_key,
options.trusted_user_ca_keys, 1, 0) != 0) {
Expand Down
22 changes: 21 additions & 1 deletion digest-libc.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: digest-libc.c,v 1.3 2014/06/24 01:13:21 djm Exp $ */
/* $OpenBSD: digest-libc.c,v 1.4 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2013 Damien Miller <[email protected]>
* Copyright (c) 2014 Markus Friedl. All rights reserved.
Expand Down Expand Up @@ -126,6 +126,26 @@ ssh_digest_by_alg(int alg)
return &(digests[alg]);
}

int
ssh_digest_alg_by_name(const char *name)
{
int alg;

for (alg = 0; alg < SSH_DIGEST_MAX; alg++) {
if (strcasecmp(name, digests[alg].name) == 0)
return digests[alg].id;
}
return -1;
}

const char *
ssh_digest_alg_name(int alg)
{
const struct ssh_digest *digest = ssh_digest_by_alg(alg);

return digest == NULL ? NULL : digest->name;
}

size_t
ssh_digest_bytes(int alg)
{
Expand Down
22 changes: 21 additions & 1 deletion digest-openssl.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: digest-openssl.c,v 1.4 2014/07/03 03:26:43 djm Exp $ */
/* $OpenBSD: digest-openssl.c,v 1.5 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2013 Damien Miller <[email protected]>
*
Expand Down Expand Up @@ -74,6 +74,26 @@ ssh_digest_by_alg(int alg)
return &(digests[alg]);
}

int
ssh_digest_alg_by_name(const char *name)
{
int alg;

for (alg = 0; digests[alg].id != -1; alg++) {
if (strcasecmp(name, digests[alg].name) == 0)
return digests[alg].id;
}
return -1;
}

const char *
ssh_digest_alg_name(int alg)
{
const struct ssh_digest *digest = ssh_digest_by_alg(alg);

return digest == NULL ? NULL : digest->name;
}

size_t
ssh_digest_bytes(int alg)
{
Expand Down
8 changes: 7 additions & 1 deletion digest.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: digest.h,v 1.6 2014/07/03 04:36:45 djm Exp $ */
/* $OpenBSD: digest.h,v 1.7 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2013 Damien Miller <[email protected]>
*
Expand Down Expand Up @@ -33,6 +33,12 @@
struct sshbuf;
struct ssh_digest_ctx;

/* Looks up a digest algorithm by name */
int ssh_digest_alg_by_name(const char *name);

/* Returns the algorithm name for a digest identifier */
const char *ssh_digest_alg_name(int alg);

/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
size_t ssh_digest_bytes(int alg);

Expand Down
11 changes: 6 additions & 5 deletions dns.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: dns.c,v 1.31 2014/06/24 01:13:21 djm Exp $ */
/* $OpenBSD: dns.c,v 1.32 2014/12/21 22:27:56 djm Exp $ */

/*
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
Expand Down Expand Up @@ -41,6 +41,7 @@
#include "key.h"
#include "dns.h"
#include "log.h"
#include "digest.h"

static const char *errset_text[] = {
"success", /* 0 ERRSET_SUCCESS */
Expand Down Expand Up @@ -80,7 +81,7 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
u_char **digest, u_int *digest_len, Key *key)
{
int success = 0;
enum fp_type fp_type = 0;
int fp_alg = -1;

switch (key->type) {
case KEY_RSA:
Expand Down Expand Up @@ -110,17 +111,17 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,

switch (*digest_type) {
case SSHFP_HASH_SHA1:
fp_type = SSH_FP_SHA1;
fp_alg = SSH_DIGEST_SHA1;
break;
case SSHFP_HASH_SHA256:
fp_type = SSH_FP_SHA256;
fp_alg = SSH_DIGEST_SHA256;
break;
default:
*digest_type = SSHFP_HASH_RESERVED; /* 0 */
}

if (*algorithm && *digest_type) {
*digest = key_fingerprint_raw(key, fp_type, digest_len);
*digest = key_fingerprint_raw(key, fp_alg, digest_len);
if (*digest == NULL)
fatal("dns_read_key: null from key_fingerprint_raw()");
success = 1;
Expand Down
7 changes: 3 additions & 4 deletions key.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: key.c,v 1.123 2014/12/04 20:47:36 djm Exp $ */
/* $OpenBSD: key.c,v 1.124 2014/12/21 22:27:56 djm Exp $ */
/*
* placed in the public domain
*/
Expand Down Expand Up @@ -40,16 +40,15 @@ key_new_private(int type)
}

u_char*
key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
u_int *dgst_raw_length)
key_fingerprint_raw(const Key *k, int dgst_alg, u_int *dgst_raw_length)
{
u_char *ret = NULL;
size_t dlen;
int r;

if (dgst_raw_length != NULL)
*dgst_raw_length = 0;
if ((r = sshkey_fingerprint_raw(k, dgst_type, &ret, &dlen)) != 0)
if ((r = sshkey_fingerprint_raw(k, dgst_alg, &ret, &dlen)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
if (dlen > INT_MAX)
fatal("%s: giant len %zu", __func__, dlen);
Expand Down
4 changes: 2 additions & 2 deletions key.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: key.h,v 1.43 2014/12/04 20:47:36 djm Exp $ */
/* $OpenBSD: key.h,v 1.44 2014/12/21 22:27:56 djm Exp $ */

/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
Expand Down Expand Up @@ -67,7 +67,7 @@ void key_add_private(Key *);
Key *key_new_private(int);
void key_free(Key *);
Key *key_demote(const Key *);
u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *);
u_char *key_fingerprint_raw(const Key *, int, u_int *);
int key_write(const Key *, FILE *);
int key_read(Key *, char **);

Expand Down
8 changes: 5 additions & 3 deletions krl.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/* $OpenBSD: krl.c,v 1.20 2014/12/04 01:49:59 djm Exp $ */
/* $OpenBSD: krl.c,v 1.21 2014/12/21 22:27:56 djm Exp $ */

#include "includes.h"

Expand All @@ -36,6 +36,7 @@
#include "misc.h"
#include "log.h"
#include "ssherr.h"
#include "digest.h"

#include "krl.h"

Expand Down Expand Up @@ -411,7 +412,8 @@ ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key)
int r;

debug3("%s: revoke type %s by sha1", __func__, sshkey_type(key));
if ((r = sshkey_fingerprint_raw(key, SSH_FP_SHA1, &blob, &len)) != 0)
if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1,
&blob, &len)) != 0)
return r;
return revoke_blob(&krl->revoked_sha1s, blob, len);
}
Expand Down Expand Up @@ -1151,7 +1153,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)

/* Check explicitly revoked hashes first */
memset(&rb, 0, sizeof(rb));
if ((r = sshkey_fingerprint_raw(key, SSH_FP_SHA1,
if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1,
&rb.blob, &rb.len)) != 0)
return r;
erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
Expand Down
24 changes: 23 additions & 1 deletion readconf.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: readconf.c,v 1.223 2014/12/04 02:24:32 djm Exp $ */
/* $OpenBSD: readconf.c,v 1.224 2014/12/21 22:27:56 djm Exp $ */
/*
* Author: Tatu Ylonen <[email protected]>
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -60,6 +60,7 @@
#include "mac.h"
#include "uidswap.h"
#include "myproposal.h"
#include "digest.h"

/* Format of the configuration file:
Expand Down Expand Up @@ -155,6 +156,7 @@ typedef enum {
oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
oFingerprintHash,
oIgnoredUnknownOption, oDeprecated, oUnsupported
} OpCodes;

Expand Down Expand Up @@ -270,6 +272,7 @@ static struct {
{ "streamlocalbindmask", oStreamLocalBindMask },
{ "streamlocalbindunlink", oStreamLocalBindUnlink },
{ "revokedhostkeys", oRevokedHostKeys },
{ "fingerprinthash", oFingerprintHash },
{ "ignoreunknown", oIgnoreUnknown },

{ NULL, oBadOption }
Expand Down Expand Up @@ -1460,6 +1463,18 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
charptr = &options->revoked_host_keys;
goto parse_string;

case oFingerprintHash:
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.",
filename, linenum);
if ((value = ssh_digest_alg_by_name(arg)) == -1)
fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
filename, linenum, arg);
if (*activep)
options->fingerprint_hash = value;
break;

case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
Expand Down Expand Up @@ -1637,6 +1652,7 @@ initialize_options(Options * options)
options->canonicalize_fallback_local = -1;
options->canonicalize_hostname = -1;
options->revoked_host_keys = NULL;
options->fingerprint_hash = -1;
}

/*
Expand Down Expand Up @@ -1814,6 +1830,9 @@ fill_default_options(Options * options)
options->canonicalize_fallback_local = 1;
if (options->canonicalize_hostname == -1)
options->canonicalize_hostname = SSH_CANONICALISE_NO;
if (options->fingerprint_hash == -1)
options->fingerprint_hash = SSH_FP_HASH_DEFAULT;

#define CLEAR_ON_NONE(v) \
do { \
if (option_clear_or_none(v)) { \
Expand Down Expand Up @@ -2071,6 +2090,8 @@ fmt_intarg(OpCodes code, int val)
return fmt_multistate_int(val, multistate_requesttty);
case oCanonicalizeHostname:
return fmt_multistate_int(val, multistate_canonicalizehostname);
case oFingerprintHash:
return ssh_digest_alg_name(val);
case oProtocol:
switch (val) {
case SSH_PROTO_1:
Expand Down Expand Up @@ -2205,6 +2226,7 @@ dump_client_config(Options *o, const char *host)
dump_cfg_fmtint(oControlMaster, o->control_master);
dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
dump_cfg_fmtint(oForwardAgent, o->forward_agent);
dump_cfg_fmtint(oForwardX11, o->forward_x11);
dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
Expand Down
Loading

0 comments on commit 56d1c83

Please sign in to comment.