Search code examples
rubyopensslcentosjwtopenid-connect

"uninitialized constant OpenSSL::PKey::EC" from Ruby on CentOS 6.6


I have a Rails server application that uses the openid_connect gem. When I attempt to run it on CentOS 6.6, I get:

uninitialized constant OpenSSL::PKey::EC

Here is the full stacktrace:

$ rails server
/home/foo/.rvm/gems/ruby-2.1.3/gems/json-jwt-1.5.1/lib/json/jwk/jwkizable.rb:69:in `<top (required)>': uninitialized constant OpenSSL::PKey::EC (NameError)
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/json-jwt-1.5.1/lib/json/jwt.rb:102:in `<top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/openid_connect-0.9.2/lib/openid_connect/response_object/id_token.rb:1:in `<top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/openid_connect-0.9.2/lib/openid_connect/response_object.rb:7:in `block in <top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/openid_connect-0.9.2/lib/openid_connect/response_object.rb:6:in `each'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/openid_connect-0.9.2/lib/openid_connect/response_object.rb:6:in `<top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/openid_connect-0.9.2/lib/openid_connect/connect_object.rb:52:in `<top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/openid_connect-0.9.2/lib/openid_connect.rb:85:in `<top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler/runtime.rb:76:in `require'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler/runtime.rb:76:in `block (2 levels) in require'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler/runtime.rb:72:in `each'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler/runtime.rb:72:in `block in require'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler/runtime.rb:61:in `each'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler/runtime.rb:61:in `require'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler.rb:134:in `require'
    from /home/foo/tmp/openid_connect_sample/config/application.rb:7:in `<top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/railties-3.2.22/lib/rails/commands.rb:53:in `require'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/railties-3.2.22/lib/rails/commands.rb:53:in `block in <top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/railties-3.2.22/lib/rails/commands.rb:50:in `tap'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/railties-3.2.22/lib/rails/commands.rb:50:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

What does this mean and how I can I get past it?


Solution

  • This problem stems from Red Hat's refusal to include (for fear-of-patent-litigation reasons) certain Elliptic Curve (EC) algorithms in CentOS' default build of OpenSSL.

    Note: According to @Cal's answer, CentOS 6.7 does not have this issue.

    The openid_connect gem is dependent on the json-jwt gem, which uses one of those not-included algorithms.

    Therefore, you need to rebuild a new version of OpenSSL that includes the needed algorithms.

    These are the steps I followed (adapted from here) to build a new OpenSSL on my machine:

    1. cd /usr/src
    2. wget https://www.openssl.org/source/openssl-1.0.1l.tar.gz
    3. yum install autoconf automake (you probably already have these installed)
    4. tar zxvf openssl-1.0.1l.tar.gz
    5. cd openssl-1.0.1l
    6. export CFLAGS="-fPIC"
    7. ./config --prefix=/opt/openssl shared enable-ec enable-ecdh enable-ecdsa
    8. make all
    9. make install

    Now, your Ruby is probably still linked against the old OpenSSL library, so you'll need to rebuild it to link to the new one.

    Are you using rvm? Then great! Any new Rubies you install will build against the new OpenSSL. rvm remove your Ruby and re-install it (or simply install a different ruby version).

    Not using rvm? Then I guess you'll need to rebuild Ruby the traditional way. But you probably already know how to do that, right? If not, you'll need to look in a different tutorial, because we can't cover that here.

    Now reinstall bunder and do a bundle install, and your rails server should now run successfully.

    (If anyone has corrections or clarifications to offer, please leave a comment and I'll make edits as necessary.)