mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-08 08:58:00 +00:00
Support receiving RFC 8332 rsa-sha2-* host keys.
This is the cleanest part of the RFC 8332 support: I simply add two more RSA-based SSH-2 key algorithm vtables, both almost identical to the existing one, with different ssh_id strings and signature flags. Adding those to the HOSTKEY_ALGORITHMS list macro is enough to ensure that we advertise support for the new identifiers in our client KEXINIT, select the appropriate algorithm if the server announces one or both of them too, and use the right version of the signature validation.
This commit is contained in:
parent
40e648db46
commit
b22e26f07b
2
ssh.h
2
ssh.h
@ -997,6 +997,8 @@ extern const ssh_kex ssh_ec_kex_nistp521;
|
||||
extern const ssh_kexes ssh_ecdh_kex;
|
||||
extern const ssh_keyalg ssh_dss;
|
||||
extern const ssh_keyalg ssh_rsa;
|
||||
extern const ssh_keyalg ssh_rsa_sha256;
|
||||
extern const ssh_keyalg ssh_rsa_sha512;
|
||||
extern const ssh_keyalg ssh_ecdsa_ed25519;
|
||||
extern const ssh_keyalg ssh_ecdsa_ed448;
|
||||
extern const ssh_keyalg ssh_ecdsa_nistp256;
|
||||
|
@ -52,6 +52,8 @@ struct kexinit_algorithm {
|
||||
X(HK_ECDSA, ssh_ecdsa_nistp384) \
|
||||
X(HK_ECDSA, ssh_ecdsa_nistp521) \
|
||||
X(HK_DSA, ssh_dss) \
|
||||
X(HK_RSA, ssh_rsa_sha512) \
|
||||
X(HK_RSA, ssh_rsa_sha256) \
|
||||
X(HK_RSA, ssh_rsa) \
|
||||
/* end of list */
|
||||
#define COUNT_HOSTKEY_ALGORITHM(type, alg) +1
|
||||
|
71
sshrsa.c
71
sshrsa.c
@ -456,9 +456,13 @@ void freersakey(RSAKey *key)
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Implementation of the ssh-rsa signing key type.
|
||||
* Implementation of the ssh-rsa signing key type family.
|
||||
*/
|
||||
|
||||
struct ssh2_rsa_extra {
|
||||
unsigned signflags;
|
||||
};
|
||||
|
||||
static void rsa2_freekey(ssh_key *key); /* forward reference */
|
||||
|
||||
static ssh_key *rsa2_new_pub(const ssh_keyalg *self, ptrlen data)
|
||||
@ -471,7 +475,7 @@ static ssh_key *rsa2_new_pub(const ssh_keyalg *self, ptrlen data)
|
||||
return NULL;
|
||||
|
||||
rsa = snew(RSAKey);
|
||||
rsa->sshk.vt = &ssh_rsa;
|
||||
rsa->sshk.vt = self;
|
||||
rsa->exponent = get_mp_ssh2(src);
|
||||
rsa->modulus = get_mp_ssh2(src);
|
||||
rsa->private_exponent = NULL;
|
||||
@ -729,8 +733,10 @@ static bool rsa2_verify(ssh_key *key, ptrlen sig, ptrlen data)
|
||||
ptrlen type, in_pl;
|
||||
mp_int *in, *out;
|
||||
|
||||
/* If we need to support variable flags on verify, this is where they go */
|
||||
const ssh_hashalg *halg = rsa2_hash_alg_for_flags(0, NULL);
|
||||
const struct ssh2_rsa_extra *extra =
|
||||
(const struct ssh2_rsa_extra *)key->vt->extra;
|
||||
|
||||
const ssh_hashalg *halg = rsa2_hash_alg_for_flags(extra->signflags, NULL);
|
||||
|
||||
/* Start by making sure the key is even long enough to encode a
|
||||
* signature. If not, everything fails to verify. */
|
||||
@ -751,7 +757,7 @@ static bool rsa2_verify(ssh_key *key, ptrlen sig, ptrlen data)
|
||||
* mp_from_bytes_be, which will tolerate anything.
|
||||
*/
|
||||
in_pl = get_string(src);
|
||||
if (get_err(src) || !ptrlen_eq_string(type, "ssh-rsa"))
|
||||
if (get_err(src) || !ptrlen_eq_string(type, key->vt->ssh_id))
|
||||
return false;
|
||||
|
||||
in = mp_from_bytes_be(in_pl);
|
||||
@ -780,6 +786,10 @@ static void rsa2_sign(ssh_key *key, ptrlen data,
|
||||
const ssh_hashalg *halg;
|
||||
const char *sign_alg_name;
|
||||
|
||||
const struct ssh2_rsa_extra *extra =
|
||||
(const struct ssh2_rsa_extra *)key->vt->extra;
|
||||
flags |= extra->signflags;
|
||||
|
||||
halg = rsa2_hash_alg_for_flags(flags, &sign_alg_name);
|
||||
|
||||
nbytes = (mp_get_nbits(rsa->modulus) + 7) / 8;
|
||||
@ -816,23 +826,46 @@ static char *rsa2_invalid(ssh_key *key, unsigned flags)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct ssh2_rsa_extra
|
||||
rsa_extra = { 0 },
|
||||
rsa_sha256_extra = { SSH_AGENT_RSA_SHA2_256 },
|
||||
rsa_sha512_extra = { SSH_AGENT_RSA_SHA2_512 };
|
||||
|
||||
#define COMMON_KEYALG_FIELDS \
|
||||
.new_pub = rsa2_new_pub, \
|
||||
.new_priv = rsa2_new_priv, \
|
||||
.new_priv_openssh = rsa2_new_priv_openssh, \
|
||||
.freekey = rsa2_freekey, \
|
||||
.invalid = rsa2_invalid, \
|
||||
.sign = rsa2_sign, \
|
||||
.verify = rsa2_verify, \
|
||||
.public_blob = rsa2_public_blob, \
|
||||
.private_blob = rsa2_private_blob, \
|
||||
.openssh_blob = rsa2_openssh_blob, \
|
||||
.cache_str = rsa2_cache_str, \
|
||||
.components = rsa2_components, \
|
||||
.pubkey_bits = rsa2_pubkey_bits, \
|
||||
.cache_id = "rsa2"
|
||||
|
||||
const ssh_keyalg ssh_rsa = {
|
||||
.new_pub = rsa2_new_pub,
|
||||
.new_priv = rsa2_new_priv,
|
||||
.new_priv_openssh = rsa2_new_priv_openssh,
|
||||
.freekey = rsa2_freekey,
|
||||
.invalid = rsa2_invalid,
|
||||
.sign = rsa2_sign,
|
||||
.verify = rsa2_verify,
|
||||
.public_blob = rsa2_public_blob,
|
||||
.private_blob = rsa2_private_blob,
|
||||
.openssh_blob = rsa2_openssh_blob,
|
||||
.cache_str = rsa2_cache_str,
|
||||
.components = rsa2_components,
|
||||
.pubkey_bits = rsa2_pubkey_bits,
|
||||
COMMON_KEYALG_FIELDS,
|
||||
.ssh_id = "ssh-rsa",
|
||||
.cache_id = "rsa2",
|
||||
.supported_flags = SSH_AGENT_RSA_SHA2_256 | SSH_AGENT_RSA_SHA2_512,
|
||||
.extra = &rsa_extra,
|
||||
};
|
||||
|
||||
const ssh_keyalg ssh_rsa_sha256 = {
|
||||
COMMON_KEYALG_FIELDS,
|
||||
.ssh_id = "rsa-sha2-256",
|
||||
.supported_flags = 0,
|
||||
.extra = &rsa_sha256_extra,
|
||||
};
|
||||
|
||||
const ssh_keyalg ssh_rsa_sha512 = {
|
||||
COMMON_KEYALG_FIELDS,
|
||||
.ssh_id = "rsa-sha2-512",
|
||||
.supported_flags = 0,
|
||||
.extra = &rsa_sha512_extra,
|
||||
};
|
||||
|
||||
RSAKey *ssh_rsakex_newkey(ptrlen data)
|
||||
|
Loading…
Reference in New Issue
Block a user