View | Details | Raw Unified | Return to bug 1872 | Differences between
and this patch

Collapse All | Expand All

(-)a/auth-rsa.c (-1 / +2 lines)
Lines 233-239 rsa_key_allowed_in_file(struct passwd *pw, char *file, Link Here
233
			    "actual %d vs. announced %d.",
233
			    "actual %d vs. announced %d.",
234
			    file, linenum, BN_num_bits(key->rsa->n), bits);
234
			    file, linenum, BN_num_bits(key->rsa->n), bits);
235
235
236
		fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
236
		fp = key_fingerprint(key, options.fingerprint_hash,
237
		    SSH_FP_DEFAULT);
237
		debug("matching key found: file %s, line %lu %s %s",
238
		debug("matching key found: file %s, line %lu %s %s",
238
		    file, linenum, key_type(key), fp);
239
		    file, linenum, key_type(key), fp);
239
		free(fp);
240
		free(fp);
(-)a/auth.c (-1 / +2 lines)
Lines 552-558 auth_key_is_revoked(Key *key) Link Here
552
552
553
	if (options.revoked_keys_file == NULL)
553
	if (options.revoked_keys_file == NULL)
554
		return 0;
554
		return 0;
555
	if ((fp = sshkey_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX)) == NULL) {
555
	if ((fp = sshkey_fingerprint(key, options.fingerprint_hash,
556
	    SSH_FP_DEFAULT)) == NULL) {
556
		r = SSH_ERR_ALLOC_FAIL;
557
		r = SSH_ERR_ALLOC_FAIL;
557
		error("%s: fingerprint key: %s", __func__, ssh_err(r));
558
		error("%s: fingerprint key: %s", __func__, ssh_err(r));
558
		goto out;
559
		goto out;
(-)a/auth2-hostbased.c (-2 / +3 lines)
Lines 207-219 hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, Link Here
207
	if (host_status == HOST_OK) {
207
	if (host_status == HOST_OK) {
208
		if (key_is_cert(key)) {
208
		if (key_is_cert(key)) {
209
			fp = key_fingerprint(key->cert->signature_key,
209
			fp = key_fingerprint(key->cert->signature_key,
210
			    SSH_FP_MD5, SSH_FP_HEX);
210
			    options.fingerprint_hash, SSH_FP_DEFAULT);
211
			verbose("Accepted certificate ID \"%s\" signed by "
211
			verbose("Accepted certificate ID \"%s\" signed by "
212
			    "%s CA %s from %s@%s", key->cert->key_id,
212
			    "%s CA %s from %s@%s", key->cert->key_id,
213
			    key_type(key->cert->signature_key), fp,
213
			    key_type(key->cert->signature_key), fp,
214
			    cuser, lookup);
214
			    cuser, lookup);
215
		} else {
215
		} else {
216
			fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
216
			fp = key_fingerprint(key, options.fingerprint_hash,
217
			    SSH_FP_DEFAULT);
217
			verbose("Accepted %s public key %s from %s@%s",
218
			verbose("Accepted %s public key %s from %s@%s",
218
			    key_type(key), fp, cuser, lookup);
219
			    key_type(key), fp, cuser, lookup);
219
		}
220
		}
(-)a/auth2-pubkey.c (-6 / +8 lines)
Lines 210-216 pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) Link Here
210
210
211
	if (key_is_cert(key)) {
211
	if (key_is_cert(key)) {
212
		fp = key_fingerprint(key->cert->signature_key,
212
		fp = key_fingerprint(key->cert->signature_key,
213
		    SSH_FP_MD5, SSH_FP_HEX);
213
		    options.fingerprint_hash, SSH_FP_DEFAULT);
214
		auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", 
214
		auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", 
215
		    key_type(key), key->cert->key_id,
215
		    key_type(key), key->cert->key_id,
216
		    (unsigned long long)key->cert->serial,
216
		    (unsigned long long)key->cert->serial,
Lines 218-224 pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) Link Here
218
		    extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
218
		    extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
219
		free(fp);
219
		free(fp);
220
	} else {
220
	} else {
221
		fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
221
		fp = key_fingerprint(key, options.fingerprint_hash,
222
		    SSH_FP_DEFAULT);
222
		auth_info(authctxt, "%s %s%s%s", key_type(key), fp,
223
		auth_info(authctxt, "%s %s%s%s", key_type(key), fp,
223
		    extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
224
		    extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
224
		free(fp);
225
		free(fp);
Lines 362-369 check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) Link Here
362
				continue;
363
				continue;
363
			if (!key_is_cert_authority)
364
			if (!key_is_cert_authority)
364
				continue;
365
				continue;
365
			fp = key_fingerprint(found, SSH_FP_MD5,
366
			fp = key_fingerprint(found, options.fingerprint_hash,
366
			    SSH_FP_HEX);
367
			    SSH_FP_DEFAULT);
367
			debug("matching CA found: file %s, line %lu, %s %s",
368
			debug("matching CA found: file %s, line %lu, %s %s",
368
			    file, linenum, key_type(found), fp);
369
			    file, linenum, key_type(found), fp);
369
			/*
370
			/*
Lines 403-409 check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) Link Here
403
			if (key_is_cert_authority)
404
			if (key_is_cert_authority)
404
				continue;
405
				continue;
405
			found_key = 1;
406
			found_key = 1;
406
			fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
407
			fp = key_fingerprint(found, options.fingerprint_hash,
408
			    SSH_FP_DEFAULT);
407
			debug("matching key found: file %s, line %lu %s %s",
409
			debug("matching key found: file %s, line %lu %s %s",
408
			    file, linenum, key_type(found), fp);
410
			    file, linenum, key_type(found), fp);
409
			free(fp);
411
			free(fp);
Lines 429-435 user_cert_trusted_ca(struct passwd *pw, Key *key) Link Here
429
		return 0;
431
		return 0;
430
432
431
	ca_fp = key_fingerprint(key->cert->signature_key,
433
	ca_fp = key_fingerprint(key->cert->signature_key,
432
	    SSH_FP_MD5, SSH_FP_HEX);
434
	    options.fingerprint_hash, SSH_FP_DEFAULT);
433
435
434
	if (sshkey_in_file(key->cert->signature_key,
436
	if (sshkey_in_file(key->cert->signature_key,
435
	    options.trusted_user_ca_keys, 1, 0) != 0) {
437
	    options.trusted_user_ca_keys, 1, 0) != 0) {
(-)a/digest-libc.c (+20 lines)
Lines 124-129 ssh_digest_by_alg(int alg) Link Here
124
	return &(digests[alg]);
124
	return &(digests[alg]);
125
}
125
}
126
126
127
int
128
ssh_digest_alg_by_name(const char *name)
129
{
130
	int alg;
131
132
	for (alg = 0; alg < SSH_DIGEST_MAX; alg++) {
133
		if (strcasecmp(name, digests[alg].name) == 0)
134
			return digests[alg].id;
135
	}
136
	return -1;
137
}
138
139
const char *
140
ssh_digest_alg_name(int alg)
141
{
142
	const struct ssh_digest *digest = ssh_digest_by_alg(alg);
143
144
	return digest == NULL ? NULL : digest->name;
145
}
146
127
size_t
147
size_t
128
ssh_digest_bytes(int alg)
148
ssh_digest_bytes(int alg)
129
{
149
{
(-)a/digest-openssl.c (+20 lines)
Lines 59-64 ssh_digest_by_alg(int alg) Link Here
59
	return &(digests[alg]);
59
	return &(digests[alg]);
60
}
60
}
61
61
62
int
63
ssh_digest_alg_by_name(const char *name)
64
{
65
	int alg;
66
67
	for (alg = 0; digests[alg].id != -1; alg++) {
68
		if (strcasecmp(name, digests[alg].name) == 0)
69
			return digests[alg].id;
70
	}
71
	return -1;
72
}
73
74
const char *
75
ssh_digest_alg_name(int alg)
76
{
77
	const struct ssh_digest *digest = ssh_digest_by_alg(alg);
78
79
	return digest == NULL ? NULL : digest->name;
80
}
81
62
size_t
82
size_t
63
ssh_digest_bytes(int alg)
83
ssh_digest_bytes(int alg)
64
{
84
{
(-)a/digest.h (+6 lines)
Lines 33-38 Link Here
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
(-)a/dns.c (-4 / +5 lines)
Lines 38-43 Link Here
38
#include "key.h"
38
#include "key.h"
39
#include "dns.h"
39
#include "dns.h"
40
#include "log.h"
40
#include "log.h"
41
#include "digest.h"
41
42
42
static const char *errset_text[] = {
43
static const char *errset_text[] = {
43
	"success",		/* 0 ERRSET_SUCCESS */
44
	"success",		/* 0 ERRSET_SUCCESS */
Lines 77-83 dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, Link Here
77
    u_char **digest, u_int *digest_len, Key *key)
78
    u_char **digest, u_int *digest_len, Key *key)
78
{
79
{
79
	int success = 0;
80
	int success = 0;
80
	enum fp_type fp_type = 0;
81
	int fp_alg = -1;
81
82
82
	switch (key->type) {
83
	switch (key->type) {
83
	case KEY_RSA:
84
	case KEY_RSA:
Lines 107-123 dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, Link Here
107
108
108
	switch (*digest_type) {
109
	switch (*digest_type) {
109
	case SSHFP_HASH_SHA1:
110
	case SSHFP_HASH_SHA1:
110
		fp_type = SSH_FP_SHA1;
111
		fp_alg = SSH_DIGEST_SHA1;
111
		break;
112
		break;
112
	case SSHFP_HASH_SHA256:
113
	case SSHFP_HASH_SHA256:
113
		fp_type = SSH_FP_SHA256;
114
		fp_alg = SSH_DIGEST_SHA256;
114
		break;
115
		break;
115
	default:
116
	default:
116
		*digest_type = SSHFP_HASH_RESERVED; /* 0 */
117
		*digest_type = SSHFP_HASH_RESERVED; /* 0 */
117
	}
118
	}
118
119
119
	if (*algorithm && *digest_type) {
120
	if (*algorithm && *digest_type) {
120
		*digest = key_fingerprint_raw(key, fp_type, digest_len);
121
		*digest = key_fingerprint_raw(key, fp_alg, digest_len);
121
		if (*digest == NULL)
122
		if (*digest == NULL)
122
			fatal("dns_read_key: null from key_fingerprint_raw()");
123
			fatal("dns_read_key: null from key_fingerprint_raw()");
123
		success = 1;
124
		success = 1;
(-)a/key.c (-3 / +2 lines)
Lines 38-45 key_new_private(int type) Link Here
38
}
38
}
39
39
40
u_char*
40
u_char*
41
key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
41
key_fingerprint_raw(const Key *k, int dgst_alg, u_int *dgst_raw_length)
42
    u_int *dgst_raw_length)
43
{
42
{
44
	u_char *ret = NULL;
43
	u_char *ret = NULL;
45
	size_t dlen;
44
	size_t dlen;
Lines 47-53 key_fingerprint_raw(const Key *k, enum fp_type dgst_type, Link Here
47
46
48
	if (dgst_raw_length != NULL)
47
	if (dgst_raw_length != NULL)
49
		*dgst_raw_length = 0;
48
		*dgst_raw_length = 0;
50
	if ((r = sshkey_fingerprint_raw(k, dgst_type, &ret, &dlen)) != 0)
49
	if ((r = sshkey_fingerprint_raw(k, dgst_alg, &ret, &dlen)) != 0)
51
		fatal("%s: %s", __func__, ssh_err(r));
50
		fatal("%s: %s", __func__, ssh_err(r));
52
	if (dlen > INT_MAX)
51
	if (dlen > INT_MAX)
53
		fatal("%s: giant len %zu", __func__, dlen);
52
		fatal("%s: giant len %zu", __func__, dlen);
(-)a/key.h (-1 / +1 lines)
Lines 67-73 void key_add_private(Key *); Link Here
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
(-)a/krl.c (-2 / +4 lines)
Lines 34-39 Link Here
34
#include "misc.h"
34
#include "misc.h"
35
#include "log.h"
35
#include "log.h"
36
#include "ssherr.h"
36
#include "ssherr.h"
37
#include "digest.h"
37
38
38
#include "krl.h"
39
#include "krl.h"
39
40
Lines 409-415 ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key) Link Here
409
	int r;
410
	int r;
410
411
411
	debug3("%s: revoke type %s by sha1", __func__, sshkey_type(key));
412
	debug3("%s: revoke type %s by sha1", __func__, sshkey_type(key));
412
	if ((r = sshkey_fingerprint_raw(key, SSH_FP_SHA1, &blob, &len)) != 0)
413
	if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1,
414
	    &blob, &len)) != 0)
413
		return r;
415
		return r;
414
	return revoke_blob(&krl->revoked_sha1s, blob, len);
416
	return revoke_blob(&krl->revoked_sha1s, blob, len);
415
}
417
}
Lines 1149-1155 is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) Link Here
1149
1151
1150
	/* Check explicitly revoked hashes first */
1152
	/* Check explicitly revoked hashes first */
1151
	memset(&rb, 0, sizeof(rb));
1153
	memset(&rb, 0, sizeof(rb));
1152
	if ((r = sshkey_fingerprint_raw(key, SSH_FP_SHA1,
1154
	if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1,
1153
	    &rb.blob, &rb.len)) != 0)
1155
	    &rb.blob, &rb.len)) != 0)
1154
		return r;
1156
		return r;
1155
	erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
1157
	erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
(-)a/readconf.c (+22 lines)
Lines 49-54 Link Here
49
#include "mac.h"
49
#include "mac.h"
50
#include "uidswap.h"
50
#include "uidswap.h"
51
#include "myproposal.h"
51
#include "myproposal.h"
52
#include "digest.h"
52
53
53
/* Format of the configuration file:
54
/* Format of the configuration file:
54
55
Lines 144-149 typedef enum { Link Here
144
	oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
145
	oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
145
	oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
146
	oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
146
	oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
147
	oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
148
	oFingerprintHash,
147
	oIgnoredUnknownOption, oDeprecated, oUnsupported
149
	oIgnoredUnknownOption, oDeprecated, oUnsupported
148
} OpCodes;
150
} OpCodes;
149
151
Lines 259-264 static struct { Link Here
259
	{ "streamlocalbindmask", oStreamLocalBindMask },
261
	{ "streamlocalbindmask", oStreamLocalBindMask },
260
	{ "streamlocalbindunlink", oStreamLocalBindUnlink },
262
	{ "streamlocalbindunlink", oStreamLocalBindUnlink },
261
	{ "revokedhostkeys", oRevokedHostKeys },
263
	{ "revokedhostkeys", oRevokedHostKeys },
264
	{ "fingerprinthash", oFingerprintHash },
262
	{ "ignoreunknown", oIgnoreUnknown },
265
	{ "ignoreunknown", oIgnoreUnknown },
263
266
264
	{ NULL, oBadOption }
267
	{ NULL, oBadOption }
Lines 1448-1453 parse_int: Link Here
1448
		charptr = &options->revoked_host_keys;
1451
		charptr = &options->revoked_host_keys;
1449
		goto parse_string;
1452
		goto parse_string;
1450
1453
1454
	case oFingerprintHash:
1455
		arg = strdelim(&s);
1456
		if (!arg || *arg == '\0')
1457
			fatal("%.200s line %d: Missing argument.",
1458
			    filename, linenum);
1459
		if ((value = ssh_digest_alg_by_name(arg)) == -1)
1460
			fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1461
			    filename, linenum, arg);
1462
		if (*activep)
1463
			options->fingerprint_hash = value;
1464
		break;
1465
1451
	case oDeprecated:
1466
	case oDeprecated:
1452
		debug("%s line %d: Deprecated option \"%s\"",
1467
		debug("%s line %d: Deprecated option \"%s\"",
1453
		    filename, linenum, keyword);
1468
		    filename, linenum, keyword);
Lines 1625-1630 initialize_options(Options * options) Link Here
1625
	options->canonicalize_fallback_local = -1;
1640
	options->canonicalize_fallback_local = -1;
1626
	options->canonicalize_hostname = -1;
1641
	options->canonicalize_hostname = -1;
1627
	options->revoked_host_keys = NULL;
1642
	options->revoked_host_keys = NULL;
1643
	options->fingerprint_hash = -1;
1628
}
1644
}
1629
1645
1630
/*
1646
/*
Lines 1800-1805 fill_default_options(Options * options) Link Here
1800
		options->canonicalize_fallback_local = 1;
1816
		options->canonicalize_fallback_local = 1;
1801
	if (options->canonicalize_hostname == -1)
1817
	if (options->canonicalize_hostname == -1)
1802
		options->canonicalize_hostname = SSH_CANONICALISE_NO;
1818
		options->canonicalize_hostname = SSH_CANONICALISE_NO;
1819
	if (options->fingerprint_hash == -1)
1820
		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
1821
1803
#define CLEAR_ON_NONE(v) \
1822
#define CLEAR_ON_NONE(v) \
1804
	do { \
1823
	do { \
1805
		if (option_clear_or_none(v)) { \
1824
		if (option_clear_or_none(v)) { \
Lines 2057-2062 fmt_intarg(OpCodes code, int val) Link Here
2057
		return fmt_multistate_int(val, multistate_requesttty);
2076
		return fmt_multistate_int(val, multistate_requesttty);
2058
	case oCanonicalizeHostname:
2077
	case oCanonicalizeHostname:
2059
		return fmt_multistate_int(val, multistate_canonicalizehostname);
2078
		return fmt_multistate_int(val, multistate_canonicalizehostname);
2079
	case oFingerprintHash:
2080
		return ssh_digest_alg_name(val);
2060
	case oProtocol:
2081
	case oProtocol:
2061
		switch (val) {
2082
		switch (val) {
2062
		case SSH_PROTO_1:
2083
		case SSH_PROTO_1:
Lines 2219-2224 dump_client_config(Options *o, const char *host) Link Here
2219
	dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2240
	dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2220
	dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2241
	dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2221
	dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2242
	dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2243
	dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2222
2244
2223
	/* Integer options */
2245
	/* Integer options */
2224
	dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2246
	dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
(-)a/readconf.h (+2 lines)
Lines 146-151 typedef struct { Link Here
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
(-)a/servconf.c (-1 / +21 lines)
Lines 50-55 Link Here
50
#include "hostfile.h"
50
#include "hostfile.h"
51
#include "auth.h"
51
#include "auth.h"
52
#include "myproposal.h"
52
#include "myproposal.h"
53
#include "digest.h"
53
54
54
static void add_listen_addr(ServerOptions *, char *, int);
55
static void add_listen_addr(ServerOptions *, char *, int);
55
static void add_one_listen_addr(ServerOptions *, char *, int);
56
static void add_one_listen_addr(ServerOptions *, char *, int);
Lines 148-153 initialize_server_options(ServerOptions *options) Link Here
148
	options->ip_qos_interactive = -1;
149
	options->ip_qos_interactive = -1;
149
	options->ip_qos_bulk = -1;
150
	options->ip_qos_bulk = -1;
150
	options->version_addendum = NULL;
151
	options->version_addendum = NULL;
152
	options->fingerprint_hash = -1;
151
}
153
}
152
154
153
void
155
void
Lines 296-301 fill_default_server_options(ServerOptions *options) Link Here
296
		options->fwd_opts.streamlocal_bind_mask = 0177;
298
		options->fwd_opts.streamlocal_bind_mask = 0177;
297
	if (options->fwd_opts.streamlocal_bind_unlink == -1)
299
	if (options->fwd_opts.streamlocal_bind_unlink == -1)
298
		options->fwd_opts.streamlocal_bind_unlink = 0;
300
		options->fwd_opts.streamlocal_bind_unlink = 0;
301
	if (options->fingerprint_hash == -1)
302
		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
299
	/* Turn privilege separation on by default */
303
	/* Turn privilege separation on by default */
300
	if (use_privsep == -1)
304
	if (use_privsep == -1)
301
		use_privsep = PRIVSEP_NOSANDBOX;
305
		use_privsep = PRIVSEP_NOSANDBOX;
Lines 332-338 typedef enum { Link Here
332
	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
336
	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
333
	sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
337
	sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
334
	sStreamLocalBindMask, sStreamLocalBindUnlink,
338
	sStreamLocalBindMask, sStreamLocalBindUnlink,
335
	sAllowStreamLocalForwarding,
339
	sAllowStreamLocalForwarding, sFingerprintHash,
336
	sDeprecated, sUnsupported
340
	sDeprecated, sUnsupported
337
} ServerOpCodes;
341
} ServerOpCodes;
338
342
Lines 451-456 static struct { Link Here
451
	{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
455
	{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
452
	{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
456
	{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
453
	{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
457
	{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
458
	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
454
	{ NULL, sBadOption, 0 }
459
	{ NULL, sBadOption, 0 }
455
};
460
};
456
461
Lines 1622-1627 process_server_config_line(ServerOptions *options, char *line, Link Here
1622
		intptr = &options->fwd_opts.streamlocal_bind_unlink;
1627
		intptr = &options->fwd_opts.streamlocal_bind_unlink;
1623
		goto parse_flag;
1628
		goto parse_flag;
1624
1629
1630
	case sFingerprintHash:
1631
		arg = strdelim(&cp);
1632
		if (!arg || *arg == '\0')
1633
			fatal("%.200s line %d: Missing argument.",
1634
			    filename, linenum);
1635
		if ((value = ssh_digest_alg_by_name(arg)) == -1)
1636
			fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1637
			    filename, linenum, arg);
1638
		if (*activep)
1639
			options->fingerprint_hash = value;
1640
		break;
1641
1625
	case sDeprecated:
1642
	case sDeprecated:
1626
		logit("%s line %d: Deprecated option %s",
1643
		logit("%s line %d: Deprecated option %s",
1627
		    filename, linenum, arg);
1644
		    filename, linenum, arg);
Lines 1864-1869 fmt_intarg(ServerOpCodes code, int val) Link Here
1864
		return fmt_multistate_int(val, multistate_tcpfwd);
1881
		return fmt_multistate_int(val, multistate_tcpfwd);
1865
	case sAllowStreamLocalForwarding:
1882
	case sAllowStreamLocalForwarding:
1866
		return fmt_multistate_int(val, multistate_tcpfwd);
1883
		return fmt_multistate_int(val, multistate_tcpfwd);
1884
	case sFingerprintHash:
1885
		return ssh_digest_alg_name(val);
1867
	case sProtocol:
1886
	case sProtocol:
1868
		switch (val) {
1887
		switch (val) {
1869
		case SSH_PROTO_1:
1888
		case SSH_PROTO_1:
Lines 2020-2025 dump_config(ServerOptions *o) Link Here
2020
	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
2039
	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
2021
	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2040
	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2022
	dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
2041
	dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
2042
	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2023
2043
2024
	/* string arguments */
2044
	/* string arguments */
2025
	dump_cfg_string(sPidFile, o->pid_file);
2045
	dump_cfg_string(sPidFile, o->pid_file);
(-)a/servconf.h (+2 lines)
Lines 183-188 typedef struct { Link Here
183
183
184
	u_int	num_auth_methods;
184
	u_int	num_auth_methods;
185
	char   *auth_methods[MAX_AUTH_METHODS];
185
	char   *auth_methods[MAX_AUTH_METHODS];
186
187
	int	fingerprint_hash;
186
}       ServerOptions;
188
}       ServerOptions;
187
189
188
/* Information about the incoming connection as used by Match */
190
/* Information about the incoming connection as used by Match */
(-)a/ssh-add.1 (+11 lines)
Lines 44-49 Link Here
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
Lines 95-100 Successful confirmation is signaled by a zero exit status from the Link Here
95
program, rather than text entered into the requester.
96
program, rather than text entered into the requester.
96
.It Fl D
97
.It Fl D
97
Deletes all identities from the agent.
98
Deletes all identities from the agent.
99
.It Fl E
100
Specifies the hash algorithm used when displaying key fingerprints.
101
Valid options are:
102
.Dq md5 ,
103
.Dq sha1 ,
104
.Dq sha256
105
and
106
.Dq sha512 .
107
The default is
108
.Dq sha256 .
98
.It Fl d
109
.It Fl d
99
Instead of adding identities, removes identities from the agent.
110
Instead of adding identities, removes identities from the agent.
100
If
111
If
(-)a/ssh-add.c (-3 / +11 lines)
Lines 59-64 Link Here
59
#include "pathnames.h"
59
#include "pathnames.h"
60
#include "misc.h"
60
#include "misc.h"
61
#include "ssherr.h"
61
#include "ssherr.h"
62
#include "digest.h"
62
63
63
/* argv0 */
64
/* argv0 */
64
extern char *__progname;
65
extern char *__progname;
Lines 73-78 static char *default_files[] = { Link Here
73
	NULL
74
	NULL
74
};
75
};
75
76
77
static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
78
76
/* Default lifetime (0 == forever) */
79
/* Default lifetime (0 == forever) */
77
static int lifetime = 0;
80
static int lifetime = 0;
78
81
Lines 334-341 list_identities(AuthenticationConnection *ac, int do_fp) Link Here
334
		    key = ssh_get_next_identity(ac, &comment, version)) {
337
		    key = ssh_get_next_identity(ac, &comment, version)) {
335
			had_identities = 1;
338
			had_identities = 1;
336
			if (do_fp) {
339
			if (do_fp) {
337
				fp = key_fingerprint(key, SSH_FP_MD5,
340
				fp = key_fingerprint(key, fingerprint_hash,
338
				    SSH_FP_HEX);
341
				    SSH_FP_DEFAULT);
339
				printf("%d %s %s (%s)\n",
342
				printf("%d %s %s (%s)\n",
340
				    key_size(key), fp, comment, key_type(key));
343
				    key_size(key), fp, comment, key_type(key));
341
				free(fp);
344
				free(fp);
Lines 437-444 main(int argc, char **argv) Link Here
437
		    "Could not open a connection to your authentication agent.\n");
440
		    "Could not open a connection to your authentication agent.\n");
438
		exit(2);
441
		exit(2);
439
	}
442
	}
440
	while ((ch = getopt(argc, argv, "klLcdDxXe:s:t:")) != -1) {
443
	while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:t:")) != -1) {
441
		switch (ch) {
444
		switch (ch) {
445
		case 'E':
446
			fingerprint_hash = ssh_digest_alg_by_name(optarg);
447
			if (fingerprint_hash == -1)
448
				fatal("Invalid hash algorithm \"%s\"", optarg);
449
			break;
442
		case 'k':
450
		case 'k':
443
			key_only = 1;
451
			key_only = 1;
444
			break;
452
			break;
(-)a/ssh-agent.1 (+11 lines)
Lines 44-49 Link Here
44
.Nm ssh-agent
44
.Nm ssh-agent
45
.Op Fl c | s
45
.Op Fl c | s
46
.Op Fl d
46
.Op Fl d
47
.Op Fl E Ar fingerprint_hash
47
.Op Fl a Ar bind_address
48
.Op Fl a Ar bind_address
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 ...
Lines 96-101 Debug mode. Link Here
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
101
Specifies the hash algorithm used when displaying key fingerprints.
102
Valid options are:
103
.Dq md5 ,
104
.Dq sha1 ,
105
.Dq sha256
106
and
107
.Dq sha512 .
108
The default is
109
.Dq sha256 .
99
.It Fl k
110
.It Fl k
100
Kill the current agent (given by the
111
Kill the current agent (given by the
101
.Ev SSH_AGENT_PID
112
.Ev SSH_AGENT_PID
(-)a/ssh-agent.c (-2 / +9 lines)
Lines 128-133 extern char *__progname; Link Here
128
/* Default lifetime in seconds (0 == forever) */
128
/* Default lifetime in seconds (0 == forever) */
129
static long lifetime = 0;
129
static long lifetime = 0;
130
130
131
static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
132
131
static void
133
static void
132
close_socket(SocketEntry *e)
134
close_socket(SocketEntry *e)
133
{
135
{
Lines 189-195 confirm_key(Identity *id) Link Here
189
	char *p;
191
	char *p;
190
	int ret = -1;
192
	int ret = -1;
191
193
192
	p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
194
	p = key_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT);
193
	if (ask_permission("Allow use of key %s?\nKey fingerprint %s.",
195
	if (ask_permission("Allow use of key %s?\nKey fingerprint %s.",
194
	    id->comment, p))
196
	    id->comment, p))
195
		ret = 0;
197
		ret = 0;
Lines 1043-1050 main(int ac, char **av) Link Here
1043
	OpenSSL_add_all_algorithms();
1045
	OpenSSL_add_all_algorithms();
1044
#endif
1046
#endif
1045
1047
1046
	while ((ch = getopt(ac, av, "cdksa:t:")) != -1) {
1048
	while ((ch = getopt(ac, av, "cdksE:a:t:")) != -1) {
1047
		switch (ch) {
1049
		switch (ch) {
1050
		case 'E':
1051
			fingerprint_hash = ssh_digest_alg_by_name(optarg);
1052
			if (fingerprint_hash == -1)
1053
				fatal("Invalid hash algorithm \"%s\"", optarg);
1054
			break;
1048
		case 'c':
1055
		case 'c':
1049
			if (s_flag)
1056
			if (s_flag)
1050
				usage();
1057
				usage();
(-)a/ssh-keygen.1 (+11 lines)
Lines 73-78 Link Here
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
Lines 269-274 When used in combination with Link Here
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
274
Specifies the hash algorithm used when displaying key fingerprints.
275
Valid options are:
276
.Dq md5 ,
277
.Dq sha1 ,
278
.Dq sha256
279
and
280
.Dq sha512 .
281
The default is
282
.Dq sha256 .
272
.It Fl e
283
.It Fl e
273
This option will read a private or public OpenSSH key file and
284
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
285
print to stdout the key in one of the formats specified by the
(-)a/ssh-keygen.c (-20 / +34 lines)
Lines 45-50 Link Here
45
#include "ssh2.h"
45
#include "ssh2.h"
46
#include "atomicio.h"
46
#include "atomicio.h"
47
#include "krl.h"
47
#include "krl.h"
48
#include "digest.h"
48
49
49
#ifdef ENABLE_PKCS11
50
#ifdef ENABLE_PKCS11
50
#include "ssh-pkcs11.h"
51
#include "ssh-pkcs11.h"
Lines 86-91 int show_cert = 0; Link Here
86
int print_fingerprint = 0;
87
int print_fingerprint = 0;
87
int print_bubblebabble = 0;
88
int print_bubblebabble = 0;
88
89
90
/* Hash algorithm to use for fingerprints. */
91
int fingerprint_hash = SSH_FP_HASH_DEFAULT;
92
89
/* The identity file name, given on the command line or entered by the user. */
93
/* The identity file name, given on the command line or entered by the user. */
90
char identity_file[1024];
94
char identity_file[1024];
91
int have_identity = 0;
95
int have_identity = 0;
Lines 737-747 do_download(struct passwd *pw) Link Here
737
	Key **keys = NULL;
741
	Key **keys = NULL;
738
	int i, nkeys;
742
	int i, nkeys;
739
	enum fp_rep rep;
743
	enum fp_rep rep;
740
	enum fp_type fptype;
744
	int fptype;
741
	char *fp, *ra;
745
	char *fp, *ra;
742
746
743
	fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
747
	fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
744
	rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
748
	rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
745
749
746
	pkcs11_init(0);
750
	pkcs11_init(0);
747
	nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys);
751
	nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys);
Lines 750-756 do_download(struct passwd *pw) Link Here
750
	for (i = 0; i < nkeys; i++) {
754
	for (i = 0; i < nkeys; i++) {
751
		if (print_fingerprint) {
755
		if (print_fingerprint) {
752
			fp = key_fingerprint(keys[i], fptype, rep);
756
			fp = key_fingerprint(keys[i], fptype, rep);
753
			ra = key_fingerprint(keys[i], SSH_FP_MD5,
757
			ra = key_fingerprint(keys[i], fingerprint_hash,
754
			    SSH_FP_RANDOMART);
758
			    SSH_FP_RANDOMART);
755
			printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]),
759
			printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]),
756
			    fp, key_type(keys[i]));
760
			    fp, key_type(keys[i]));
Lines 780-791 do_fingerprint(struct passwd *pw) Link Here
780
	char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;
784
	char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;
781
	int i, skip = 0, num = 0, invalid = 1;
785
	int i, skip = 0, num = 0, invalid = 1;
782
	enum fp_rep rep;
786
	enum fp_rep rep;
783
	enum fp_type fptype;
787
	int fptype;
784
	struct stat st;
788
	struct stat st;
785
789
786
	fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
790
	fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
787
	rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
791
	rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
788
789
	if (!have_identity)
792
	if (!have_identity)
790
		ask_filename(pw, "Enter file in which the key is");
793
		ask_filename(pw, "Enter file in which the key is");
791
	if (stat(identity_file, &st) < 0) {
794
	if (stat(identity_file, &st) < 0) {
Lines 795-801 do_fingerprint(struct passwd *pw) Link Here
795
	public = key_load_public(identity_file, &comment);
798
	public = key_load_public(identity_file, &comment);
796
	if (public != NULL) {
799
	if (public != NULL) {
797
		fp = key_fingerprint(public, fptype, rep);
800
		fp = key_fingerprint(public, fptype, rep);
798
		ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
801
		ra = key_fingerprint(public, fingerprint_hash,
802
		    SSH_FP_RANDOMART);
799
		printf("%u %s %s (%s)\n", key_size(public), fp, comment,
803
		printf("%u %s %s (%s)\n", key_size(public), fp, comment,
800
		    key_type(public));
804
		    key_type(public));
801
		if (log_level >= SYSLOG_LEVEL_VERBOSE)
805
		if (log_level >= SYSLOG_LEVEL_VERBOSE)
Lines 861-867 do_fingerprint(struct passwd *pw) Link Here
861
		}
865
		}
862
		comment = *cp ? cp : comment;
866
		comment = *cp ? cp : comment;
863
		fp = key_fingerprint(public, fptype, rep);
867
		fp = key_fingerprint(public, fptype, rep);
864
		ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
868
		ra = key_fingerprint(public, fingerprint_hash,
869
		    SSH_FP_RANDOMART);
865
		printf("%u %s %s (%s)\n", key_size(public), fp,
870
		printf("%u %s %s (%s)\n", key_size(public), fp,
866
		    comment ? comment : "no comment", key_type(public));
871
		    comment ? comment : "no comment", key_type(public));
867
		if (log_level >= SYSLOG_LEVEL_VERBOSE)
872
		if (log_level >= SYSLOG_LEVEL_VERBOSE)
Lines 979-991 printhost(FILE *f, const char *name, Key *public, int ca, int revoked, int hash) Link Here
979
{
984
{
980
	if (print_fingerprint) {
985
	if (print_fingerprint) {
981
		enum fp_rep rep;
986
		enum fp_rep rep;
982
		enum fp_type fptype;
987
		int fptype;
983
		char *fp, *ra;
988
		char *fp, *ra;
984
989
985
		fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
990
		fptype = print_bubblebabble ?
986
		rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
991
		    SSH_DIGEST_SHA1 : fingerprint_hash;
992
		rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
987
		fp = key_fingerprint(public, fptype, rep);
993
		fp = key_fingerprint(public, fptype, rep);
988
		ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
994
		ra = key_fingerprint(public, fingerprint_hash,
995
		    SSH_FP_RANDOMART);
989
		printf("%u %s %s (%s)\n", key_size(public), fp, name,
996
		printf("%u %s %s (%s)\n", key_size(public), fp, name,
990
		    key_type(public));
997
		    key_type(public));
991
		if (log_level >= SYSLOG_LEVEL_VERBOSE)
998
		if (log_level >= SYSLOG_LEVEL_VERBOSE)
Lines 1894-1902 do_show_cert(struct passwd *pw) Link Here
1894
		fatal("%s is not a certificate", identity_file);
1901
		fatal("%s is not a certificate", identity_file);
1895
	v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00;
1902
	v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00;
1896
1903
1897
	key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
1904
	key_fp = key_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT);
1898
	ca_fp = key_fingerprint(key->cert->signature_key,
1905
	ca_fp = key_fingerprint(key->cert->signature_key,
1899
	    SSH_FP_MD5, SSH_FP_HEX);
1906
	    fingerprint_hash, SSH_FP_DEFAULT);
1900
1907
1901
	printf("%s:\n", identity_file);
1908
	printf("%s:\n", identity_file);
1902
	printf("        Type: %s %s certificate\n", key_ssh_name(key),
1909
	printf("        Type: %s %s certificate\n", key_ssh_name(key),
Lines 2240-2248 main(int argc, char **argv) Link Here
2240
		exit(1);
2247
		exit(1);
2241
	}
2248
	}
2242
2249
2243
	/* Remaining characters: EUYdw */
2250
	/* Remaining characters: UYdw */
2244
	while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy"
2251
	while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy"
2245
	    "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) {
2252
	    "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:"
2253
	    "a:b:f:g:j:m:n:r:s:t:z:")) != -1) {
2246
		switch (opt) {
2254
		switch (opt) {
2247
		case 'A':
2255
		case 'A':
2248
			gen_all_hostkeys = 1;
2256
			gen_all_hostkeys = 1;
Lines 2253-2258 main(int argc, char **argv) Link Here
2253
				fatal("Bits has bad value %s (%s)",
2261
				fatal("Bits has bad value %s (%s)",
2254
					optarg, errstr);
2262
					optarg, errstr);
2255
			break;
2263
			break;
2264
		case 'E':
2265
			fingerprint_hash = ssh_digest_alg_by_name(optarg);
2266
			if (fingerprint_hash == -1)
2267
				fatal("Invalid hash algorithm \"%s\"", optarg);
2268
			break;
2256
		case 'F':
2269
		case 'F':
2257
			find_host = 1;
2270
			find_host = 1;
2258
			rr_hostname = optarg;
2271
			rr_hostname = optarg;
Lines 2684-2691 passphrase_again: Link Here
2684
	fclose(f);
2697
	fclose(f);
2685
2698
2686
	if (!quiet) {
2699
	if (!quiet) {
2687
		char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
2700
		char *fp = key_fingerprint(public, fingerprint_hash,
2688
		char *ra = key_fingerprint(public, SSH_FP_MD5,
2701
		    SSH_FP_DEFAULT);
2702
		char *ra = key_fingerprint(public, fingerprint_hash,
2689
		    SSH_FP_RANDOMART);
2703
		    SSH_FP_RANDOMART);
2690
		printf("Your public key has been saved in %s.\n",
2704
		printf("Your public key has been saved in %s.\n",
2691
		    identity_file);
2705
		    identity_file);
(-)a/ssh-keysign.c (-1 / +2 lines)
Lines 235-241 main(int argc, char **argv) Link Here
235
		}
235
		}
236
	}
236
	}
237
	if (!found) {
237
	if (!found) {
238
		fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
238
		fp = key_fingerprint(key, options.fingerprint_hash,
239
		    SSH_FP_DEFAULT);
239
		fatal("no matching hostkey found for key %s %s",
240
		fatal("no matching hostkey found for key %s %s",
240
		    key_type(key), fp);
241
		    key_type(key), fp);
241
	}
242
	}
(-)a/ssh.1 (-1 / +1 lines)
Lines 1091-1097 Fingerprints can be determined using Link Here
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 .
(-)a/ssh_config.5 (-2 / +12 lines)
Lines 638-643 or Link Here
638
.Dq no .
638
.Dq no .
639
The default is
639
The default is
640
.Dq no .
640
.Dq no .
641
.It Cm FingerprintHash
642
Specifies the hash algorithm used when displaying key fingerprints.
643
Valid options are:
644
.Dq md5 ,
645
.Dq sha1 ,
646
.Dq sha256
647
and
648
.Dq sha512 .
649
The default is
650
.Dq sha256 .
641
.It Cm ForwardAgent
651
.It Cm ForwardAgent
642
Specifies whether the connection to the authentication agent (if any)
652
Specifies whether the connection to the authentication agent (if any)
643
will be forwarded to the remote machine.
653
will be forwarded to the remote machine.
Lines 1519-1530 See also VERIFYING HOST KEYS in Link Here
1519
If this flag is set to
1529
If this flag is set to
1520
.Dq yes ,
1530
.Dq yes ,
1521
an ASCII art representation of the remote host key fingerprint is
1531
an ASCII art representation of the remote host key fingerprint is
1522
printed in addition to the hex fingerprint string at login and
1532
printed in addition to the fingerprint string at login and
1523
for unknown host keys.
1533
for unknown host keys.
1524
If this flag is set to
1534
If this flag is set to
1525
.Dq no ,
1535
.Dq no ,
1526
no fingerprint strings are printed at login and
1536
no fingerprint strings are printed at login and
1527
only the hex fingerprint string will be printed for unknown host keys.
1537
only the fingerprint string will be printed for unknown host keys.
1528
The default is
1538
The default is
1529
.Dq no .
1539
.Dq no .
1530
.It Cm XAuthLocation
1540
.It Cm XAuthLocation
(-)a/sshconnect.c (-10 / +15 lines)
Lines 892-900 check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, Link Here
892
				    "key for IP address '%.128s' to the list "
892
				    "key for IP address '%.128s' to the list "
893
				    "of known hosts.", type, ip);
893
				    "of known hosts.", type, ip);
894
		} else if (options.visual_host_key) {
894
		} else if (options.visual_host_key) {
895
			fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
895
			fp = key_fingerprint(host_key,
896
			ra = key_fingerprint(host_key, SSH_FP_MD5,
896
			    options.fingerprint_hash, SSH_FP_DEFAULT);
897
			    SSH_FP_RANDOMART);
897
			ra = key_fingerprint(host_key,
898
			    options.fingerprint_hash, SSH_FP_RANDOMART);
898
			logit("Host key fingerprint is %s\n%s\n", fp, ra);
899
			logit("Host key fingerprint is %s\n%s\n", fp, ra);
899
			free(ra);
900
			free(ra);
900
			free(fp);
901
			free(fp);
Lines 933-941 check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, Link Here
933
			else
934
			else
934
				snprintf(msg1, sizeof(msg1), ".");
935
				snprintf(msg1, sizeof(msg1), ".");
935
			/* The default */
936
			/* The default */
936
			fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
937
			fp = key_fingerprint(host_key,
937
			ra = key_fingerprint(host_key, SSH_FP_MD5,
938
			    options.fingerprint_hash, SSH_FP_DEFAULT);
938
			    SSH_FP_RANDOMART);
939
			ra = key_fingerprint(host_key,
940
			    options.fingerprint_hash, SSH_FP_RANDOMART);
939
			msg2[0] = '\0';
941
			msg2[0] = '\0';
940
			if (options.verify_host_key_dns) {
942
			if (options.verify_host_key_dns) {
941
				if (matching_host_key_dns)
943
				if (matching_host_key_dns)
Lines 1200-1206 verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) Link Here
1200
	struct sshkey *plain = NULL;
1202
	struct sshkey *plain = NULL;
1201
1203
1202
	if ((fp = sshkey_fingerprint(host_key,
1204
	if ((fp = sshkey_fingerprint(host_key,
1203
	    SSH_FP_MD5, SSH_FP_HEX)) == NULL) {
1205
	    options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
1204
		error("%s: fingerprint host key: %s", __func__, ssh_err(r));
1206
		error("%s: fingerprint host key: %s", __func__, ssh_err(r));
1205
		r = -1;
1207
		r = -1;
1206
		goto out;
1208
		goto out;
Lines 1361-1368 show_other_keys(struct hostkeys *hostkeys, Key *key) Link Here
1361
			continue;
1363
			continue;
1362
		if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found))
1364
		if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found))
1363
			continue;
1365
			continue;
1364
		fp = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_HEX);
1366
		fp = key_fingerprint(found->key,
1365
		ra = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_RANDOMART);
1367
		    options.fingerprint_hash, SSH_FP_DEFAULT);
1368
		ra = key_fingerprint(found->key,
1369
		    options.fingerprint_hash, SSH_FP_RANDOMART);
1366
		logit("WARNING: %s key found for host %s\n"
1370
		logit("WARNING: %s key found for host %s\n"
1367
		    "in %s:%lu\n"
1371
		    "in %s:%lu\n"
1368
		    "%s key fingerprint %s.",
1372
		    "%s key fingerprint %s.",
Lines 1383-1389 warn_changed_key(Key *host_key) Link Here
1383
{
1387
{
1384
	char *fp;
1388
	char *fp;
1385
1389
1386
	fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
1390
	fp = key_fingerprint(host_key, options.fingerprint_hash,
1391
	    SSH_FP_DEFAULT);
1387
1392
1388
	error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1393
	error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1389
	error("@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @");
1394
	error("@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @");
(-)a/sshconnect2.c (-2 / +2 lines)
Lines 576-582 input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) Link Here
576
		    key->type, pktype);
576
		    key->type, pktype);
577
		goto done;
577
		goto done;
578
	}
578
	}
579
	fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
579
	fp = key_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT);
580
	debug2("input_userauth_pk_ok: fp %s", fp);
580
	debug2("input_userauth_pk_ok: fp %s", fp);
581
	free(fp);
581
	free(fp);
582
582
Lines 985-991 sign_and_send_pubkey(Authctxt *authctxt, Identity *id) Link Here
985
	int have_sig = 1;
985
	int have_sig = 1;
986
	char *fp;
986
	char *fp;
987
987
988
	fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
988
	fp = key_fingerprint(id->key, options.fingerprint_hash, SSH_FP_DEFAULT);
989
	debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp);
989
	debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp);
990
	free(fp);
990
	free(fp);
991
991
(-)a/sshd_config.5 (+11 lines)
Lines 486-491 and finally Link Here
486
See PATTERNS in
486
See PATTERNS in
487
.Xr ssh_config 5
487
.Xr ssh_config 5
488
for more information on patterns.
488
for more information on patterns.
489
.It Cm FingerprintHash
490
Specifies the hash algorithm used when logging key fingerprints.
491
Valid options are:
492
.Dq md5 ,
493
.Dq sha1 ,
494
.Dq sha256
495
and
496
.Dq sha512 .
497
The default is
498
.Dq sha256 .
499
.Pp
489
.It Cm ForceCommand
500
.It Cm ForceCommand
490
Forces the execution of the command specified by
501
Forces the execution of the command specified by
491
.Cm ForceCommand ,
502
.Cm ForceCommand ,
(-)a/sshkey.c (-37 / +75 lines)
Lines 27-32 Link Here
27
27
28
#include <sys/param.h>
28
#include <sys/param.h>
29
#include <sys/types.h>
29
#include <sys/types.h>
30
#include <netinet/in.h>
30
31
31
#include <openssl/evp.h>
32
#include <openssl/evp.h>
32
#include <openssl/err.h>
33
#include <openssl/err.h>
Lines 38-43 Link Here
38
#include <stdio.h>
39
#include <stdio.h>
39
#include <string.h>
40
#include <string.h>
40
#include <util.h>
41
#include <util.h>
42
#include <resolv.h>
41
43
42
#include "ssh2.h"
44
#include "ssh2.h"
43
#include "ssherr.h"
45
#include "ssherr.h"
Lines 826-854 sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp) Link Here
826
}
828
}
827
829
828
int
830
int
829
sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type,
831
sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg,
830
    u_char **retp, size_t *lenp)
832
    u_char **retp, size_t *lenp)
831
{
833
{
832
	u_char *blob = NULL, *ret = NULL;
834
	u_char *blob = NULL, *ret = NULL;
833
	size_t blob_len = 0;
835
	size_t blob_len = 0;
834
	int hash_alg = -1, r = SSH_ERR_INTERNAL_ERROR;
836
	int r = SSH_ERR_INTERNAL_ERROR;
835
837
836
	if (retp != NULL)
838
	if (retp != NULL)
837
		*retp = NULL;
839
		*retp = NULL;
838
	if (lenp != NULL)
840
	if (lenp != NULL)
839
		*lenp = 0;
841
		*lenp = 0;
840
842
	if (ssh_digest_bytes(dgst_alg) == 0) {
841
	switch (dgst_type) {
842
	case SSH_FP_MD5:
843
		hash_alg = SSH_DIGEST_MD5;
844
		break;
845
	case SSH_FP_SHA1:
846
		hash_alg = SSH_DIGEST_SHA1;
847
		break;
848
	case SSH_FP_SHA256:
849
		hash_alg = SSH_DIGEST_SHA256;
850
		break;
851
	default:
852
		r = SSH_ERR_INVALID_ARGUMENT;
843
		r = SSH_ERR_INVALID_ARGUMENT;
853
		goto out;
844
		goto out;
854
	}
845
	}
Lines 873-879 sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, Link Here
873
		r = SSH_ERR_ALLOC_FAIL;
864
		r = SSH_ERR_ALLOC_FAIL;
874
		goto out;
865
		goto out;
875
	}
866
	}
876
	if ((r = ssh_digest_memory(hash_alg, blob, blob_len,
867
	if ((r = ssh_digest_memory(dgst_alg, blob, blob_len,
877
	    ret, SSH_DIGEST_MAX_LENGTH)) != 0)
868
	    ret, SSH_DIGEST_MAX_LENGTH)) != 0)
878
		goto out;
869
		goto out;
879
	/* success */
870
	/* success */
Lines 882-888 sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, Link Here
882
		ret = NULL;
873
		ret = NULL;
883
	}
874
	}
884
	if (lenp != NULL)
875
	if (lenp != NULL)
885
		*lenp = ssh_digest_bytes(hash_alg);
876
		*lenp = ssh_digest_bytes(dgst_alg);
886
	r = 0;
877
	r = 0;
887
 out:
878
 out:
888
	free(ret);
879
	free(ret);
Lines 894-914 sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, Link Here
894
}
885
}
895
886
896
static char *
887
static char *
897
fingerprint_hex(u_char *dgst_raw, size_t dgst_raw_len)
888
fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
898
{
889
{
899
	char *retval;
890
	char *ret;
900
	size_t i;
891
	size_t plen = strlen(alg) + 1;
892
	size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1;
893
	int r;
901
894
902
	if ((retval = calloc(1, dgst_raw_len * 3 + 1)) == NULL)
895
	if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL)
903
		return NULL;
896
		return NULL;
897
	strlcpy(ret, alg, rlen);
898
	strlcat(ret, ":", rlen);
899
	if (dgst_raw_len == 0)
900
		return ret;
901
	if ((r = b64_ntop(dgst_raw, dgst_raw_len,
902
	    ret + plen, rlen - plen)) == -1) {
903
		explicit_bzero(ret, rlen);
904
		free(ret);
905
		return NULL;
906
	}
907
	/* Trim padding characters from end */
908
	ret[strcspn(ret, "=")] = '\0';
909
	return ret;
910
}
911
912
static char *
913
fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
914
{
915
	char *retval, hex[5];
916
	size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2;
917
918
	if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL)
919
		return NULL;
920
	strlcpy(retval, alg, rlen);
921
	strlcat(retval, ":", rlen);
904
	for (i = 0; i < dgst_raw_len; i++) {
922
	for (i = 0; i < dgst_raw_len; i++) {
905
		char hex[4];
923
		snprintf(hex, sizeof(hex), "%s%02x",
906
		snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
924
		    i > 0 ? ":" : "", dgst_raw[i]);
907
		strlcat(retval, hex, dgst_raw_len * 3 + 1);
925
		strlcat(retval, hex, rlen);
908
	}
926
	}
909
910
	/* Remove the trailing ':' character */
911
	retval[(dgst_raw_len * 3) - 1] = '\0';
912
	return retval;
927
	return retval;
913
}
928
}
914
929
Lines 994-1000 fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len) Link Here
994
#define	FLDSIZE_Y	(FLDBASE + 1)
1009
#define	FLDSIZE_Y	(FLDBASE + 1)
995
#define	FLDSIZE_X	(FLDBASE * 2 + 1)
1010
#define	FLDSIZE_X	(FLDBASE * 2 + 1)
996
static char *
1011
static char *
997
fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len,
1012
fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len,
998
    const struct sshkey *k)
1013
    const struct sshkey *k)
999
{
1014
{
1000
	/*
1015
	/*
Lines 1002-1010 fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, Link Here
1002
	 * intersects with itself.  Matter of taste.
1017
	 * intersects with itself.  Matter of taste.
1003
	 */
1018
	 */
1004
	char	*augmentation_string = " .o+=*BOX@%&#/^SE";
1019
	char	*augmentation_string = " .o+=*BOX@%&#/^SE";
1005
	char	*retval, *p, title[FLDSIZE_X];
1020
	char	*retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X];
1006
	u_char	 field[FLDSIZE_X][FLDSIZE_Y];
1021
	u_char	 field[FLDSIZE_X][FLDSIZE_Y];
1007
	size_t	 i, tlen;
1022
	size_t	 i, tlen, hlen;
1008
	u_int	 b;
1023
	u_int	 b;
1009
	int	 x, y, r;
1024
	int	 x, y, r;
1010
	size_t	 len = strlen(augmentation_string) - 1;
1025
	size_t	 len = strlen(augmentation_string) - 1;
Lines 1049-1056 fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, Link Here
1049
		sshkey_type(k), sshkey_size(k));
1064
		sshkey_type(k), sshkey_size(k));
1050
	/* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */
1065
	/* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */
1051
	if (r < 0 || r > (int)sizeof(title))
1066
	if (r < 0 || r > (int)sizeof(title))
1052
		snprintf(title, sizeof(title), "[%s]", sshkey_type(k));
1067
		r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k));
1053
	tlen = strlen(title);
1068
	tlen = (r <= 0) ? 0 : strlen(title);
1069
1070
	/* assemble hash ID. */
1071
	r = snprintf(hash, sizeof(hash), "[%s]", alg);
1072
	hlen = (r <= 0) ? 0 : strlen(hash);
1054
1073
1055
	/* output upper border */
1074
	/* output upper border */
1056
	p = retval;
1075
	p = retval;
Lines 1059-1065 fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, Link Here
1059
		*p++ = '-';
1078
		*p++ = '-';
1060
	memcpy(p, title, tlen);
1079
	memcpy(p, title, tlen);
1061
	p += tlen;
1080
	p += tlen;
1062
	for (i = p - retval - 1; i < FLDSIZE_X; i++)
1081
	for (i += tlen; i < FLDSIZE_X; i++)
1063
		*p++ = '-';
1082
		*p++ = '-';
1064
	*p++ = '+';
1083
	*p++ = '+';
1065
	*p++ = '\n';
1084
	*p++ = '\n';
Lines 1075-1081 fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, Link Here
1075
1094
1076
	/* output lower border */
1095
	/* output lower border */
1077
	*p++ = '+';
1096
	*p++ = '+';
1078
	for (i = 0; i < FLDSIZE_X; i++)
1097
	for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++)
1098
		*p++ = '-';
1099
	memcpy(p, hash, hlen);
1100
	p += hlen;
1101
	for (i += hlen; i < FLDSIZE_X; i++)
1079
		*p++ = '-';
1102
		*p++ = '-';
1080
	*p++ = '+';
1103
	*p++ = '+';
1081
1104
Lines 1083-1106 fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, Link Here
1083
}
1106
}
1084
1107
1085
char *
1108
char *
1086
sshkey_fingerprint(const struct sshkey *k, enum sshkey_fp_type dgst_type,
1109
sshkey_fingerprint(const struct sshkey *k, int dgst_alg,
1087
    enum sshkey_fp_rep dgst_rep)
1110
    enum sshkey_fp_rep dgst_rep)
1088
{
1111
{
1089
	char *retval = NULL;
1112
	char *retval = NULL;
1090
	u_char *dgst_raw;
1113
	u_char *dgst_raw;
1091
	size_t dgst_raw_len;
1114
	size_t dgst_raw_len;
1092
1115
1093
	if (sshkey_fingerprint_raw(k, dgst_type, &dgst_raw, &dgst_raw_len) != 0)
1116
	if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0)
1094
		return NULL;
1117
		return NULL;
1095
	switch (dgst_rep) {
1118
	switch (dgst_rep) {
1119
	case SSH_FP_DEFAULT:
1120
		if (dgst_alg == SSH_DIGEST_MD5) {
1121
			retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
1122
			    dgst_raw, dgst_raw_len);
1123
		} else {
1124
			retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
1125
			    dgst_raw, dgst_raw_len);
1126
		}
1127
		break;
1096
	case SSH_FP_HEX:
1128
	case SSH_FP_HEX:
1097
		retval = fingerprint_hex(dgst_raw, dgst_raw_len);
1129
		retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
1130
		    dgst_raw, dgst_raw_len);
1131
		break;
1132
	case SSH_FP_BASE64:
1133
		retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
1134
		    dgst_raw, dgst_raw_len);
1098
		break;
1135
		break;
1099
	case SSH_FP_BUBBLEBABBLE:
1136
	case SSH_FP_BUBBLEBABBLE:
1100
		retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
1137
		retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
1101
		break;
1138
		break;
1102
	case SSH_FP_RANDOMART:
1139
	case SSH_FP_RANDOMART:
1103
		retval = fingerprint_randomart(dgst_raw, dgst_raw_len, k);
1140
		retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg),
1141
		    dgst_raw, dgst_raw_len, k);
1104
		break;
1142
		break;
1105
	default:
1143
	default:
1106
		explicit_bzero(dgst_raw, dgst_raw_len);
1144
		explicit_bzero(dgst_raw, dgst_raw_len);
(-)a/sshkey.h (-8 / +6 lines)
Lines 61-76 enum sshkey_types { Link Here
61
	KEY_UNSPEC
61
	KEY_UNSPEC
62
};
62
};
63
63
64
/* Fingerprint hash algorithms */
64
/* Default fingerprint hash */
65
enum sshkey_fp_type {
65
#define SSH_FP_HASH_DEFAULT	SSH_DIGEST_SHA256
66
	SSH_FP_SHA1,
67
	SSH_FP_MD5,
68
	SSH_FP_SHA256
69
};
70
66
71
/* Fingerprint representation formats */
67
/* Fingerprint representation formats */
72
enum sshkey_fp_rep {
68
enum sshkey_fp_rep {
69
	SSH_FP_DEFAULT = 0,
73
	SSH_FP_HEX,
70
	SSH_FP_HEX,
71
	SSH_FP_BASE64,
74
	SSH_FP_BUBBLEBABBLE,
72
	SSH_FP_BUBBLEBABBLE,
75
	SSH_FP_RANDOMART
73
	SSH_FP_RANDOMART
76
};
74
};
Lines 118-126 int sshkey_equal_public(const struct sshkey *, Link Here
118
    const struct sshkey *);
116
    const struct sshkey *);
119
int		 sshkey_equal(const struct sshkey *, const struct sshkey *);
117
int		 sshkey_equal(const struct sshkey *, const struct sshkey *);
120
char		*sshkey_fingerprint(const struct sshkey *,
118
char		*sshkey_fingerprint(const struct sshkey *,
121
    enum sshkey_fp_type, enum sshkey_fp_rep);
119
    int, enum sshkey_fp_rep);
122
int		 sshkey_fingerprint_raw(const struct sshkey *k,
120
int		 sshkey_fingerprint_raw(const struct sshkey *k,
123
    enum sshkey_fp_type dgst_type, u_char **retp, size_t *lenp);
121
    int, u_char **retp, size_t *lenp);
124
const char	*sshkey_type(const struct sshkey *);
122
const char	*sshkey_type(const struct sshkey *);
125
const char	*sshkey_cert_type(const struct sshkey *);
123
const char	*sshkey_cert_type(const struct sshkey *);
126
int		 sshkey_write(const struct sshkey *, FILE *);
124
int		 sshkey_write(const struct sshkey *, FILE *);

Return to bug 1872