diff --git a/lib/jwt/jwk/rsa.rb b/lib/jwt/jwk/rsa.rb index d1edb690..457b6de7 100644 --- a/lib/jwt/jwk/rsa.rb +++ b/lib/jwt/jwk/rsa.rb @@ -2,17 +2,17 @@ module JWT module JWK - class RSA + class RSA < KeyAbstract attr_reader :keypair - attr_reader :jwk_kid BINARY = 2 KTY = 'RSA'.freeze def initialize(keypair, kid = nil) raise ArgumentError, 'keypair must be of type OpenSSL::PKey::RSA' unless keypair.is_a?(OpenSSL::PKey::RSA) - @jwk_kid = kid + @keypair = keypair + @kid = kid end def private? @@ -24,10 +24,7 @@ def public_key end def kid - return jwk_kid if jwk_kid - sequence = OpenSSL::ASN1::Sequence([OpenSSL::ASN1::Integer.new(public_key.n), - OpenSSL::ASN1::Integer.new(public_key.e)]) - OpenSSL::Digest::SHA256.hexdigest(sequence.to_der) + @kid ||= generate_kid end def export(options = {}) @@ -38,7 +35,7 @@ def export(options = {}) kid: kid } - return ret if options[:include_private] != true + return ret unless private? && options[:include_private] == true ret.merge( d: encode_open_ssl_bn(keypair.d), @@ -50,6 +47,14 @@ def export(options = {}) ) end + private + + def generate_kid + sequence = OpenSSL::ASN1::Sequence([OpenSSL::ASN1::Integer.new(public_key.n), + OpenSSL::ASN1::Integer.new(public_key.e)]) + OpenSSL::Digest::SHA256.hexdigest(sequence.to_der) + end + def encode_open_ssl_bn(key_part) ::Base64.urlsafe_encode64(key_part.to_s(BINARY), padding: false) end @@ -59,6 +64,8 @@ def import(jwk_data) self.new(rsa_pkey(*jwk_attrs(jwk_data, :n, :e, :d, :p, :q, :dp, :dq, :qi)), jwk_data[:kid]) end + private + def jwk_attrs(jwk_data, *attrs) attrs.map do |attr| decode_open_ssl_bn(jwk_data[attr] || jwk_data[attr.to_s]) diff --git a/spec/jwk/rsa_spec.rb b/spec/jwk/rsa_spec.rb index 954e7206..4b6c9274 100644 --- a/spec/jwk/rsa_spec.rb +++ b/spec/jwk/rsa_spec.rb @@ -34,7 +34,7 @@ it 'returns a hash with the public parts of the key' do expect(subject).to be_a Hash expect(subject).to include(:kty, :n, :e, :kid) - expect(subject).not_to include(:d, :p, :dp, :dq,:qi) + expect(subject).not_to include(:d, :p, :dp, :dq, :qi) end end @@ -43,7 +43,7 @@ it 'returns a hash with the public parts of the key' do expect(subject).to be_a Hash expect(subject).to include(:kty, :n, :e, :kid) - expect(subject).not_to include(:d, :p, :dp, :dq,:qi) + expect(subject).not_to include(:d, :p, :dp, :dq, :qi) end end @@ -59,7 +59,7 @@ let(:keypair) { rsa_key } it 'returns a hash with the public AND private parts of the key' do expect(subject).to be_a Hash - expect(subject).to include(:kty, :n, :e, :kid, :d, :p, :q, :dp, :dq,:qi) + expect(subject).to include(:kty, :n, :e, :kid, :d, :p, :q, :dp, :dq, :qi) end end end