Ruby `generate_key!’: pkeys are immutable on OpenSSL 3.0


Source of the pkeys are immutable on OpenSSL 3.0 error

Ruby 3.1.2 -> Ruby 3.1.3 introduced a change in compilation of the underlying C for OpenSSL::PKey::generate_key! here:

 static VALUE ossl_ec_key_generate_key(VALUE self)
{
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
    rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0");
#else
    EC_KEY *ec;

    GetEC(self, ec);
    if (EC_KEY_generate_key(ec) != 1)
        ossl_raise(eECError, "EC_KEY_generate_key");

    return self;
#endif
}
            

…in which the #if condition now matches.

Observing the error

On macOS, you can observe this between ruby-build versions 3.1.2 and 3.1.3 with the following code:

require 'openssl'
curve='prime256v1'
p ::OpenSSL::PKey::EC.new(curve).generate_key

Ruby 3.1.2:

~/projects via 💎 v3.1.2
❯ ruby generate_key_check.rb
#<OpenSSL::PKey::EC:0x000000010eda90f8 oid=id-ecPublicKey>

Ruby 3.1.3

~/projects via 💎 v3.1.3
❯ ruby generate_key_check.rb
generate_key_check.rb:3:in `generate_key!': pkeys are immutable on OpenSSL 3.0 (OpenSSL::PKey::PKeyError)
	from generate_key_check.rb:3:in `<main>' 

GitHub Actions

Using a major.minor version specification on your .github/.../workflows/*.yml such as the following

 name: My workflow
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: ruby/setup-ruby@v1
      with:
        ruby-version: '3.1' # Not needed with a .ruby-version file
        bundler-cache: true # runs 'bundle install' and caches installed gems automatically
    - run: bundle exec rake

allows the ruby patch versions to advance, so you might want to use '3.1.2' if you have test code that uses generate_key.

 name: My workflow
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: ruby/setup-ruby@v1
      with:
        ruby-version: '3.1.2' # don't upgrade yet
        bundler-cache: true # runs 'bundle install' and caches installed gems automatically
    - run: bundle exec rake

Leave a Reply

%d bloggers like this: