Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Public EC key from buffer #498

Open
voxik opened this issue Feb 25, 2022 · 3 comments
Open

Public EC key from buffer #498

voxik opened this issue Feb 25, 2022 · 3 comments

Comments

@voxik
Copy link

voxik commented Feb 25, 2022

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.

@sergiodj
Copy link

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.

ClearlyClaire added a commit to ClearlyClaire/cose-ruby that referenced this issue Mar 15, 2022
PKey objects are immutable in OpenSSL 3.0, so the `to_pkey` methods
had to be rewritten. Unfortunately, the `openssl` gem does not seem to provide
a convenient way to build PKeys from individual parameters. Instead, this
commits goes through ASN.1 representations of the keys, as suggested in
ruby/openssl#498 (comment)
@julik
Copy link

julik commented Dec 3, 2022

@sergiodj thank you so much for this!

@DimaD
Copy link

DimaD commented Dec 30, 2022

@sergiodj thank you for the code! You saved my evening of bashing my head against the weird #public_key APIs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants