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

Collapse All | Expand All

(-)a/PROTOCOL.certkeys (-3 / +14 lines)
Lines 25-30 raw user keys. The ssh client will support automatic verification of Link Here
25
acceptance of certified host keys, by adding a similar ability to
25
acceptance of certified host keys, by adding a similar ability to
26
specify CA keys in ~/.ssh/known_hosts.
26
specify CA keys in ~/.ssh/known_hosts.
27
27
28
All certificate types include certification information along with the
29
public key that is used to sign challenges. In OpenSSH, ssh-keygen
30
performs the CA signing operation.
31
28
Certified keys are represented using new key types:
32
Certified keys are represented using new key types:
29
33
30
    ssh-rsa-cert-v01@openssh.com
34
    ssh-rsa-cert-v01@openssh.com
Lines 33-41 Certified keys are represented using new key types: Link Here
33
    ecdsa-sha2-nistp384-cert-v01@openssh.com
37
    ecdsa-sha2-nistp384-cert-v01@openssh.com
34
    ecdsa-sha2-nistp521-cert-v01@openssh.com
38
    ecdsa-sha2-nistp521-cert-v01@openssh.com
35
39
36
These include certification information along with the public key
40
Two additional types exist for RSA certificates to force use of
37
that is used to sign challenges. ssh-keygen performs the CA signing
41
SHA-2 signatures (SHA-256 and SHA-512 respectively):
38
operation.
42
43
    rsa-sha2-256-cert-v01@openssh.com
44
    rsa-sha2-512-cert-v01@openssh.com
45
46
These RSA/SHA-2 types should not appear in keys at rest or transmitted
47
on their wire, but do appear in the "public key algorithm name" field
48
of a "publickey" SSH_MSG_USERAUTH_REQUEST to indicate that the
49
signature will use the specified algorithm.
39
50
40
Protocol extensions
51
Protocol extensions
41
-------------------
52
-------------------
(-)a/auth2-hostbased.c (-2 / +1 lines)
Lines 110-117 userauth_hostbased(struct ssh *ssh) Link Here
110
		    "signature format");
110
		    "signature format");
111
		goto done;
111
		goto done;
112
	}
112
	}
113
	if (match_pattern_list(sshkey_ssh_name(key),
113
	if (match_pattern_list(pkalg, options.hostbased_key_types, 0) != 1) {
114
	    options.hostbased_key_types, 0) != 1) {
115
		logit("%s: key type %s not in HostbasedAcceptedKeyTypes",
114
		logit("%s: key type %s not in HostbasedAcceptedKeyTypes",
116
		    __func__, sshkey_type(key));
115
		    __func__, sshkey_type(key));
117
		goto done;
116
		goto done;
(-)a/auth2-pubkey.c (-5 / +6 lines)
Lines 106-112 userauth_pubkey(struct ssh *ssh) Link Here
106
	pktype = sshkey_type_from_name(pkalg);
106
	pktype = sshkey_type_from_name(pkalg);
107
	if (pktype == KEY_UNSPEC) {
107
	if (pktype == KEY_UNSPEC) {
108
		/* this is perfectly legal */
108
		/* this is perfectly legal */
109
		logit("%s: unsupported public key algorithm: %s",
109
		verbose("%s: unsupported public key algorithm: %s",
110
		    __func__, pkalg);
110
		    __func__, pkalg);
111
		goto done;
111
		goto done;
112
	}
112
	}
Lines 133-140 userauth_pubkey(struct ssh *ssh) Link Here
133
		logit("refusing previously-used %s key", sshkey_type(key));
133
		logit("refusing previously-used %s key", sshkey_type(key));
134
		goto done;
134
		goto done;
135
	}
135
	}
136
	if (match_pattern_list(sshkey_ssh_name(key),
136
	if (match_pattern_list(pkalg, options.pubkey_key_types, 0) != 1) {
137
	    options.pubkey_key_types, 0) != 1) {
138
		logit("%s: key type %s not in PubkeyAcceptedKeyTypes",
137
		logit("%s: key type %s not in PubkeyAcceptedKeyTypes",
139
		    __func__, sshkey_ssh_name(key));
138
		    __func__, sshkey_ssh_name(key));
140
		goto done;
139
		goto done;
Lines 185-192 userauth_pubkey(struct ssh *ssh) Link Here
185
		/* test for correct signature */
184
		/* test for correct signature */
186
		authenticated = 0;
185
		authenticated = 0;
187
		if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) &&
186
		if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) &&
188
		    PRIVSEP(sshkey_verify(key, sig, slen, sshbuf_ptr(b),
187
		    PRIVSEP(sshkey_verify(key, sig, slen,
189
		    sshbuf_len(b), NULL, ssh->compat)) == 0) {
188
		    sshbuf_ptr(b), sshbuf_len(b),
189
		    (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL,
190
		    ssh->compat)) == 0) {
190
			authenticated = 1;
191
			authenticated = 1;
191
		}
192
		}
192
		sshbuf_free(b);
193
		sshbuf_free(b);
(-)a/authfd.c (-10 / +15 lines)
Lines 341-350 ssh_agent_sign(int sock, const struct sshkey *key, Link Here
341
    const u_char *data, size_t datalen, const char *alg, u_int compat)
341
    const u_char *data, size_t datalen, const char *alg, u_int compat)
342
{
342
{
343
	struct sshbuf *msg;
343
	struct sshbuf *msg;
344
	u_char *blob = NULL, type;
344
	u_char *sig = NULL, type = 0;
345
	size_t blen = 0, len = 0;
345
	size_t len = 0;
346
	u_int flags = 0;
346
	u_int flags = 0;
347
	int r = SSH_ERR_INTERNAL_ERROR;
347
	int r = SSH_ERR_INTERNAL_ERROR;
348
	char *sigtype = NULL;
348
349
349
	*sigp = NULL;
350
	*sigp = NULL;
350
	*lenp = 0;
351
	*lenp = 0;
Lines 353-363 ssh_agent_sign(int sock, const struct sshkey *key, Link Here
353
		return SSH_ERR_INVALID_ARGUMENT;
354
		return SSH_ERR_INVALID_ARGUMENT;
354
	if ((msg = sshbuf_new()) == NULL)
355
	if ((msg = sshbuf_new()) == NULL)
355
		return SSH_ERR_ALLOC_FAIL;
356
		return SSH_ERR_ALLOC_FAIL;
356
	if ((r = sshkey_to_blob(key, &blob, &blen)) != 0)
357
		goto out;
358
	flags |= agent_encode_alg(key, alg);
357
	flags |= agent_encode_alg(key, alg);
359
	if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
358
	if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
360
	    (r = sshbuf_put_string(msg, blob, blen)) != 0 ||
359
	    (r = sshkey_puts(key, msg)) != 0 ||
361
	    (r = sshbuf_put_string(msg, data, datalen)) != 0 ||
360
	    (r = sshbuf_put_string(msg, data, datalen)) != 0 ||
362
	    (r = sshbuf_put_u32(msg, flags)) != 0)
361
	    (r = sshbuf_put_u32(msg, flags)) != 0)
363
		goto out;
362
		goto out;
Lines 372-386 ssh_agent_sign(int sock, const struct sshkey *key, Link Here
372
		r = SSH_ERR_INVALID_FORMAT;
371
		r = SSH_ERR_INVALID_FORMAT;
373
		goto out;
372
		goto out;
374
	}
373
	}
375
	if ((r = sshbuf_get_string(msg, sigp, &len)) != 0)
374
	if ((r = sshbuf_get_string(msg, &sig, &len)) != 0 ||
375
	    (r = sshkey_sigtype(sig, len, &sigtype)) != 0)
376
		goto out;
376
		goto out;
377
	/* Check what we actually got back from the agent. */
378
	if ((r = sshkey_check_sigtype(sig, len, alg)) != 0)
379
		goto out;
380
	/* success */
381
	*sigp = sig;
377
	*lenp = len;
382
	*lenp = len;
383
	sig = NULL;
384
	len = 0;
378
	r = 0;
385
	r = 0;
379
 out:
386
 out:
380
	if (blob != NULL) {
387
	freezero(sig, len);
381
		explicit_bzero(blob, blen);
388
	free(sigtype);
382
		free(blob);
383
	}
384
	sshbuf_free(msg);
389
	sshbuf_free(msg);
385
	return r;
390
	return r;
386
}
391
}
(-)a/compat.c (-7 / +18 lines)
Lines 50-65 compat_datafellows(const char *version) Link Here
50
	} check[] = {
50
	} check[] = {
51
		{ "OpenSSH_2.*,"
51
		{ "OpenSSH_2.*,"
52
		  "OpenSSH_3.0*,"
52
		  "OpenSSH_3.0*,"
53
		  "OpenSSH_3.1*",	SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
53
		  "OpenSSH_3.1*",	SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR|
54
		{ "OpenSSH_3.*",	SSH_OLD_FORWARD_ADDR },
54
					SSH_BUG_SIGTYPE},
55
		{ "Sun_SSH_1.0*",	SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
55
		{ "OpenSSH_3.*",	SSH_OLD_FORWARD_ADDR|SSH_BUG_SIGTYPE },
56
		{ "Sun_SSH_1.0*",	SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
57
					SSH_BUG_SIGTYPE},
56
		{ "OpenSSH_2*,"
58
		{ "OpenSSH_2*,"
57
		  "OpenSSH_3*,"
59
		  "OpenSSH_3*,"
58
		  "OpenSSH_4*",		0 },
60
		  "OpenSSH_4*",		SSH_BUG_SIGTYPE },
59
		{ "OpenSSH_5*",		SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT},
61
		{ "OpenSSH_5*",		SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT|
60
		{ "OpenSSH_6.6.1*",	SSH_NEW_OPENSSH},
62
					SSH_BUG_SIGTYPE},
63
		{ "OpenSSH_6.6.1*",	SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE},
61
		{ "OpenSSH_6.5*,"
64
		{ "OpenSSH_6.5*,"
62
		  "OpenSSH_6.6*",	SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD},
65
		  "OpenSSH_6.6*",	SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD|
66
					SSH_BUG_SIGTYPE},
67
		{ "OpenSSH_7.0*,"
68
		  "OpenSSH_7.1*,"
69
		  "OpenSSH_7.2*,"
70
		  "OpenSSH_7.3*,"
71
		  "OpenSSH_7.4*,"
72
		  "OpenSSH_7.5*,"
73
		  "OpenSSH_7.6*",	SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE},
63
		{ "OpenSSH*",		SSH_NEW_OPENSSH },
74
		{ "OpenSSH*",		SSH_NEW_OPENSSH },
64
		{ "*MindTerm*",		0 },
75
		{ "*MindTerm*",		0 },
65
		{ "3.0.*",		SSH_BUG_DEBUG },
76
		{ "3.0.*",		SSH_BUG_DEBUG },
(-)a/compat.h (-1 / +1 lines)
Lines 33-39 Link Here
33
#define	SSH_PROTO_2		0x04
33
#define	SSH_PROTO_2		0x04
34
34
35
#define SSH_BUG_UTF8TTYMODE	0x00000001
35
#define SSH_BUG_UTF8TTYMODE	0x00000001
36
/* #define unused		0x00000002 */
36
#define SSH_BUG_SIGTYPE		0x00000002
37
/* #define unused		0x00000004 */
37
/* #define unused		0x00000004 */
38
/* #define unused		0x00000008 */
38
/* #define unused		0x00000008 */
39
#define SSH_OLD_SESSIONID	0x00000010
39
#define SSH_OLD_SESSIONID	0x00000010
(-)a/kex.c (+14 lines)
Lines 330-335 kex_send_ext_info(struct ssh *ssh) Link Here
330
330
331
	if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
331
	if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
332
		return SSH_ERR_ALLOC_FAIL;
332
		return SSH_ERR_ALLOC_FAIL;
333
	/* XXX filter algs list by allowed pubkey/hostbased types */
333
	if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
334
	if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
334
	    (r = sshpkt_put_u32(ssh, 1)) != 0 ||
335
	    (r = sshpkt_put_u32(ssh, 1)) != 0 ||
335
	    (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
336
	    (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
Lines 389-394 kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh) Link Here
389
				return SSH_ERR_INVALID_FORMAT;
390
				return SSH_ERR_INVALID_FORMAT;
390
			}
391
			}
391
			debug("%s: %s=<%s>", __func__, name, val);
392
			debug("%s: %s=<%s>", __func__, name, val);
393
			/* XXX use a bitmap for this */
392
			found = match_list("rsa-sha2-256", val, NULL);
394
			found = match_list("rsa-sha2-256", val, NULL);
393
			if (found) {
395
			if (found) {
394
				kex->rsa_sha2 = 256;
396
				kex->rsa_sha2 = 256;
Lines 399-404 kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh) Link Here
399
				kex->rsa_sha2 = 512;
401
				kex->rsa_sha2 = 512;
400
				free(found);
402
				free(found);
401
			}
403
			}
404
			found = match_list("rsa-sha2-256-cert-v01@openssh.com",
405
			    val, NULL);
406
			if (found) {
407
				kex->rsa_sha2_cert = 256;
408
				free(found);
409
			}
410
			found = match_list("rsa-sha2-512-cert-v01@openssh.com",
411
			    val, NULL);
412
			if (found) {
413
				kex->rsa_sha2_cert = 512;
414
				free(found);
415
			}
402
		} else
416
		} else
403
			debug("%s: %s (unrecognised)", __func__, name);
417
			debug("%s: %s (unrecognised)", __func__, name);
404
		free(name);
418
		free(name);
(-)a/kex.h (+1 lines)
Lines 126-131 struct kex { Link Here
126
	int	hostkey_nid;
126
	int	hostkey_nid;
127
	u_int	kex_type;
127
	u_int	kex_type;
128
	int	rsa_sha2;
128
	int	rsa_sha2;
129
	int	rsa_sha2_cert;
129
	int	ext_info_c;
130
	int	ext_info_c;
130
	struct sshbuf *my;
131
	struct sshbuf *my;
131
	struct sshbuf *peer;
132
	struct sshbuf *peer;
(-)a/myproposal.h (+2 lines)
Lines 50-55 Link Here
50
	"ecdsa-sha2-nistp384-cert-v01@openssh.com," \
50
	"ecdsa-sha2-nistp384-cert-v01@openssh.com," \
51
	"ecdsa-sha2-nistp521-cert-v01@openssh.com," \
51
	"ecdsa-sha2-nistp521-cert-v01@openssh.com," \
52
	"ssh-ed25519-cert-v01@openssh.com," \
52
	"ssh-ed25519-cert-v01@openssh.com," \
53
	"rsa-sha2-512-cert-v01@openssh.com," \
54
	"rsa-sha2-256-cert-v01@openssh.com," \
53
	"ssh-rsa-cert-v01@openssh.com," \
55
	"ssh-rsa-cert-v01@openssh.com," \
54
	"ecdsa-sha2-nistp256," \
56
	"ecdsa-sha2-nistp256," \
55
	"ecdsa-sha2-nistp384," \
57
	"ecdsa-sha2-nistp384," \
(-)a/ssh-rsa.c (-14 / +44 lines)
Lines 46-56 rsa_hash_alg_ident(int hash_alg) Link Here
46
	return NULL;
46
	return NULL;
47
}
47
}
48
48
49
/*
50
 * Returns the hash algorithm ID for a given algorithm identifier as used
51
 * inside the signature blob,
52
 */
49
static int
53
static int
50
rsa_hash_alg_from_ident(const char *ident)
54
rsa_hash_id_from_ident(const char *ident)
51
{
55
{
52
	if (strcmp(ident, "ssh-rsa") == 0 ||
56
	if (strcmp(ident, "ssh-rsa") == 0)
53
	    strcmp(ident, "ssh-rsa-cert-v01@openssh.com") == 0)
54
		return SSH_DIGEST_SHA1;
57
		return SSH_DIGEST_SHA1;
55
	if (strcmp(ident, "rsa-sha2-256") == 0)
58
	if (strcmp(ident, "rsa-sha2-256") == 0)
56
		return SSH_DIGEST_SHA256;
59
		return SSH_DIGEST_SHA256;
Lines 59-64 rsa_hash_alg_from_ident(const char *ident) Link Here
59
	return -1;
62
	return -1;
60
}
63
}
61
64
65
/*
66
 * Return the hash algorithm ID for the specified key name. This includes
67
 * all the cases of rsa_hash_id_from_ident() but also the certificate key
68
 * types.
69
 */
70
static int
71
rsa_hash_id_from_keyname(const char *alg)
72
{
73
	int r;
74
75
	if ((r = rsa_hash_id_from_ident(alg)) != -1)
76
		return r;
77
	if (strcmp(alg, "ssh-rsa-cert-v01@openssh.com") == 0)
78
		return SSH_DIGEST_SHA1;
79
	if (strcmp(alg, "rsa-sha2-256-cert-v01@openssh.com") == 0)
80
		return SSH_DIGEST_SHA256;
81
	if (strcmp(alg, "rsa-sha2-512-cert-v01@openssh.com") == 0)
82
		return SSH_DIGEST_SHA512;
83
	return -1;
84
}
85
62
static int
86
static int
63
rsa_hash_alg_nid(int type)
87
rsa_hash_alg_nid(int type)
64
{
88
{
Lines 130-136 ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, Link Here
130
	if (alg_ident == NULL || strlen(alg_ident) == 0)
154
	if (alg_ident == NULL || strlen(alg_ident) == 0)
131
		hash_alg = SSH_DIGEST_SHA1;
155
		hash_alg = SSH_DIGEST_SHA1;
132
	else
156
	else
133
		hash_alg = rsa_hash_alg_from_ident(alg_ident);
157
		hash_alg = rsa_hash_id_from_keyname(alg_ident);
134
	if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
158
	if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
135
	    sshkey_type_plain(key->type) != KEY_RSA)
159
	    sshkey_type_plain(key->type) != KEY_RSA)
136
		return SSH_ERR_INVALID_ARGUMENT;
160
		return SSH_ERR_INVALID_ARGUMENT;
Lines 197-203 ssh_rsa_verify(const struct sshkey *key, Link Here
197
    const char *alg)
221
    const char *alg)
198
{
222
{
199
	char *sigtype = NULL;
223
	char *sigtype = NULL;
200
	int hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
224
	int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;
201
	size_t len = 0, diff, modlen, dlen;
225
	size_t len = 0, diff, modlen, dlen;
202
	struct sshbuf *b = NULL;
226
	struct sshbuf *b = NULL;
203
	u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
227
	u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
Lines 215-232 ssh_rsa_verify(const struct sshkey *key, Link Here
215
		ret = SSH_ERR_INVALID_FORMAT;
239
		ret = SSH_ERR_INVALID_FORMAT;
216
		goto out;
240
		goto out;
217
	}
241
	}
218
	/* XXX djm: need cert types that reliably yield SHA-2 signatures */
242
	if ((hash_alg = rsa_hash_id_from_ident(sigtype)) == -1) {
219
	if (alg != NULL && strcmp(alg, sigtype) != 0 &&
220
	    strcmp(alg, "ssh-rsa-cert-v01@openssh.com") != 0) {
221
		error("%s: RSA signature type mismatch: "
222
		    "expected %s received %s", __func__, alg, sigtype);
223
		ret = SSH_ERR_SIGNATURE_INVALID;
224
		goto out;
225
	}
226
	if ((hash_alg = rsa_hash_alg_from_ident(sigtype)) == -1) {
227
		ret = SSH_ERR_KEY_TYPE_MISMATCH;
243
		ret = SSH_ERR_KEY_TYPE_MISMATCH;
228
		goto out;
244
		goto out;
229
	}
245
	}
246
	/*
247
	 * Allow ssh-rsa-cert-v01 certs to generate SHA2 signatures for
248
	 * legacy reasons, but otherwise the signature type should match.
249
	 */
250
	if (alg != NULL && strcmp(alg, "ssh-rsa-cert-v01@openssh.com") != 0) {
251
		if ((want_alg = rsa_hash_id_from_keyname(alg)) == -1) {
252
			ret = SSH_ERR_INVALID_ARGUMENT;
253
			goto out;
254
		}
255
		if (hash_alg != want_alg) {
256
			ret = SSH_ERR_SIGNATURE_INVALID;
257
			goto out;
258
		}
259
	}
230
	if (sshbuf_get_string(b, &sigblob, &len) != 0) {
260
	if (sshbuf_get_string(b, &sigblob, &len) != 0) {
231
		ret = SSH_ERR_INVALID_FORMAT;
261
		ret = SSH_ERR_INVALID_FORMAT;
232
		goto out;
262
		goto out;
(-)a/ssh_config.5 (-3 / +6 lines)
Lines 773-781 ecdsa-sha2-nistp256-cert-v01@openssh.com, Link Here
773
ecdsa-sha2-nistp384-cert-v01@openssh.com,
773
ecdsa-sha2-nistp384-cert-v01@openssh.com,
774
ecdsa-sha2-nistp521-cert-v01@openssh.com,
774
ecdsa-sha2-nistp521-cert-v01@openssh.com,
775
ssh-ed25519-cert-v01@openssh.com,
775
ssh-ed25519-cert-v01@openssh.com,
776
rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
776
ssh-rsa-cert-v01@openssh.com,
777
ssh-rsa-cert-v01@openssh.com,
777
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
778
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
778
ssh-ed25519,ssh-rsa
779
ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
779
.Ed
780
.Ed
780
.Pp
781
.Pp
781
The
782
The
Lines 800-808 ecdsa-sha2-nistp256-cert-v01@openssh.com, Link Here
800
ecdsa-sha2-nistp384-cert-v01@openssh.com,
801
ecdsa-sha2-nistp384-cert-v01@openssh.com,
801
ecdsa-sha2-nistp521-cert-v01@openssh.com,
802
ecdsa-sha2-nistp521-cert-v01@openssh.com,
802
ssh-ed25519-cert-v01@openssh.com,
803
ssh-ed25519-cert-v01@openssh.com,
804
rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
803
ssh-rsa-cert-v01@openssh.com,
805
ssh-rsa-cert-v01@openssh.com,
804
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
806
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
805
ssh-ed25519,ssh-rsa
807
ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
806
.Ed
808
.Ed
807
.Pp
809
.Pp
808
If hostkeys are known for the destination host then this default is modified
810
If hostkeys are known for the destination host then this default is modified
Lines 1254-1262 ecdsa-sha2-nistp256-cert-v01@openssh.com, Link Here
1254
ecdsa-sha2-nistp384-cert-v01@openssh.com,
1256
ecdsa-sha2-nistp384-cert-v01@openssh.com,
1255
ecdsa-sha2-nistp521-cert-v01@openssh.com,
1257
ecdsa-sha2-nistp521-cert-v01@openssh.com,
1256
ssh-ed25519-cert-v01@openssh.com,
1258
ssh-ed25519-cert-v01@openssh.com,
1259
rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
1257
ssh-rsa-cert-v01@openssh.com,
1260
ssh-rsa-cert-v01@openssh.com,
1258
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
1261
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
1259
ssh-ed25519,ssh-rsa
1262
ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
1260
.Ed
1263
.Ed
1261
.Pp
1264
.Pp
1262
The list of available key types may also be obtained using
1265
The list of available key types may also be obtained using
(-)a/sshconnect2.c (-111 / +139 lines)
Lines 307-313 int input_gssapi_errtok(int, u_int32_t, struct ssh *); Link Here
307
307
308
void	userauth(Authctxt *, char *);
308
void	userauth(Authctxt *, char *);
309
309
310
static int sign_and_send_pubkey(Authctxt *, Identity *);
310
static int sign_and_send_pubkey(struct ssh *ssh, Authctxt *, Identity *);
311
static void pubkey_prepare(Authctxt *);
311
static void pubkey_prepare(Authctxt *);
312
static void pubkey_cleanup(Authctxt *);
312
static void pubkey_cleanup(Authctxt *);
313
static void pubkey_reset(Authctxt *);
313
static void pubkey_reset(Authctxt *);
Lines 611-617 input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) Link Here
611
	 */
611
	 */
612
	TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) {
612
	TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) {
613
		if (key_equal(key, id->key)) {
613
		if (key_equal(key, id->key)) {
614
			sent = sign_and_send_pubkey(authctxt, id);
614
			sent = sign_and_send_pubkey(ssh, authctxt, id);
615
			break;
615
			break;
616
		}
616
		}
617
	}
617
	}
Lines 979-1048 input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) Link Here
979
}
979
}
980
980
981
static const char *
981
static const char *
982
key_sign_encode(const struct sshkey *key)
982
key_sign_encode(struct ssh *ssh, const struct sshkey *key)
983
{
983
{
984
	struct ssh *ssh = active_state;
984
	switch (key->type) {
985
985
	case KEY_RSA:
986
	if (key->type == KEY_RSA) {
987
		switch (ssh->kex->rsa_sha2) {
986
		switch (ssh->kex->rsa_sha2) {
988
		case 256:
987
		case 256:
989
			return "rsa-sha2-256";
988
			return "rsa-sha2-256";
990
		case 512:
989
		case 512:
991
			return "rsa-sha2-512";
990
			return "rsa-sha2-512";
992
		}
991
		}
992
		break;
993
	case KEY_RSA_CERT:
994
		switch (ssh->kex->rsa_sha2_cert) {
995
		case 256:
996
			return "rsa-sha2-256-cert-v01@openssh.com";
997
		case 512:
998
			return "rsa-sha2-512-cert-v01@openssh.com";
999
		}
1000
		break;
993
	}
1001
	}
994
	return key_ssh_name(key);
1002
	return key_ssh_name(key);
995
}
1003
}
996
1004
997
/*
998
 * Some agents will return ssh-rsa signatures when asked to make a
999
 * rsa-sha2-* signature. Check what they actually gave back and warn the
1000
 * user if the agent has returned an unexpected type.
1001
 */
1002
static int
1003
check_sigtype(const struct sshkey *key, const u_char *sig, size_t len)
1004
{
1005
	int r;
1006
	char *sigtype = NULL;
1007
	const char *alg = key_sign_encode(key);
1008
1009
	if ((r = sshkey_sigtype(sig, len, &sigtype)) != 0)
1010
		return r;
1011
	if (strcmp(sigtype, alg) != 0) {
1012
		logit("warning: agent returned different signature type %s "
1013
		    "(expected %s)", sigtype, alg);
1014
	}
1015
	free(sigtype);
1016
	/* Incorrect signature types aren't an error ... yet */
1017
	return 0;
1018
}
1019
1020
static int
1005
static int
1021
identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
1006
identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
1022
    const u_char *data, size_t datalen, u_int compat)
1007
    const u_char *data, size_t datalen, u_int compat, const char *alg)
1023
{
1008
{
1024
	struct sshkey *prv;
1009
	struct sshkey *prv;
1025
	int r;
1010
	int r;
1026
1011
1027
	/* the agent supports this key */
1012
	/* The agent supports this key. */
1028
	if (id->key != NULL && id->agent_fd != -1) {
1013
	if (id->key != NULL && id->agent_fd != -1) {
1029
		if ((r = ssh_agent_sign(id->agent_fd, id->key, sigp, lenp,
1014
		return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp,
1030
		    data, datalen, key_sign_encode(id->key), compat)) != 0 ||
1015
		    data, datalen, alg, compat);
1031
		    (r = check_sigtype(id->key, *sigp, *lenp)) != 0)
1032
			return r;
1033
		return 0;
1034
	}
1016
	}
1035
1017
1036
	/*
1018
	/*
1037
	 * we have already loaded the private key or
1019
	 * We have already loaded the private key or the private key is
1038
	 * the private key is stored in external hardware
1020
	 * stored in external hardware.
1039
	 */
1021
	 */
1040
	if (id->key != NULL &&
1022
	if (id->key != NULL &&
1041
	    (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT)))
1023
	    (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))) {
1042
		return (sshkey_sign(id->key, sigp, lenp, data, datalen,
1024
		if ((r = sshkey_sign(id->key, sigp, lenp, data, datalen,
1043
		    key_sign_encode(id->key), compat));
1025
		    alg, compat)) != 0)
1026
			return r;
1027
		/*
1028
		 * PKCS#11 tokens may not support all signature algorithms,
1029
		 * so check what we get back.
1030
		 */
1031
		if ((r = sshkey_check_sigtype(*sigp, *lenp, alg)) != 0)
1032
			return r;
1033
		return 0;
1034
	}
1044
1035
1045
	/* load the private key from the file */
1036
	/* Load the private key from the file. */
1046
	if ((prv = load_identity_file(id)) == NULL)
1037
	if ((prv = load_identity_file(id)) == NULL)
1047
		return SSH_ERR_KEY_NOT_FOUND;
1038
		return SSH_ERR_KEY_NOT_FOUND;
1048
	if (id->key != NULL && !sshkey_equal_public(prv, id->key)) {
1039
	if (id->key != NULL && !sshkey_equal_public(prv, id->key)) {
Lines 1050-1057 identity_sign(struct identity *id, u_char **sigp, size_t *lenp, Link Here
1050
		   __func__, id->filename);
1041
		   __func__, id->filename);
1051
		return SSH_ERR_KEY_NOT_FOUND;
1042
		return SSH_ERR_KEY_NOT_FOUND;
1052
	}
1043
	}
1053
	r = sshkey_sign(prv, sigp, lenp, data, datalen,
1044
	r = sshkey_sign(prv, sigp, lenp, data, datalen, alg, compat);
1054
	    key_sign_encode(prv), compat);
1055
	sshkey_free(prv);
1045
	sshkey_free(prv);
1056
	return r;
1046
	return r;
1057
}
1047
}
Lines 1076-1132 id_filename_matches(Identity *id, Identity *private_id) Link Here
1076
}
1066
}
1077
1067
1078
static int
1068
static int
1079
sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
1069
sign_and_send_pubkey(struct ssh *ssh, Authctxt *authctxt, Identity *id)
1080
{
1070
{
1081
	Buffer b;
1071
	struct sshbuf *b = NULL;
1082
	Identity *private_id;
1072
	Identity *private_id, *sign_id = NULL;
1083
	u_char *blob, *signature;
1073
	u_char *signature = NULL;
1084
	size_t slen;
1074
	size_t slen = 0, skip = 0;
1085
	u_int bloblen, skip = 0;
1075
	int r, fallback_sigtype, sent = 0;
1086
	int matched, ret = -1, have_sig = 1;
1076
	char *fp = NULL;
1087
	char *fp;
1077
	const char *alg, *loc = "";
1088
1078
1089
	if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash,
1079
	if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash,
1090
	    SSH_FP_DEFAULT)) == NULL)
1080
	    SSH_FP_DEFAULT)) == NULL)
1091
		return 0;
1081
		return 0;
1092
	debug3("%s: %s %s", __func__, key_type(id->key), fp);
1093
	free(fp);
1094
1082
1095
	if (key_to_blob(id->key, &blob, &bloblen) == 0) {
1083
	debug3("%s: %s %s", __func__, sshkey_type(id->key), fp);
1096
		/* we cannot handle this key */
1097
		debug3("sign_and_send_pubkey: cannot handle key");
1098
		return 0;
1099
	}
1100
	/* data to be signed */
1101
	buffer_init(&b);
1102
	if (datafellows & SSH_OLD_SESSIONID) {
1103
		buffer_append(&b, session_id2, session_id2_len);
1104
		skip = session_id2_len;
1105
	} else {
1106
		buffer_put_string(&b, session_id2, session_id2_len);
1107
		skip = buffer_len(&b);
1108
	}
1109
	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1110
	buffer_put_cstring(&b, authctxt->server_user);
1111
	buffer_put_cstring(&b, authctxt->service);
1112
	buffer_put_cstring(&b, authctxt->method->name);
1113
	buffer_put_char(&b, have_sig);
1114
	buffer_put_cstring(&b, key_sign_encode(id->key));
1115
	buffer_put_string(&b, blob, bloblen);
1116
1084
1117
	/*
1085
	/*
1118
	 * If the key is an certificate, try to find a matching private key
1086
	 * If the key is an certificate, try to find a matching private key
1119
	 * and use it to complete the signature.
1087
	 * and use it to complete the signature.
1120
	 * If no such private key exists, fall back to trying the certificate
1088
	 * If no such private key exists, fall back to trying the certificate
1121
	 * key itself in case it has a private half already loaded.
1089
	 * key itself in case it has a private half already loaded.
1090
	 * This will try to set sign_id to the private key that will perform
1091
	 * the signature.
1122
	 */
1092
	 */
1123
	if (key_is_cert(id->key)) {
1093
	if (sshkey_is_cert(id->key)) {
1124
		matched = 0;
1125
		TAILQ_FOREACH(private_id, &authctxt->keys, next) {
1094
		TAILQ_FOREACH(private_id, &authctxt->keys, next) {
1126
			if (sshkey_equal_public(id->key, private_id->key) &&
1095
			if (sshkey_equal_public(id->key, private_id->key) &&
1127
			    id->key->type != private_id->key->type) {
1096
			    id->key->type != private_id->key->type) {
1128
				id = private_id;
1097
				sign_id = private_id;
1129
				matched = 1;
1130
				break;
1098
				break;
1131
			}
1099
			}
1132
		}
1100
		}
Lines 1137-1154 sign_and_send_pubkey(Authctxt *authctxt, Identity *id) Link Here
1137
		 * of keeping just a private key file and public
1105
		 * of keeping just a private key file and public
1138
		 * certificate on disk.
1106
		 * certificate on disk.
1139
		 */
1107
		 */
1140
		if (!matched && !id->isprivate && id->agent_fd == -1 &&
1108
		if (sign_id == NULL &&
1109
		    !id->isprivate && id->agent_fd == -1 &&
1141
		    (id->key->flags & SSHKEY_FLAG_EXT) == 0) {
1110
		    (id->key->flags & SSHKEY_FLAG_EXT) == 0) {
1142
			TAILQ_FOREACH(private_id, &authctxt->keys, next) {
1111
			TAILQ_FOREACH(private_id, &authctxt->keys, next) {
1143
				if (private_id->key == NULL &&
1112
				if (private_id->key == NULL &&
1144
				    id_filename_matches(id, private_id)) {
1113
				    id_filename_matches(id, private_id)) {
1145
					id = private_id;
1114
					sign_id = private_id;
1146
					matched = 1;
1147
					break;
1115
					break;
1148
				}
1116
				}
1149
			}
1117
			}
1150
		}
1118
		}
1151
		if (matched) {
1119
		if (sign_id != NULL) {
1152
			debug2("%s: using private key \"%s\"%s for "
1120
			debug2("%s: using private key \"%s\"%s for "
1153
			    "certificate", __func__, id->filename,
1121
			    "certificate", __func__, id->filename,
1154
			    id->agent_fd != -1 ? " from agent" : "");
1122
			    id->agent_fd != -1 ? " from agent" : "");
Lines 1158-1198 sign_and_send_pubkey(Authctxt *authctxt, Identity *id) Link Here
1158
		}
1126
		}
1159
	}
1127
	}
1160
1128
1161
	/* generate signature */
1129
	/*
1162
	ret = identity_sign(id, &signature, &slen,
1130
	 * If the above didn't select another identity to do the signing
1163
	    buffer_ptr(&b), buffer_len(&b), datafellows);
1131
	 * then default to the one we started with.
1164
	if (ret != 0) {
1132
	 */
1165
		if (ret != SSH_ERR_KEY_NOT_FOUND)
1133
	if (sign_id == NULL)
1166
			error("%s: signing failed: %s", __func__, ssh_err(ret));
1134
		sign_id = id;
1167
		free(blob);
1135
1168
		buffer_free(&b);
1136
	/* assemble and sign data */
1169
		return 0;
1137
	for (fallback_sigtype = 0; fallback_sigtype <= 1; fallback_sigtype++) {
1138
		slen = 0;
1139
		signature = NULL;
1140
		alg = fallback_sigtype ?
1141
		    sshkey_ssh_name(id->key) : key_sign_encode(ssh, id->key);
1142
1143
		sshbuf_free(b);
1144
		if ((b = sshbuf_new()) == NULL)
1145
			fatal("%s: sshbuf_new failed", __func__);
1146
		if (datafellows & SSH_OLD_SESSIONID) {
1147
			if ((r = sshbuf_put(b, session_id2,
1148
			    session_id2_len)) != 0) {
1149
				fatal("%s: sshbuf_put: %s",
1150
				    __func__, ssh_err(r));
1151
			}
1152
		} else {
1153
			if ((r = sshbuf_put_string(b, session_id2,
1154
			    session_id2_len)) != 0) {
1155
				fatal("%s: sshbuf_put_string: %s",
1156
				    __func__, ssh_err(r));
1157
			}
1158
		}
1159
		skip = buffer_len(b);
1160
		if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
1161
		    (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 ||
1162
		    (r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
1163
		    (r = sshbuf_put_cstring(b, authctxt->method->name)) != 0 ||
1164
		    (r = sshbuf_put_u8(b, 1)) != 0 ||
1165
		    (r = sshbuf_put_cstring(b, alg)) != 0 ||
1166
		    (r = sshkey_puts(id->key, b)) != 0) {
1167
			fatal("%s: assemble signed data: %s",
1168
			    __func__, ssh_err(r));
1169
		}
1170
1171
		/* generate signature */
1172
		r = identity_sign(sign_id, &signature, &slen,
1173
		    sshbuf_ptr(b), sshbuf_len(b), datafellows, alg);
1174
		if (r == 0)
1175
			break;
1176
		else if (r == SSH_ERR_KEY_NOT_FOUND)
1177
			goto out; /* soft failure */
1178
		else if (r == SSH_ERR_SIGN_ALG_UNSUPPORTED &&
1179
		    !fallback_sigtype) {
1180
			if (sign_id->agent_fd != -1)
1181
				loc = "agent ";
1182
			else if ((sign_id->key->flags & SSHKEY_FLAG_EXT) != 0)
1183
				loc = "token ";
1184
			logit("%skey %s %s returned incorrect signature type",
1185
			    loc, sshkey_type(id->key), fp);
1186
			continue;
1187
		}
1188
		error("%s: signing failed: %s", __func__, ssh_err(r));
1189
		goto out;
1170
	}
1190
	}
1171
#ifdef DEBUG_PK
1191
	if (slen == 0 || signature == NULL) /* shouldn't happen */
1172
	buffer_dump(&b);
1192
		fatal("%s: no signature", __func__);
1173
#endif
1174
	free(blob);
1175
1193
1176
	/* append signature */
1194
	/* append signature */
1177
	buffer_put_string(&b, signature, slen);
1195
	if ((r = sshbuf_put_string(b, signature, slen)) != 0)
1178
	free(signature);
1196
		fatal("%s: append signature: %s", __func__, ssh_err(r));
1179
1197
1198
#ifdef DEBUG_PK
1199
	sshbuf_dump(b, stderr);
1200
#endif
1180
	/* skip session id and packet type */
1201
	/* skip session id and packet type */
1181
	if (buffer_len(&b) < skip + 1)
1202
	if ((r = sshbuf_consume(b, skip + 1)) != 0)
1182
		fatal("userauth_pubkey: internal error");
1203
		fatal("%s: consume: %s", __func__, ssh_err(r));
1183
	buffer_consume(&b, skip + 1);
1184
1204
1185
	/* put remaining data from buffer into packet */
1205
	/* put remaining data from buffer into packet */
1186
	packet_start(SSH2_MSG_USERAUTH_REQUEST);
1206
	if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
1187
	packet_put_raw(buffer_ptr(&b), buffer_len(&b));
1207
	    (r = sshpkt_putb(ssh, b)) != 0 ||
1188
	buffer_free(&b);
1208
	    (r = sshpkt_send(ssh)) != 0)
1189
	packet_send();
1209
		fatal("%s: enqueue request: %s", __func__, ssh_err(r));
1190
1210
1191
	return 1;
1211
	/* success */
1212
	sent = 1;
1213
1214
 out:
1215
	free(fp);
1216
	sshbuf_free(b);
1217
	freezero(signature, slen);
1218
	return sent;
1192
}
1219
}
1193
1220
1194
static int
1221
static int
1195
send_pubkey_test(Authctxt *authctxt, Identity *id)
1222
send_pubkey_test(struct ssh *ssh, Authctxt *authctxt, Identity *id)
1196
{
1223
{
1197
	u_char *blob;
1224
	u_char *blob;
1198
	u_int bloblen, have_sig = 0;
1225
	u_int bloblen, have_sig = 0;
Lines 1212-1218 send_pubkey_test(Authctxt *authctxt, Identity *id) Link Here
1212
	packet_put_cstring(authctxt->service);
1239
	packet_put_cstring(authctxt->service);
1213
	packet_put_cstring(authctxt->method->name);
1240
	packet_put_cstring(authctxt->method->name);
1214
	packet_put_char(have_sig);
1241
	packet_put_char(have_sig);
1215
	packet_put_cstring(key_sign_encode(id->key));
1242
	packet_put_cstring(key_sign_encode(ssh, id->key));
1216
	packet_put_string(blob, bloblen);
1243
	packet_put_string(blob, bloblen);
1217
	free(blob);
1244
	free(blob);
1218
	packet_send();
1245
	packet_send();
Lines 1469-1474 try_identity(Identity *id) Link Here
1469
int
1496
int
1470
userauth_pubkey(Authctxt *authctxt)
1497
userauth_pubkey(Authctxt *authctxt)
1471
{
1498
{
1499
	struct ssh *ssh = active_state; /* XXX */
1472
	Identity *id;
1500
	Identity *id;
1473
	int sent = 0;
1501
	int sent = 0;
1474
	char *fp;
1502
	char *fp;
Lines 1496-1502 userauth_pubkey(Authctxt *authctxt) Link Here
1496
				debug("Offering public key: %s %s %s",
1524
				debug("Offering public key: %s %s %s",
1497
				    sshkey_type(id->key), fp, id->filename);
1525
				    sshkey_type(id->key), fp, id->filename);
1498
				free(fp);
1526
				free(fp);
1499
				sent = send_pubkey_test(authctxt, id);
1527
				sent = send_pubkey_test(ssh, authctxt, id);
1500
			}
1528
			}
1501
		} else {
1529
		} else {
1502
			debug("Trying private key: %s", id->filename);
1530
			debug("Trying private key: %s", id->filename);
Lines 1504-1510 userauth_pubkey(Authctxt *authctxt) Link Here
1504
			if (id->key != NULL) {
1532
			if (id->key != NULL) {
1505
				if (try_identity(id)) {
1533
				if (try_identity(id)) {
1506
					id->isprivate = 1;
1534
					id->isprivate = 1;
1507
					sent = sign_and_send_pubkey(
1535
					sent = sign_and_send_pubkey(ssh,
1508
					    authctxt, id);
1536
					    authctxt, id);
1509
				}
1537
				}
1510
				key_free(id->key);
1538
				key_free(id->key);
Lines 1725-1731 ssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp, Link Here
1725
int
1753
int
1726
userauth_hostbased(Authctxt *authctxt)
1754
userauth_hostbased(Authctxt *authctxt)
1727
{
1755
{
1728
	struct ssh *ssh = active_state;
1756
	struct ssh *ssh = active_state; /* XXX */
1729
	struct sshkey *private = NULL;
1757
	struct sshkey *private = NULL;
1730
	struct sshbuf *b = NULL;
1758
	struct sshbuf *b = NULL;
1731
	u_char *sig = NULL, *keyblob = NULL;
1759
	u_char *sig = NULL, *keyblob = NULL;
(-)a/sshd.c (-27 / +32 lines)
Lines 639-683 privsep_postauth(Authctxt *authctxt) Link Here
639
	packet_set_authenticated();
639
	packet_set_authenticated();
640
}
640
}
641
641
642
static void
643
append_hostkey_type(struct sshbuf *b, const char *s)
644
{
645
	int r;
646
647
	if (match_pattern_list(s, options.hostkeyalgorithms, 0) != 1) {
648
		debug3("%s: %s key not permitted by HostkeyAlgorithms",
649
		    __func__, s);
650
		return;
651
	}
652
	if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) > 0 ? "," : "", s)) != 0)
653
		fatal("%s: sshbuf_putf: %s", __func__, ssh_err(r));
654
}
655
642
static char *
656
static char *
643
list_hostkey_types(void)
657
list_hostkey_types(void)
644
{
658
{
645
	Buffer b;
659
	struct sshbuf *b;
646
	const char *p;
660
	struct sshkey *key;
647
	char *ret;
661
	char *ret;
648
	u_int i;
662
	u_int i;
649
	struct sshkey *key;
650
663
651
	buffer_init(&b);
664
	if ((b = sshbuf_new()) == NULL)
665
		fatal("%s: sshbuf_new failed", __func__);
652
	for (i = 0; i < options.num_host_key_files; i++) {
666
	for (i = 0; i < options.num_host_key_files; i++) {
653
		key = sensitive_data.host_keys[i];
667
		key = sensitive_data.host_keys[i];
654
		if (key == NULL)
668
		if (key == NULL)
655
			key = sensitive_data.host_pubkeys[i];
669
			key = sensitive_data.host_pubkeys[i];
656
		if (key == NULL)
670
		if (key == NULL)
657
			continue;
671
			continue;
658
		/* Check that the key is accepted in HostkeyAlgorithms */
659
		if (match_pattern_list(sshkey_ssh_name(key),
660
		    options.hostkeyalgorithms, 0) != 1) {
661
			debug3("%s: %s key not permitted by HostkeyAlgorithms",
662
			    __func__, sshkey_ssh_name(key));
663
			continue;
664
		}
665
		switch (key->type) {
672
		switch (key->type) {
666
		case KEY_RSA:
673
		case KEY_RSA:
674
			/* for RSA we also support SHA2 signatures */
675
			append_hostkey_type(b, "rsa-sha2-512");
676
			append_hostkey_type(b, "rsa-sha2-256");
677
			/* FALLTHROUGH */
667
		case KEY_DSA:
678
		case KEY_DSA:
668
		case KEY_ECDSA:
679
		case KEY_ECDSA:
669
		case KEY_ED25519:
680
		case KEY_ED25519:
670
		case KEY_XMSS:
681
		case KEY_XMSS:
671
			if (buffer_len(&b) > 0)
682
			append_hostkey_type(b, sshkey_ssh_name(key));
672
				buffer_append(&b, ",", 1);
673
			p = key_ssh_name(key);
674
			buffer_append(&b, p, strlen(p));
675
676
			/* for RSA we also support SHA2 signatures */
677
			if (key->type == KEY_RSA) {
678
				p = ",rsa-sha2-512,rsa-sha2-256";
679
				buffer_append(&b, p, strlen(p));
680
			}
681
			break;
683
			break;
682
		}
684
		}
683
		/* If the private key has a cert peer, then list that too */
685
		/* If the private key has a cert peer, then list that too */
Lines 686-705 list_hostkey_types(void) Link Here
686
			continue;
688
			continue;
687
		switch (key->type) {
689
		switch (key->type) {
688
		case KEY_RSA_CERT:
690
		case KEY_RSA_CERT:
691
			/* for RSA we also support SHA2 signatures */
692
			append_hostkey_type(b,
693
			    "rsa-sha2-512-cert-v01@openssh.com");
694
			append_hostkey_type(b,
695
			    "rsa-sha2-256-cert-v01@openssh.com");
696
			/* FALLTHROUGH */
689
		case KEY_DSA_CERT:
697
		case KEY_DSA_CERT:
690
		case KEY_ECDSA_CERT:
698
		case KEY_ECDSA_CERT:
691
		case KEY_ED25519_CERT:
699
		case KEY_ED25519_CERT:
692
		case KEY_XMSS_CERT:
700
		case KEY_XMSS_CERT:
693
			if (buffer_len(&b) > 0)
701
			append_hostkey_type(b, sshkey_ssh_name(key));
694
				buffer_append(&b, ",", 1);
695
			p = key_ssh_name(key);
696
			buffer_append(&b, p, strlen(p));
697
			break;
702
			break;
698
		}
703
		}
699
	}
704
	}
700
	if ((ret = sshbuf_dup_string(&b)) == NULL)
705
	if ((ret = sshbuf_dup_string(b)) == NULL)
701
		fatal("%s: sshbuf_dup_string failed", __func__);
706
		fatal("%s: sshbuf_dup_string failed", __func__);
702
	buffer_free(&b);
707
	sshbuf_free(b);
703
	debug("list_hostkey_types: %s", ret);
708
	debug("list_hostkey_types: %s", ret);
704
	return ret;
709
	return ret;
705
}
710
}
(-)a/sshd_config.5 (-3 / +6 lines)
Lines 673-681 ecdsa-sha2-nistp256-cert-v01@openssh.com, Link Here
673
ecdsa-sha2-nistp384-cert-v01@openssh.com,
673
ecdsa-sha2-nistp384-cert-v01@openssh.com,
674
ecdsa-sha2-nistp521-cert-v01@openssh.com,
674
ecdsa-sha2-nistp521-cert-v01@openssh.com,
675
ssh-ed25519-cert-v01@openssh.com,
675
ssh-ed25519-cert-v01@openssh.com,
676
rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
676
ssh-rsa-cert-v01@openssh.com,
677
ssh-rsa-cert-v01@openssh.com,
677
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
678
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
678
ssh-ed25519,ssh-rsa
679
ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
679
.Ed
680
.Ed
680
.Pp
681
.Pp
681
The list of available key types may also be obtained using
682
The list of available key types may also be obtained using
Lines 750-758 ecdsa-sha2-nistp256-cert-v01@openssh.com, Link Here
750
ecdsa-sha2-nistp384-cert-v01@openssh.com,
751
ecdsa-sha2-nistp384-cert-v01@openssh.com,
751
ecdsa-sha2-nistp521-cert-v01@openssh.com,
752
ecdsa-sha2-nistp521-cert-v01@openssh.com,
752
ssh-ed25519-cert-v01@openssh.com,
753
ssh-ed25519-cert-v01@openssh.com,
754
rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
753
ssh-rsa-cert-v01@openssh.com,
755
ssh-rsa-cert-v01@openssh.com,
754
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
756
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
755
ssh-ed25519,ssh-rsa
757
ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
756
.Ed
758
.Ed
757
.Pp
759
.Pp
758
The list of available key types may also be obtained using
760
The list of available key types may also be obtained using
Lines 1346-1354 ecdsa-sha2-nistp256-cert-v01@openssh.com, Link Here
1346
ecdsa-sha2-nistp384-cert-v01@openssh.com,
1348
ecdsa-sha2-nistp384-cert-v01@openssh.com,
1347
ecdsa-sha2-nistp521-cert-v01@openssh.com,
1349
ecdsa-sha2-nistp521-cert-v01@openssh.com,
1348
ssh-ed25519-cert-v01@openssh.com,
1350
ssh-ed25519-cert-v01@openssh.com,
1351
rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
1349
ssh-rsa-cert-v01@openssh.com,
1352
ssh-rsa-cert-v01@openssh.com,
1350
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
1353
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
1351
ssh-ed25519,ssh-rsa
1354
ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
1352
.Ed
1355
.Ed
1353
.Pp
1356
.Pp
1354
The list of available key types may also be obtained using
1357
The list of available key types may also be obtained using
(-)a/ssherr.c (+2 lines)
Lines 139-144 ssh_err(int n) Link Here
139
		return "Invalid key length";
139
		return "Invalid key length";
140
	case SSH_ERR_NUMBER_TOO_LARGE:
140
	case SSH_ERR_NUMBER_TOO_LARGE:
141
		return "number is too large";
141
		return "number is too large";
142
	case SSH_ERR_SIGN_ALG_UNSUPPORTED:
143
		return "signature algorithm not supported";
142
	default:
144
	default:
143
		return "unknown error";
145
		return "unknown error";
144
	}
146
	}
(-)a/ssherr.h (+1 lines)
Lines 79-84 Link Here
79
#define SSH_ERR_PROTOCOL_ERROR			-55
79
#define SSH_ERR_PROTOCOL_ERROR			-55
80
#define SSH_ERR_KEY_LENGTH			-56
80
#define SSH_ERR_KEY_LENGTH			-56
81
#define SSH_ERR_NUMBER_TOO_LARGE		-57
81
#define SSH_ERR_NUMBER_TOO_LARGE		-57
82
#define SSH_ERR_SIGN_ALG_UNSUPPORTED		-58
82
83
83
/* Translate a numeric error code to a human-readable error string */
84
/* Translate a numeric error code to a human-readable error string */
84
const char *ssh_err(int n);
85
const char *ssh_err(int n);
(-)a/sshkey.c (-18 / +72 lines)
Lines 79-116 static int sshkey_from_blob_internal(struct sshbuf *buf, Link Here
79
struct keytype {
79
struct keytype {
80
	const char *name;
80
	const char *name;
81
	const char *shortname;
81
	const char *shortname;
82
	const char *sigalg;
82
	int type;
83
	int type;
83
	int nid;
84
	int nid;
84
	int cert;
85
	int cert;
85
	int sigonly;
86
	int sigonly;
86
};
87
};
87
static const struct keytype keytypes[] = {
88
static const struct keytype keytypes[] = {
88
	{ "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0, 0 },
89
	{ "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 },
89
	{ "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
90
	{ "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL,
90
	    KEY_ED25519_CERT, 0, 1, 0 },
91
	    KEY_ED25519_CERT, 0, 1, 0 },
91
#ifdef WITH_XMSS
92
#ifdef WITH_XMSS
92
	{ "ssh-xmss@openssh.com", "XMSS", KEY_XMSS, 0, 0, 0 },
93
	{ "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 },
93
	{ "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT",
94
	{ "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL,
94
	    KEY_XMSS_CERT, 0, 1, 0 },
95
	    KEY_XMSS_CERT, 0, 1, 0 },
95
#endif /* WITH_XMSS */
96
#endif /* WITH_XMSS */
96
#ifdef WITH_OPENSSL
97
#ifdef WITH_OPENSSL
97
	{ "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 },
98
	{ "ssh-rsa", "RSA", NULL, KEY_RSA, 0, 0, 0 },
98
	{ "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 },
99
	{ "rsa-sha2-256", "RSA", NULL, KEY_RSA, 0, 0, 1 },
99
	{ "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 },
100
	{ "rsa-sha2-512", "RSA", NULL, KEY_RSA, 0, 0, 1 },
100
	{ "ssh-dss", "DSA", KEY_DSA, 0, 0, 0 },
101
	{ "ssh-dss", "DSA", NULL, KEY_DSA, 0, 0, 0 },
101
	{ "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 },
102
	{ "ecdsa-sha2-nistp256", "ECDSA", NULL,
102
	{ "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0, 0 },
103
	    KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 },
103
	{ "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0, 0 },
104
	{ "ecdsa-sha2-nistp384", "ECDSA", NULL,
104
	{ "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1, 0 },
105
	    KEY_ECDSA, NID_secp384r1, 0, 0 },
105
	{ "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1, 0 },
106
	{ "ecdsa-sha2-nistp521", "ECDSA", NULL,
106
	{ "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT",
107
	    KEY_ECDSA, NID_secp521r1, 0, 0 },
108
	{ "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL,
109
	    KEY_RSA_CERT, 0, 1, 0 },
110
	{ "rsa-sha2-256-cert-v01@openssh.com", "RSA-CERT",
111
	    "ssh-rsa-sha2-256", KEY_RSA_CERT, 0, 1, 1 },
112
	{ "rsa-sha2-512-cert-v01@openssh.com", "RSA-CERT",
113
	    "ssh-rsa-sha2-512", KEY_RSA_CERT, 0, 1, 1 },
114
	{ "ssh-dss-cert-v01@openssh.com", "DSA-CERT", NULL,
115
	    KEY_DSA_CERT, 0, 1, 0 },
116
	{ "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT", NULL,
107
	    KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 },
117
	    KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 },
108
	{ "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT",
118
	{ "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT", NULL,
109
	    KEY_ECDSA_CERT, NID_secp384r1, 1, 0 },
119
	    KEY_ECDSA_CERT, NID_secp384r1, 1, 0 },
110
	{ "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT",
120
	{ "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", NULL,
111
	    KEY_ECDSA_CERT, NID_secp521r1, 1, 0 },
121
	   KEY_ECDSA_CERT, NID_secp521r1, 1, 0 },
112
#endif /* WITH_OPENSSL */
122
#endif /* WITH_OPENSSL */
113
	{ NULL, NULL, -1, -1, 0, 0 }
123
	{ NULL, NULL, NULL, -1, -1, 0, 0 }
114
};
124
};
115
125
116
const char *
126
const char *
Lines 2185-2190 sshkey_sigtype(const u_char *sig, size_t siglen, char **sigtypep) Link Here
2185
	return r;
2195
	return r;
2186
}
2196
}
2187
2197
2198
/*
2199
 * Returns the expected signature algorithm for a given public key algorithm.
2200
 */
2201
static const char *
2202
sigalg_by_name(const char *name)
2203
{
2204
	const struct keytype *kt;
2205
2206
	for (kt = keytypes; kt->type != -1; kt++) {
2207
		if (strcmp(kt->name, name) != 0)
2208
			continue;
2209
		if (kt->sigalg != NULL)
2210
			return kt->sigalg;
2211
		if (!kt->cert)
2212
			return kt->name;
2213
		return sshkey_ssh_name_from_type_nid(
2214
		    sshkey_type_plain(kt->type), kt->nid);
2215
	}
2216
	return NULL;
2217
}
2218
2219
/*
2220
 * Verifies that the signature algorithm appearing inside the signature blob
2221
 * matches that which was requested.
2222
 */
2223
int
2224
sshkey_check_sigtype(const u_char *sig, size_t siglen,
2225
    const char *requested_alg)
2226
{
2227
	const char *expected_alg;
2228
	char *sigtype = NULL;
2229
	int r;
2230
2231
	if (requested_alg == NULL)
2232
		return 0;
2233
	if ((expected_alg = sigalg_by_name(requested_alg)) == NULL)
2234
		return SSH_ERR_INVALID_ARGUMENT;
2235
	if ((r = sshkey_sigtype(sig, siglen, &sigtype)) != 0)
2236
		return r;
2237
	r = strcmp(expected_alg, sigtype) == 0;
2238
	free(sigtype);
2239
	return r ? 0 : SSH_ERR_SIGN_ALG_UNSUPPORTED;
2240
}
2241
2188
int
2242
int
2189
sshkey_sign(const struct sshkey *key,
2243
sshkey_sign(const struct sshkey *key,
2190
    u_char **sigp, size_t *lenp,
2244
    u_char **sigp, size_t *lenp,
(-)a/sshkey.h (-1 / +3 lines)
Lines 185-196 int sshkey_puts_opts(const struct sshkey *, struct sshbuf *, Link Here
185
int	 sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);
185
int	 sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);
186
int	 sshkey_putb_plain(const struct sshkey *, struct sshbuf *);
186
int	 sshkey_putb_plain(const struct sshkey *, struct sshbuf *);
187
187
188
int	 sshkey_sigtype(const u_char *, size_t, char **);
189
int	 sshkey_sign(const struct sshkey *, u_char **, size_t *,
188
int	 sshkey_sign(const struct sshkey *, u_char **, size_t *,
190
    const u_char *, size_t, const char *, u_int);
189
    const u_char *, size_t, const char *, u_int);
191
int	 sshkey_verify(const struct sshkey *, const u_char *, size_t,
190
int	 sshkey_verify(const struct sshkey *, const u_char *, size_t,
192
    const u_char *, size_t, const char *, u_int);
191
    const u_char *, size_t, const char *, u_int);
193
192
193
int	 sshkey_sigtype(const u_char *, size_t, char **);
194
int	 sshkey_check_sigtype(const u_char *, size_t, const char *);
195
194
/* for debug */
196
/* for debug */
195
void	sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *);
197
void	sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *);
196
void	sshkey_dump_ec_key(const EC_KEY *);
198
void	sshkey_dump_ec_key(const EC_KEY *);
(-)a/version.h (-1 / +1 lines)
Lines 1-3 Link Here
1
/* $OpenBSD: version.h,v 1.80 2017/09/30 22:26:33 djm Exp $ */
1
/* $OpenBSD: version.h,v 1.80 2017/09/30 22:26:33 djm Exp $ */
2
2
3
#define SSH_VERSION	"OpenSSH_7.6"
3
#define SSH_VERSION	"OpenSSH_7.7"

Return to bug 2799