1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-01 03:22:48 -05:00

Pad RSA signature blobs if they're made with SHA-2.

The "rsa-sha2-256" and "rsa-sha2-512" algorithms, as defined by RFC
8332, differ in one detail from "ssh-rsa" in addition to the change of
hash function. They also specify that the signature integer should be
encoded using the same number of bytes as the key modulus, even if
that means giving it a leading zero byte (or even more than one).

I hadn't noticed this, and had assumed that unrelated details wouldn't
have changed. But they had. Thanks to Ilia Mirkin for pointing this
out.

Nobody has previously reported a problem, so very likely most servers
are forgiving of people making this mistake! But now it's been pointed
out, we should comply with the spec. (Especially since the new spec is
more sensible, and only historical inertia justified sticking to the
old one.)
This commit is contained in:
Simon Tatham
2024-07-08 21:49:39 +01:00
parent b7174344e6
commit a5bcf3d384
2 changed files with 86 additions and 1 deletions

View File

@ -837,7 +837,36 @@ static void rsa2_sign(ssh_key *key, ptrlen data,
mp_free(in);
put_stringz(bs, sign_alg_name);
nbytes = (mp_get_nbits(out) + 7) / 8;
if (flags == 0) {
/*
* Original "ssh-rsa", per RFC 4253 section 6.6, stores the
* signature integer in a string without padding - not even
* the leading zero byte that an ordinary SSH-2 mpint would
* require to avoid looking like two's complement.
*
* "The value for 'rsa_signature_blob' is encoded as a string
* containing s (which is an integer, without lengths or
* padding, unsigned, and in network byte order)."
*/
nbytes = (mp_get_nbits(out) + 7) / 8;
} else {
/*
* The SHA-256 and SHA-512 signature systems, per RFC 8332
* section 3, should be padded to the length of the key
* modulus.
*
* "The value for 'rsa_signature_blob' is encoded as a string
* that contains an octet string S (which is the output of
* RSASSA-PKCS1-v1_5) and that has the same length (in octets)
* as the RSA modulus."
*
* Awkwardly, RFC 8332 doesn't say whether that means the
* 'raw' length of the RSA modulus (that is, ceil(n/8) for an
* n-bit key) or the length it would occupy as an SSH-2 mpint.
* My interpretation is the former.
*/
nbytes = (mp_get_nbits(rsa->modulus) + 7) / 8;
}
put_uint32(bs, nbytes);
for (size_t i = 0; i < nbytes; i++)
put_byte(bs, mp_get_byte(out, nbytes - 1 - i));