From 9b29a3bc55000edd818f4a0806581cc4df49c6ea Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 24 Apr 2023 13:06:15 -0400 Subject: [PATCH 1/2] Handle diminished RSA signatures. If an RSA signature length, in bytes, is less than the RSA modulus length, in bytes, prepend the signature with zeros. OpenSSH supports diminished RSA signatures where "leading" zeros do not need to be explicitly encoded. This handles RSA signatures similarly to how OpenSSH handles them. --- lib/ssh_data/public_key/rsa.rb | 6 ++++++ spec/public_key/rsa_spec.rb | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lib/ssh_data/public_key/rsa.rb b/lib/ssh_data/public_key/rsa.rb index 29f4a9c..8a95c53 100644 --- a/lib/ssh_data/public_key/rsa.rb +++ b/lib/ssh_data/public_key/rsa.rb @@ -37,6 +37,12 @@ def verify(signed_data, signature) raise DecodeError, "bad signature algorithm: #{sig_algo.inspect}" end + # OpenSSH compatibility: if a the number of bits in the signature is less than the number of bits of the RSA + # modulus, prepend the signature with zeros. + # See https://github.com/openssh/openssh-portable/blob/ac383f3a5c6f529a2e8a5bc44af79a08c7da294e/ssh-rsa.c#L531 + difference = n.num_bytes - raw_sig.bytesize + raw_sig = "\0" * difference + raw_sig if difference.positive? + openssl.verify(digest.new, raw_sig, signed_data) end diff --git a/spec/public_key/rsa_spec.rb b/spec/public_key/rsa_spec.rb index 5e21e03..6ec2299 100644 --- a/spec/public_key/rsa_spec.rb +++ b/spec/public_key/rsa_spec.rb @@ -55,6 +55,23 @@ expect(subject.verify("wrong", sig)).to be(false) end + it "can verify a diminished signature" do + diminished_signature_hex = + "0000000c7273612d736861322d323536000000ff897e8dc2fe891236d4378c10" + + "9f438b8a431afd9573a1fc62c07748494c38200cc30f2f6438480ca317aa6e1a" + + "c91b8352e24f325785e06e1713ee44a3b039de7af6249bac279ff887258e7dde" + + "fa16f4f9bdbf817499c0c6ae0ef9e10fe7125215ee04091c1f03004546b45bb9" + + "8e2240a481af97eba10175ca7a81a13300e5bd535db06eedbcb2491f76327695" + + "75db2b36b6a1d5975e276ce308c54134a9ce0cfc255f88b010d9e07ce5624ce9" + + "84093b2b8265bd1552709a224a64e70ef7166512d05a2719b53a9f3210f8103a" + + "1a57fb5a2c8624775e3641b2c204f6b49b8d98fe46080dbcd6cef2fead6f22a9" + + "5edd139db34728bce4b00ca8da03c01c653cff" + diminished_signature = [diminished_signature_hex].pack("H*") + content = "52b85cf8b49ec9d722f3b233215497acc2812f943c2055d92ae858da22cdebcf" + + expect(openssh_key.verify(content, diminished_signature)).to be(true) + end + it "can parse openssh-generate keys" do expect { openssh_key }.not_to raise_error end From 24e07071a10da0c36f22ff40e100dd09b7379546 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Tue, 25 Apr 2023 10:52:46 -0400 Subject: [PATCH 2/2] Update comment to use bytes instead of bits. --- lib/ssh_data/public_key/rsa.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ssh_data/public_key/rsa.rb b/lib/ssh_data/public_key/rsa.rb index 8a95c53..caf5de1 100644 --- a/lib/ssh_data/public_key/rsa.rb +++ b/lib/ssh_data/public_key/rsa.rb @@ -37,7 +37,7 @@ def verify(signed_data, signature) raise DecodeError, "bad signature algorithm: #{sig_algo.inspect}" end - # OpenSSH compatibility: if a the number of bits in the signature is less than the number of bits of the RSA + # OpenSSH compatibility: if a the number of bytes in the signature is less than the number of bytes of the RSA # modulus, prepend the signature with zeros. # See https://github.com/openssh/openssh-portable/blob/ac383f3a5c6f529a2e8a5bc44af79a08c7da294e/ssh-rsa.c#L531 difference = n.num_bytes - raw_sig.bytesize