|
|
6c1f4d |
diff --color -ru a/kex.c b/kex.c
|
|
|
6c1f4d |
--- a/kex.c 2022-06-23 10:25:29.529922670 +0200
|
|
|
6c1f4d |
+++ b/kex.c 2022-06-23 10:26:12.911762100 +0200
|
|
|
6c1f4d |
@@ -906,6 +906,18 @@
|
|
|
6c1f4d |
return (1);
|
|
|
6c1f4d |
}
|
|
|
6c1f4d |
|
|
|
6c1f4d |
+/* returns non-zero if proposal contains any algorithm from algs */
|
|
|
6c1f4d |
+static int
|
|
|
6c1f4d |
+has_any_alg(const char *proposal, const char *algs)
|
|
|
6c1f4d |
+{
|
|
|
6c1f4d |
+ char *cp;
|
|
|
6c1f4d |
+
|
|
|
6c1f4d |
+ if ((cp = match_list(proposal, algs, NULL)) == NULL)
|
|
|
6c1f4d |
+ return 0;
|
|
|
6c1f4d |
+ free(cp);
|
|
|
6c1f4d |
+ return 1;
|
|
|
6c1f4d |
+}
|
|
|
6c1f4d |
+
|
|
|
6c1f4d |
static int
|
|
|
6c1f4d |
kex_choose_conf(struct ssh *ssh)
|
|
|
6c1f4d |
{
|
|
|
6c1f4d |
@@ -941,6 +953,16 @@
|
|
|
6c1f4d |
free(ext);
|
|
|
6c1f4d |
}
|
|
|
6c1f4d |
|
|
|
6c1f4d |
+ /* Check whether client supports rsa-sha2 algorithms */
|
|
|
6c1f4d |
+ if (kex->server && (kex->flags & KEX_INITIAL)) {
|
|
|
6c1f4d |
+ if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
|
|
|
6c1f4d |
+ "rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com"))
|
|
|
6c1f4d |
+ kex->flags |= KEX_RSA_SHA2_256_SUPPORTED;
|
|
|
6c1f4d |
+ if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
|
|
|
6c1f4d |
+ "rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com"))
|
|
|
6c1f4d |
+ kex->flags |= KEX_RSA_SHA2_512_SUPPORTED;
|
|
|
6c1f4d |
+ }
|
|
|
6c1f4d |
+
|
|
|
6c1f4d |
/* Algorithm Negotiation */
|
|
|
6c1f4d |
if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
|
|
|
6c1f4d |
sprop[PROPOSAL_KEX_ALGS])) != 0) {
|
|
|
6c1f4d |
diff --color -ru a/kex.h b/kex.h
|
|
|
6c1f4d |
--- a/kex.h 2022-06-23 10:25:29.511922322 +0200
|
|
|
6c1f4d |
+++ b/kex.h 2022-06-23 10:26:12.902761926 +0200
|
|
|
6c1f4d |
@@ -117,6 +117,8 @@
|
|
|
6c1f4d |
|
|
|
6c1f4d |
#define KEX_INIT_SENT 0x0001
|
|
|
6c1f4d |
#define KEX_INITIAL 0x0002
|
|
|
6c1f4d |
+#define KEX_RSA_SHA2_256_SUPPORTED 0x0008 /* only set in server for now */
|
|
|
6c1f4d |
+#define KEX_RSA_SHA2_512_SUPPORTED 0x0010 /* only set in server for now */
|
|
|
6c1f4d |
|
|
|
6c1f4d |
struct sshenc {
|
|
|
6c1f4d |
char *name;
|
|
|
6c1f4d |
diff --color -ru a/serverloop.c b/serverloop.c
|
|
|
6c1f4d |
--- a/serverloop.c 2022-06-23 10:25:29.537922825 +0200
|
|
|
6c1f4d |
+++ b/serverloop.c 2022-06-23 10:26:12.918762235 +0200
|
|
|
6c1f4d |
@@ -736,16 +736,17 @@
|
|
|
6c1f4d |
struct sshbuf *resp = NULL;
|
|
|
6c1f4d |
struct sshbuf *sigbuf = NULL;
|
|
|
6c1f4d |
struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
|
|
|
6c1f4d |
- int r, ndx, kexsigtype, use_kexsigtype, success = 0;
|
|
|
6c1f4d |
+ int r, ndx, success = 0;
|
|
|
6c1f4d |
const u_char *blob;
|
|
|
6c1f4d |
+ const char *sigalg, *kex_rsa_sigalg = NULL;
|
|
|
6c1f4d |
u_char *sig = 0;
|
|
|
6c1f4d |
size_t blen, slen;
|
|
|
6c1f4d |
|
|
|
6c1f4d |
if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL)
|
|
|
6c1f4d |
fatal("%s: sshbuf_new", __func__);
|
|
|
6c1f4d |
-
|
|
|
6c1f4d |
- kexsigtype = sshkey_type_plain(
|
|
|
6c1f4d |
- sshkey_type_from_name(ssh->kex->hostkey_alg));
|
|
|
6c1f4d |
+ if (sshkey_type_plain(sshkey_type_from_name(
|
|
|
6c1f4d |
+ ssh->kex->hostkey_alg)) == KEY_RSA)
|
|
|
6c1f4d |
+ kex_rsa_sigalg = ssh->kex->hostkey_alg;
|
|
|
6c1f4d |
while (ssh_packet_remaining(ssh) > 0) {
|
|
|
6c1f4d |
sshkey_free(key);
|
|
|
6c1f4d |
key = NULL;
|
|
|
6c1f4d |
@@ -780,16 +781,24 @@
|
|
|
6c1f4d |
* For RSA keys, prefer to use the signature type negotiated
|
|
|
6c1f4d |
* during KEX to the default (SHA1).
|
|
|
6c1f4d |
*/
|
|
|
6c1f4d |
- use_kexsigtype = kexsigtype == KEY_RSA &&
|
|
|
6c1f4d |
- sshkey_type_plain(key->type) == KEY_RSA;
|
|
|
6c1f4d |
+ sigalg = NULL;
|
|
|
6c1f4d |
+ if (sshkey_type_plain(key->type) == KEY_RSA) {
|
|
|
6c1f4d |
+ if (kex_rsa_sigalg != NULL)
|
|
|
6c1f4d |
+ sigalg = kex_rsa_sigalg;
|
|
|
6c1f4d |
+ else if (ssh->kex->flags & KEX_RSA_SHA2_512_SUPPORTED)
|
|
|
6c1f4d |
+ sigalg = "rsa-sha2-512";
|
|
|
6c1f4d |
+ else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
|
|
|
6c1f4d |
+ sigalg = "rsa-sha2-256";
|
|
|
6c1f4d |
+ }
|
|
|
6c1f4d |
+ debug3("%s: sign %s key (index %d) using sigalg %s", __func__,
|
|
|
6c1f4d |
+ sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
|
|
|
6c1f4d |
if ((r = sshbuf_put_cstring(sigbuf,
|
|
|
6c1f4d |
"hostkeys-prove-00@openssh.com")) != 0 ||
|
|
|
6c1f4d |
(r = sshbuf_put_string(sigbuf,
|
|
|
6c1f4d |
ssh->kex->session_id, ssh->kex->session_id_len)) != 0 ||
|
|
|
6c1f4d |
(r = sshkey_puts(key, sigbuf)) != 0 ||
|
|
|
6c1f4d |
(r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen,
|
|
|
6c1f4d |
- sshbuf_ptr(sigbuf), sshbuf_len(sigbuf),
|
|
|
6c1f4d |
- use_kexsigtype ? ssh->kex->hostkey_alg : NULL)) != 0 ||
|
|
|
6c1f4d |
+ sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), sigalg)) != 0 ||
|
|
|
6c1f4d |
(r = sshbuf_put_string(resp, sig, slen)) != 0) {
|
|
|
6c1f4d |
error("%s: couldn't prepare signature: %s",
|
|
|
6c1f4d |
__func__, ssh_err(r));
|
|
|
6c1f4d |
diff --color -ru a/sshkey.c b/sshkey.c
|
|
|
6c1f4d |
--- a/sshkey.c 2022-06-23 10:25:29.532922728 +0200
|
|
|
6c1f4d |
+++ b/sshkey.c 2022-06-23 10:26:12.914762158 +0200
|
|
|
6c1f4d |
@@ -82,7 +82,6 @@
|
|
|
6c1f4d |
struct sshbuf *buf, enum sshkey_serialize_rep);
|
|
|
6c1f4d |
static int sshkey_from_blob_internal(struct sshbuf *buf,
|
|
|
6c1f4d |
struct sshkey **keyp, int allow_cert);
|
|
|
6c1f4d |
-static int get_sigtype(const u_char *sig, size_t siglen, char **sigtypep);
|
|
|
6c1f4d |
|
|
|
6c1f4d |
/* Supported key types */
|
|
|
6c1f4d |
struct keytype {
|
|
|
6c1f4d |
@@ -2092,7 +2091,8 @@
|
|
|
6c1f4d |
if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
|
|
|
6c1f4d |
sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0)
|
|
|
6c1f4d |
goto out;
|
|
|
6c1f4d |
- if ((ret = get_sigtype(sig, slen, &key->cert->signature_type)) != 0)
|
|
|
6c1f4d |
+ if ((ret = sshkey_get_sigtype(sig, slen,
|
|
|
6c1f4d |
+ &key->cert->signature_type)) != 0)
|
|
|
6c1f4d |
goto out;
|
|
|
6c1f4d |
|
|
|
6c1f4d |
/* Success */
|
|
|
6c1f4d |
@@ -2394,8 +2394,8 @@
|
|
|
6c1f4d |
return r;
|
|
|
6c1f4d |
}
|
|
|
6c1f4d |
|
|
|
6c1f4d |
-static int
|
|
|
6c1f4d |
-get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
|
|
|
6c1f4d |
+int
|
|
|
6c1f4d |
+sshkey_get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
|
|
|
6c1f4d |
{
|
|
|
6c1f4d |
int r;
|
|
|
6c1f4d |
struct sshbuf *b = NULL;
|
|
|
6c1f4d |
@@ -2477,7 +2477,7 @@
|
|
|
6c1f4d |
return 0;
|
|
|
6c1f4d |
if ((expected_alg = sshkey_sigalg_by_name(requested_alg)) == NULL)
|
|
|
6c1f4d |
return SSH_ERR_INVALID_ARGUMENT;
|
|
|
6c1f4d |
- if ((r = get_sigtype(sig, siglen, &sigtype)) != 0)
|
|
|
6c1f4d |
+ if ((r = sshkey_get_sigtype(sig, siglen, &sigtype)) != 0)
|
|
|
6c1f4d |
return r;
|
|
|
6c1f4d |
r = strcmp(expected_alg, sigtype) == 0;
|
|
|
6c1f4d |
free(sigtype);
|
|
|
6c1f4d |
@@ -2739,7 +2739,7 @@
|
|
|
6c1f4d |
sshbuf_len(cert), alg, 0, signer_ctx)) != 0)
|
|
|
6c1f4d |
goto out;
|
|
|
6c1f4d |
/* Check and update signature_type against what was actually used */
|
|
|
6c1f4d |
- if ((ret = get_sigtype(sig_blob, sig_len, &sigtype)) != 0)
|
|
|
6c1f4d |
+ if ((ret = sshkey_get_sigtype(sig_blob, sig_len, &sigtype)) != 0)
|
|
|
6c1f4d |
goto out;
|
|
|
6c1f4d |
if (alg != NULL && strcmp(alg, sigtype) != 0) {
|
|
|
6c1f4d |
ret = SSH_ERR_SIGN_ALG_UNSUPPORTED;
|
|
|
6c1f4d |
diff --color -ru a/sshkey.h b/sshkey.h
|
|
|
6c1f4d |
--- a/sshkey.h 2022-06-23 10:25:29.521922515 +0200
|
|
|
6c1f4d |
+++ b/sshkey.h 2022-06-23 10:26:12.907762022 +0200
|
|
|
6c1f4d |
@@ -211,6 +211,7 @@
|
|
|
6c1f4d |
const u_char *, size_t, const char *, u_int);
|
|
|
6c1f4d |
int sshkey_check_sigtype(const u_char *, size_t, const char *);
|
|
|
6c1f4d |
const char *sshkey_sigalg_by_name(const char *);
|
|
|
6c1f4d |
+int sshkey_get_sigtype(const u_char *, size_t, char **);
|
|
|
6c1f4d |
|
|
|
6c1f4d |
/* for debug */
|
|
|
6c1f4d |
void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *);
|