From 98ccff914983370a82208263c866482928031b88 Mon Sep 17 00:00:00 2001 From: Simon Chopin Date: Fri, 8 Apr 2022 09:32:24 +0200 Subject: buffer: create DSA keys by loading PEM data directly The OpenSSL 3.0 changes don't allow for us to modify the private key details directly, and there are no dedicated constructors as of Ruby 3.0, so we need to actually create a PEM certificate in-memory and load that instead. To add insult to injury, contrary to other types of keys such as RSA, we need to actually build the full PEM data and not just pack the numbers in a simple sequence, making the code even a bit more complicated. Co-authored-by: Lucas Kanashiro --- lib/net/ssh/buffer.rb | 31 ++++++++++++++++++------------- test/test_buffer.rb | 28 ++++++++++++++++++---------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/lib/net/ssh/buffer.rb b/lib/net/ssh/buffer.rb index 8a67d3e..42cc892 100644 --- a/lib/net/ssh/buffer.rb +++ b/lib/net/ssh/buffer.rb @@ -301,19 +301,24 @@ module Net when /^(.*)-cert-v01@openssh\.com$/ key = Net::SSH::Authentication::Certificate.read_certblob(self, $1) when /^ssh-dss$/ - key = OpenSSL::PKey::DSA.new - if key.respond_to?(:set_pqg) - key.set_pqg(read_bignum, read_bignum, read_bignum) - else - key.p = read_bignum - key.q = read_bignum - key.g = read_bignum - end - if key.respond_to?(:set_key) - key.set_key(read_bignum, nil) - else - key.pub_key = read_bignum - end + p = read_bignum + q = read_bignum + g = read_bignum + pub_key = read_bignum + + asn1 = OpenSSL::ASN1::Sequence.new([ + OpenSSL::ASN1::Sequence.new([ + OpenSSL::ASN1::ObjectId.new('DSA'), + OpenSSL::ASN1::Sequence.new([ + OpenSSL::ASN1::Integer.new(p), + OpenSSL::ASN1::Integer.new(q), + OpenSSL::ASN1::Integer.new(g) + ]), + ]), + OpenSSL::ASN1::BitString.new(OpenSSL::ASN1::Integer.new(pub_key).to_der) + ]) + + key = OpenSSL::PKey::DSA.new(asn1.to_der) when /^ssh-rsa$/ e = read_bignum n = read_bignum diff --git a/test/test_buffer.rb b/test/test_buffer.rb index b6968bb..1ff2028 100644 --- a/test/test_buffer.rb +++ b/test/test_buffer.rb @@ -319,16 +319,24 @@ class TestBuffer < NetSSHTest def test_write_dss_key_should_write_argument_to_end_of_buffer buffer = new("start") - key = OpenSSL::PKey::DSA.new - if key.respond_to?(:set_pqg) - key.set_pqg(0xffeeddccbbaa9988, 0x7766554433221100, 0xffddbb9977553311) - key.set_key(0xeeccaa8866442200, nil) - else - key.p = 0xffeeddccbbaa9988 - key.q = 0x7766554433221100 - key.g = 0xffddbb9977553311 - key.pub_key = 0xeeccaa8866442200 - end + p = 0xffeeddccbbaa9988 + q = 0x7766554433221100 + g = 0xffddbb9977553311 + pub_key = 0xeeccaa8866442200 + + asn1 = OpenSSL::ASN1::Sequence.new([ + OpenSSL::ASN1::Sequence.new([ + OpenSSL::ASN1::ObjectId.new('DSA'), + OpenSSL::ASN1::Sequence.new([ + OpenSSL::ASN1::Integer.new(p), + OpenSSL::ASN1::Integer.new(q), + OpenSSL::ASN1::Integer.new(g) + ]), + ]), + OpenSSL::ASN1::BitString.new(OpenSSL::ASN1::Integer.new(pub_key).to_der) + ]) + + key = OpenSSL::PKey::DSA.new(asn1.to_der) buffer.write_key(key) assert_equal "start\0\0\0\7ssh-dss\0\0\0\011\0\xff\xee\xdd\xcc\xbb\xaa\x99\x88\0\0\0\010\x77\x66\x55\x44\x33\x22\x11\x00\0\0\0\011\0\xff\xdd\xbb\x99\x77\x55\x33\x11\0\0\0\011\0\xee\xcc\xaa\x88\x66\x44\x22\x00", buffer.to_s -- cgit v1.2.1