summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Chopin <simon.chopin@canonical.com>2022-04-08 09:32:24 +0200
committerFlorian Wininger <fw.centrale@gmail.com>2022-04-29 14:32:38 +0200
commit763b9da5bc0fefc2345b76598d696e8b02a3eecb (patch)
treef1cd6efc8036a838231039f04fb9d5431759db1b
parent5ea15d562540a3d5dc24e2d26a9778da8568978a (diff)
downloadnet-ssh-763b9da5bc0fefc2345b76598d696e8b02a3eecb.tar.gz
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 <lucas.kanashiro@canonical.com>
-rw-r--r--lib/net/ssh/buffer.rb31
-rw-r--r--test/test_buffer.rb28
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