diff --git a/lib/ssh_data/public_key/rsa.rb b/lib/ssh_data/public_key/rsa.rb index 29f4a9c..caf5de1 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 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 + 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