1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-06-30 19:12:48 -05:00

ssh_keyalg: new method 'alternate_ssh_id'.

Previously, the fact that "ssh-rsa" sometimes comes with two subtypes
"rsa-sha2-256" and "rsa-sha2-512" was known to three different parts
of the code - two in userauth and one in transport. Now the knowledge
of what those ids are, which one goes with which signing flags, and
which key types have subtypes at all, is centralised into a method of
the key algorithm, and all those locations just query it.

This will enable the introduction of further key algorithms that have
a parallel upgrade system.
This commit is contained in:
Simon Tatham
2022-04-19 17:27:54 +01:00
parent f9775a7b67
commit cf36b9215f
7 changed files with 77 additions and 33 deletions

View File

@ -640,17 +640,21 @@ static void ssh2_write_kexinit_lists(
alg->u.hk.hkflags = 0;
alg->u.hk.warn = false;
if (keyalg == &ssh_rsa) {
alg = ssh2_kexinit_addalg(&kexlists[KEXLIST_HOSTKEY],
"rsa-sha2-256");
alg->u.hk.hostkey = keyalg;
alg->u.hk.hkflags = SSH_AGENT_RSA_SHA2_256;
alg->u.hk.warn = false;
uint32_t supported_flags = ssh_keyalg_supported_flags(keyalg);
static const uint32_t try_flags[] = {
SSH_AGENT_RSA_SHA2_256,
SSH_AGENT_RSA_SHA2_512,
};
for (size_t i = 0; i < lenof(try_flags); i++) {
if (try_flags[i] & ~supported_flags)
continue; /* these flags not supported */
alg = ssh2_kexinit_addalg(
&kexlists[KEXLIST_HOSTKEY],
ssh_keyalg_alternate_ssh_id(keyalg, try_flags[i]));
alg = ssh2_kexinit_addalg(&kexlists[KEXLIST_HOSTKEY],
"rsa-sha2-512");
alg->u.hk.hostkey = keyalg;
alg->u.hk.hkflags = SSH_AGENT_RSA_SHA2_512;
alg->u.hk.hkflags = try_flags[i];
alg->u.hk.warn = false;
}
}

View File

@ -247,6 +247,31 @@ static PktIn *ssh2_userauth_pop(struct ssh2_userauth_state *s)
return pq_pop(s->ppl.in_pq);
}
static bool ssh2_userauth_signflags(struct ssh2_userauth_state *s,
unsigned *signflags, const char **algname)
{
*signflags = 0; /* default */
const ssh_keyalg *alg = find_pubkey_alg(*algname);
if (!alg)
return false; /* we don't know how to upgrade this */
unsigned supported_flags = ssh_keyalg_supported_flags(alg);
if (s->ppl.bpp->ext_info_rsa_sha512_ok &&
(supported_flags & SSH_AGENT_RSA_SHA2_512)) {
*signflags = SSH_AGENT_RSA_SHA2_512;
} else if (s->ppl.bpp->ext_info_rsa_sha256_ok &&
(supported_flags & SSH_AGENT_RSA_SHA2_256)) {
*signflags = SSH_AGENT_RSA_SHA2_256;
} else {
return false;
}
*algname = ssh_keyalg_alternate_ssh_id(alg, *signflags);
return true;
}
static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
{
struct ssh2_userauth_state *s =
@ -712,18 +737,11 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
* Attempt public-key authentication using a key from Pageant.
*/
s->agent_keyalg = s->agent_keys[s->agent_key_index].algorithm;
s->signflags = 0;
if (ptrlen_eq_string(s->agent_keyalg, "ssh-rsa")) {
/* Try to upgrade ssh-rsa to one of the rsa-sha2-* family,
* if the server has announced support for them. */
if (s->ppl.bpp->ext_info_rsa_sha512_ok) {
s->agent_keyalg = PTRLEN_LITERAL("rsa-sha2-512");
s->signflags = SSH_AGENT_RSA_SHA2_512;
} else if (s->ppl.bpp->ext_info_rsa_sha256_ok) {
s->agent_keyalg = PTRLEN_LITERAL("rsa-sha2-256");
s->signflags = SSH_AGENT_RSA_SHA2_256;
}
}
char *alg_tmp = mkstr(s->agent_keyalg);
const char *newalg = alg_tmp;
if (ssh2_userauth_signflags(s, &s->signflags, &newalg))
s->agent_keyalg = ptrlen_from_asciz(newalg);
sfree(alg_tmp);
s->ppl.bpp->pls->actx = SSH2_PKTCTX_PUBLICKEY;
@ -845,18 +863,10 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
*
* First, try to upgrade its algorithm.
*/
if (!strcmp(s->publickey_algorithm, "ssh-rsa")) {
/* Try to upgrade ssh-rsa to one of the rsa-sha2-* family,
* if the server has announced support for them. */
if (s->ppl.bpp->ext_info_rsa_sha512_ok) {
sfree(s->publickey_algorithm);
s->publickey_algorithm = dupstr("rsa-sha2-512");
s->signflags = SSH_AGENT_RSA_SHA2_512;
} else if (s->ppl.bpp->ext_info_rsa_sha256_ok) {
sfree(s->publickey_algorithm);
s->publickey_algorithm = dupstr("rsa-sha2-256");
s->signflags = SSH_AGENT_RSA_SHA2_256;
}
const char *newalg = s->publickey_algorithm;
if (ssh2_userauth_signflags(s, &s->signflags, &newalg)) {
sfree(s->publickey_algorithm);
s->publickey_algorithm = dupstr(newalg);
}
/*