Skip to content

Public EC key from buffer #498

Open
Open

Description

@voxik

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.

Activity

  1. sergiodj commented on Mar 11, 2022

    @sergiodj

    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.

  2. added a commit that references this issue on Mar 15, 2022
  3. julik commented on Dec 3, 2022

    @julik

    @sergiodj thank you so much for this!

  4. DimaD commented on Dec 30, 2022

    @DimaD

    @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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions