nov / json-jwt

JSON Web Token and its family (JSON Web Signature, JSON Web Encryption and JSON Web Key) in Ruby
MIT License
299 stars 80 forks source link

OpenSSL::PKey interface has changed in Ruby 2.4 #45

Closed cmoylan closed 7 years ago

cmoylan commented 7 years ago

The attributes e, n, d, etc are no longer directly accessible. Those attributes are now set through setter functions: https://ruby-doc.org/stdlib-2.4.1/libdoc/openssl/rdoc/OpenSSL/PKey/RSA.html#method-i-set_key https://ruby-doc.org/stdlib-2.4.1/libdoc/openssl/rdoc/OpenSSL/PKey/RSA.html#method-i-set_factors https://ruby-doc.org/stdlib-2.4.1/libdoc/openssl/rdoc/OpenSSL/PKey/RSA.html#method-i-set_crt_params

I had a pull request #44 to update JWK#to_rsa_key but it breaks for versions of Ruby < 2.4. The simplest solution is to check the OpenSSL version before attempting to set the key attributes. If you don't have any objections or a better solution, I'm happy to submit a PR with the change.

nov commented 7 years ago

Even under ruby 2.4.1, I can execute this code.

e = 'AQAB'
n = 'xT8fom6CyF90d4FaipIZuYD6jC7Eie6JpPAAgKy7qWjzzG-Aof9_ULPFabxMGP_M4Y83iV8dI8swEI4dfkY8zzgLfvZIcwOOy6KQvdWQcas8rrLMTkeT2pfY-abG1awvuz3aEpaibia1-UF80IvYHPpr6_4b5YAPQ3LF4WZHd1gEvQ1WC-rBiWbmVIC-MSIMeQHGISM0SVxa-p3LtsQGbgb0VsaTSbWHHCwKAfLdYLmrOh0bGEtC0aZoAmoBMefEw7FVTQmyBHiJtnuZ7oPGjSMGlP1DSfa6GkUYw-qA7OBoJaYAzZiboIiUyAkPQE5QiBipW-DIoiBzUn_n12fIhw'

key = OpenSSL::PKey::RSA.new
key.e = OpenSSL::BN.new(UrlSafeBase64.decode64(e), 2)
key.n = OpenSSL::BN.new(UrlSafeBase64.decode64(n), 2)
puts key.to_pem

FYI: my ruby, openssl, openssl gem versions are here.

nov@tov json-jwt (master)$ pry
[1] pry(main)> require 'openssl'
=> true
[2] pry(main)> RUBY_VERSION
=> "2.4.1"
[3] pry(main)> OpenSSL::OPENSSL_VERSION
=> "OpenSSL 1.0.2k  26 Jan 2017"
[4] pry(main)> OpenSSL::VERSION
=> "2.0.3"
cmoylan commented 7 years ago

That's odd. If I run the specs for the gem on 2.4.1 I get a bunch of failures with:

      Failure/Error: key.e = e

      NoMethodError:
        undefined method `e=' for #<OpenSSL::PKey::RSA:0x007fba39cb1858>
        Did you mean?  e

For the time being, I'll stay on 2.3 which doesn't cause any issues. I wonder why I have problems on 2.4 and you don't. I was on MRI 2.4.1, installed through RVM.

nov commented 7 years ago

Checking Ruby version is't sufficient. You need to check your OpenSSL::OPENSSL_VERSION (it also can be confirmed via openssl version in your terminal), and OpenSSL::VERSION too.

Since my local MacBook and travis server passes the specs, I guess your machine have buggy version of them. https://travis-ci.org/nov/json-jwt/jobs/217231907

ps. If you are familiar with C, you can confirm the methods are defined here. https://github.com/ruby/openssl/blob/master/ext/openssl/ossl_pkey_rsa.c#L735

cmoylan commented 7 years ago

Ok, thank you.

fightingtheboss commented 7 years ago

I'm not sure why this was closed, but when running the same setup as @nov, I'm getting a large number of deprecation warnings on these methods.

/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:105: warning: #e= is deprecated; use #set_key
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:106: warning: #n= is deprecated; use #set_key
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:107: warning: #d= is deprecated; use #set_key
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:108: warning: #p= is deprecated; use #set_factors
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:109: warning: #q= is deprecated; use #set_factors
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:110: warning: #dmp1= is deprecated; use #set_crt_params
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:111: warning: #dmq1= is deprecated; use #set_crt_params
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:112: warning: #iqmp= is deprecated; use #set_crt_params

Everything still works, but clearly these methods are going to be deprecated. The initial suggestion of switching on the version of OpenSSL might still be a good one?

nov commented 7 years ago

which version of openssl gem and openssl otself are you using?

fightingtheboss commented 7 years ago

As you mentioned in your post, here's the output in my local:

[1] pry(main)> require 'openssl'
=> true
[2] pry(main)> RUBY_VERSION
=> "2.4.1"
[3] pry(main)> OpenSSL::OPENSSL_VERSION
=> "OpenSSL 1.0.2k  26 Jan 2017"
[4] pry(main)> OpenSSL::VERSION
=> "2.0.3"

I get the same output when running those lines in irb, as well as when running those lines in rails console.

I don't see any of the warnings (or exceptions) when running the example that you posted here: https://github.com/nov/json-jwt/issues/45#issuecomment-290750685

So I can't really explain it yet. I'm seeing the warnings when running the tests for a fork of https://github.com/nsarno/knock where I've integrated json-jwt for supporting JWKs. You can clone the repo and run the tests with rake test on the support_jwks_keys branch:

https://github.com/bitmaker-internal/knock/tree/support_jwks_keys

Let me know if you need me to dig further!

nov commented 7 years ago

If you don't get warnings with my gist, the issue is in your side. Some of your gems in Gemfile.lock is deprecating official openssl gem method?

nov

On May 29, 2017, at 1:17, Mina Mikhail notifications@github.com wrote:

As you mentioned in your post, here's the output in my local:

[1] pry(main)> require 'openssl' => true [2] pry(main)> RUBY_VERSION => "2.4.1" [3] pry(main)> OpenSSL::OPENSSL_VERSION => "OpenSSL 1.0.2k 26 Jan 2017" [4] pry(main)> OpenSSL::VERSION => "2.0.3" I get the same output when running those lines in irb, as well as when running those lines in rails console.

I don't see any of the warnings (or exceptions) when running the example that you posted here: #45 (comment)

So I can't really explain it yet. I'm seeing the warnings when running the tests for a fork of https://github.com/nsarno/knock where I've integrated json-jwt for supporting JWKs. You can clone the repo and run the tests with rake test on the support_jwks_keys branch:

https://github.com/bitmaker-internal/knock/tree/support_jwks_keys

Let me know if you need me to dig further!

― You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub, or mute the thread.

nov commented 7 years ago

Ah, I found it. https://github.com/ruby/openssl/commit/7ea72f1f50849ad0c36e08c0ac70bbdba1d96169#diff-915017dbfe6a2e8cd9741502cfe8f759

fightingtheboss commented 7 years ago

Beauty! Nice sleuthing!