openssl
openssl copied to clipboard
Public EC key from buffer
In net-ssh, there is following code:
public_key_oct = buffer.read_string
begin
key = OpenSSL::PKey::EC.new(OpenSSL::PKey::EC::CurveNameAlias[curve_name_in_key])
group = key.group
point = OpenSSL::PKey::EC::Point.new(group, OpenSSL::BN.new(public_key_oct, 2))
key.public_key = point
return key
rescue OpenSSL::PKey::ECError
raise NotImplementedError, "unsupported key type `#{type}'"
end
Which fails with OpenSSL 3.x:
1) Error:
Transport::Kex::TestEcdhSHA2NistP256#test_exchange_keys_should_return_expected_results_when_successful:
OpenSSL::PKey::PKeyError: pkeys are immutable on OpenSSL 3.0
/builddir/net-ssh/lib/net/ssh/transport/openssl.rb:164:in `public_key='
/builddir/net-ssh/lib/net/ssh/transport/openssl.rb:164:in `read_keyblob'
/builddir/net-ssh/lib/net/ssh/buffer.rb:325:in `read_keyblob'
/builddir/net-ssh/lib/net/ssh/buffer.rb:248:in `read_key'
/builddir/net-ssh/lib/net/ssh/transport/kex/abstract5656.rb:54:in `send_kexinit'
/builddir/net-ssh/lib/net/ssh/transport/kex/abstract.rb:48:in `exchange_keys'
/builddir/net-ssh/test/transport/kex/test_ecdh_sha2_nistp256.rb:96:in `exchange!'
/builddir/net-ssh/test/transport/kex/test_ecdh_sha2_nistp256.rb:18:in `test_exchange_keys_should_return_expected_results_when_successful'
Unfortunately, I struggle to find the right equivalent to implement this with immutable pkeys.
Coincidentally or not, I've been working on this exact part of the code and come up with the following solution:
public_key_oct = buffer.read_string
begin
curvename = OpenSSL::PKey::EC::CurveNameAlias[curve_name_in_key]
group = OpenSSL::PKey::EC::Group.new(curvename)
point = OpenSSL::PKey::EC::Point.new(group, OpenSSL::BN.new(public_key_oct, 2))
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::ObjectId("id-ecPublicKey"),
OpenSSL::ASN1::ObjectId(curvename)
]),
OpenSSL::ASN1::BitString(point.to_octet_string(:uncompressed))
])
key = OpenSSL::PKey::EC.new(asn1.to_der)
return key
I'm not entirely sure whether this is the right solution, but it seems to be and it does fix the failing tests.
@sergiodj thank you so much for this!
@sergiodj thank you for the code! You saved my evening of bashing my head against the weird #public_key APIs