mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-01 03:22:48 -05:00
Work around key algorithm naming change in OpenSSH <= 7.7.
When you send a "publickey" USERAUTH_REQUEST containing a certified RSA key, and you want to use a SHA-2 based RSA algorithm, modern OpenSSH expects you to send the algorithm string as rsa-sha2-NNN-cert-v01@openssh.com. But 7.7 and earlier didn't recognise those names, and expected the algorithm string in the userauth request packet to be ssh-rsa-cert-v01@... and would then follow it with an rsa-sha2-NNN signature. OpenSSH itself has a bug workaround for its own older versions. Follow suit.
This commit is contained in:
@ -135,6 +135,8 @@ static void ssh2_userauth_ki_write_responses(
|
||||
static void ssh2_userauth_final_output(PacketProtocolLayer *ppl);
|
||||
|
||||
static void ssh2_userauth_print_banner(struct ssh2_userauth_state *s);
|
||||
static ptrlen workaround_rsa_sha2_cert_userauth(
|
||||
struct ssh2_userauth_state *s, ptrlen id);
|
||||
|
||||
static const PacketProtocolLayerVtable ssh2_userauth_vtable = {
|
||||
.free = ssh2_userauth_free,
|
||||
@ -2381,9 +2383,19 @@ static void ssh2_userauth_add_alg_and_publickey(
|
||||
* bare key algorithms, or nothing useful will happen. */
|
||||
const ssh_keyalg *pkalg_base =
|
||||
pkalg->base_alg ? pkalg->base_alg : pkalg;
|
||||
|
||||
/* Construct an algorithm string that includes both the
|
||||
* signature subtype (e.g. rsa-sha2-512) and the
|
||||
* certificate-ness. Exception: in earlier versions of
|
||||
* OpenSSH we don't want to do that, and must send just
|
||||
* ssh-rsa-cert-... even when we're delivering a non-SHA-1
|
||||
* signature. */
|
||||
const ssh_keyalg *output_alg =
|
||||
ssh_keyalg_related_alg(certalg, pkalg_base);
|
||||
put_stringz(pkt, output_alg->ssh_id);
|
||||
ptrlen output_id = ptrlen_from_asciz(output_alg->ssh_id);
|
||||
output_id = workaround_rsa_sha2_cert_userauth(s, output_id);
|
||||
|
||||
put_stringpl(pkt, output_id);
|
||||
}
|
||||
put_stringpl(pkt, ptrlen_from_strbuf(s->detached_cert_blob));
|
||||
done = true;
|
||||
@ -2430,11 +2442,30 @@ static void ssh2_userauth_add_alg_and_publickey(
|
||||
return;
|
||||
}
|
||||
|
||||
/* In all other cases, just put in what we were given. */
|
||||
/* In all other cases, basically just put in what we were given -
|
||||
* except for the same bug workaround as above. */
|
||||
alg = workaround_rsa_sha2_cert_userauth(s, alg);
|
||||
put_stringpl(pkt, alg);
|
||||
put_stringpl(pkt, pkblob);
|
||||
}
|
||||
|
||||
static ptrlen workaround_rsa_sha2_cert_userauth(
|
||||
struct ssh2_userauth_state *s, ptrlen id)
|
||||
{
|
||||
if (!(s->ppl.remote_bugs & BUG_RSA_SHA2_CERT_USERAUTH))
|
||||
return id;
|
||||
/*
|
||||
* No need to try to do this in a general way based on the
|
||||
* relations between ssh_keyalgs; we know there are a limited
|
||||
* number of affected versions of OpenSSH, so this doesn't have to
|
||||
* be futureproof against later additions to the family.
|
||||
*/
|
||||
if (ptrlen_eq_string(id, "rsa-sha2-256-cert-v01@openssh.com") ||
|
||||
ptrlen_eq_string(id, "rsa-sha2-512-cert-v01@openssh.com"))
|
||||
return PTRLEN_LITERAL("ssh-rsa-cert-v01@openssh.com");
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to add an SSH-2 signature blob to a packet. Expects
|
||||
* to be shown the public key blob as well as the signature blob.
|
||||
|
@ -612,6 +612,28 @@ static void ssh_detect_bugs(struct ssh_verstring_state *s)
|
||||
bpp_logevent("We believe remote version requires us to "
|
||||
"filter our KEXINIT");
|
||||
}
|
||||
|
||||
if (conf_get_int(s->conf, CONF_sshbug_rsa_sha2_cert_userauth) == FORCE_ON ||
|
||||
(conf_get_int(s->conf, CONF_sshbug_rsa_sha2_cert_userauth) == AUTO &&
|
||||
(wc_match("OpenSSH_7.[2-7]*", imp)))) {
|
||||
/*
|
||||
* These versions have the bug in which using RSA/SHA-2
|
||||
* authentication with a certified key requires the key
|
||||
* algorithm to be sent as ssh-rsa-cert-... instead of
|
||||
* rsa-sha2-NNN-cert-...
|
||||
*
|
||||
* OpenSSH 7.8 wants rsa-sha2-NNN-cert-...:
|
||||
* https://github.com/openssh/openssh-portable/commit/4ba0d54794814ec0de1ec87987d0c3b89379b436
|
||||
* (also labelled "OpenBSD-Commit-ID:
|
||||
* c6e9f6d45eed8962ad502d315d7eaef32c419dde")
|
||||
*
|
||||
* OpenSSH 7.2 was the first release supporting RSA/SHA-2
|
||||
* at all, so this bug is irrelevant to anything before that.
|
||||
*/
|
||||
s->remote_bugs |= BUG_RSA_SHA2_CERT_USERAUTH;
|
||||
bpp_logevent("We believe remote version has SSH-2 "
|
||||
"RSA/SHA-2/certificate userauth bug");
|
||||
}
|
||||
}
|
||||
|
||||
const char *ssh_verstring_get_remote(BinaryPacketProtocol *bpp)
|
||||
|
Reference in New Issue
Block a user