jwt 2.1.0 → 2.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/workflows/test.yml +74 -0
- data/.gitignore +1 -1
- data/.rspec +1 -0
- data/.rubocop.yml +15 -16
- data/.rubocop_todo.yml +191 -0
- data/{.ebert.yml → .sourcelevel.yml} +1 -1
- data/AUTHORS +101 -0
- data/Appraisals +10 -0
- data/CHANGELOG.md +247 -19
- data/Gemfile +2 -0
- data/README.md +154 -89
- data/Rakefile +4 -1
- data/lib/jwt.rb +9 -42
- data/lib/jwt/algos.rb +44 -0
- data/lib/jwt/algos/ecdsa.rb +1 -1
- data/lib/jwt/algos/hmac.rb +1 -0
- data/lib/jwt/algos/none.rb +15 -0
- data/lib/jwt/algos/ps.rb +43 -0
- data/lib/jwt/algos/unsupported.rb +5 -4
- data/lib/jwt/base64.rb +19 -0
- data/lib/jwt/claims_validator.rb +35 -0
- data/lib/jwt/decode.rb +85 -25
- data/lib/jwt/encode.rb +43 -25
- data/lib/jwt/error.rb +4 -0
- data/lib/jwt/json.rb +18 -0
- data/lib/jwt/jwk.rb +51 -0
- data/lib/jwt/jwk/ec.rb +150 -0
- data/lib/jwt/jwk/hmac.rb +58 -0
- data/lib/jwt/jwk/key_base.rb +18 -0
- data/lib/jwt/jwk/key_finder.rb +62 -0
- data/lib/jwt/jwk/rsa.rb +115 -0
- data/lib/jwt/security_utils.rb +6 -0
- data/lib/jwt/signature.rb +9 -20
- data/lib/jwt/verify.rb +1 -5
- data/lib/jwt/version.rb +2 -2
- data/ruby-jwt.gemspec +4 -7
- metadata +30 -109
- data/.codeclimate.yml +0 -20
- data/.reek.yml +0 -40
- data/.travis.yml +0 -14
- data/Manifest +0 -8
- data/spec/fixtures/certs/ec256-private.pem +0 -8
- data/spec/fixtures/certs/ec256-public.pem +0 -4
- data/spec/fixtures/certs/ec256-wrong-private.pem +0 -8
- data/spec/fixtures/certs/ec256-wrong-public.pem +0 -4
- data/spec/fixtures/certs/ec384-private.pem +0 -9
- data/spec/fixtures/certs/ec384-public.pem +0 -5
- data/spec/fixtures/certs/ec384-wrong-private.pem +0 -9
- data/spec/fixtures/certs/ec384-wrong-public.pem +0 -5
- data/spec/fixtures/certs/ec512-private.pem +0 -10
- data/spec/fixtures/certs/ec512-public.pem +0 -6
- data/spec/fixtures/certs/ec512-wrong-private.pem +0 -10
- data/spec/fixtures/certs/ec512-wrong-public.pem +0 -6
- data/spec/fixtures/certs/rsa-1024-private.pem +0 -15
- data/spec/fixtures/certs/rsa-1024-public.pem +0 -6
- data/spec/fixtures/certs/rsa-2048-private.pem +0 -27
- data/spec/fixtures/certs/rsa-2048-public.pem +0 -9
- data/spec/fixtures/certs/rsa-2048-wrong-private.pem +0 -27
- data/spec/fixtures/certs/rsa-2048-wrong-public.pem +0 -9
- data/spec/fixtures/certs/rsa-4096-private.pem +0 -51
- data/spec/fixtures/certs/rsa-4096-public.pem +0 -14
- data/spec/integration/readme_examples_spec.rb +0 -202
- data/spec/jwt/verify_spec.rb +0 -232
- data/spec/jwt_spec.rb +0 -315
- data/spec/spec_helper.rb +0 -28
data/lib/jwt/error.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
module JWT
|
4
4
|
class EncodeError < StandardError; end
|
5
5
|
class DecodeError < StandardError; end
|
6
|
+
class RequiredDependencyError < StandardError; end
|
7
|
+
|
6
8
|
class VerificationError < DecodeError; end
|
7
9
|
class ExpiredSignature < DecodeError; end
|
8
10
|
class IncorrectAlgorithm < DecodeError; end
|
@@ -13,4 +15,6 @@ module JWT
|
|
13
15
|
class InvalidSubError < DecodeError; end
|
14
16
|
class InvalidJtiError < DecodeError; end
|
15
17
|
class InvalidPayload < DecodeError; end
|
18
|
+
|
19
|
+
class JWKError < DecodeError; end
|
16
20
|
end
|
data/lib/jwt/json.rb
ADDED
data/lib/jwt/jwk.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'jwk/key_finder'
|
4
|
+
|
5
|
+
module JWT
|
6
|
+
module JWK
|
7
|
+
class << self
|
8
|
+
def import(jwk_data)
|
9
|
+
jwk_kty = jwk_data[:kty] || jwk_data['kty']
|
10
|
+
raise JWT::JWKError, 'Key type (kty) not provided' unless jwk_kty
|
11
|
+
|
12
|
+
mappings.fetch(jwk_kty.to_s) do |kty|
|
13
|
+
raise JWT::JWKError, "Key type #{kty} not supported"
|
14
|
+
end.import(jwk_data)
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_from(keypair)
|
18
|
+
mappings.fetch(keypair.class) do |klass|
|
19
|
+
raise JWT::JWKError, "Cannot create JWK from a #{klass.name}"
|
20
|
+
end.new(keypair)
|
21
|
+
end
|
22
|
+
|
23
|
+
def classes
|
24
|
+
@mappings = nil # reset the cached mappings
|
25
|
+
@classes ||= []
|
26
|
+
end
|
27
|
+
|
28
|
+
alias new create_from
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def mappings
|
33
|
+
@mappings ||= generate_mappings
|
34
|
+
end
|
35
|
+
|
36
|
+
def generate_mappings
|
37
|
+
classes.each_with_object({}) do |klass, hash|
|
38
|
+
next unless klass.const_defined?('KTYS')
|
39
|
+
Array(klass::KTYS).each do |kty|
|
40
|
+
hash[kty] = klass
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
require_relative 'jwk/key_base'
|
49
|
+
require_relative 'jwk/ec'
|
50
|
+
require_relative 'jwk/rsa'
|
51
|
+
require_relative 'jwk/hmac'
|
data/lib/jwt/jwk/ec.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module JWT
|
6
|
+
module JWK
|
7
|
+
class EC < KeyBase
|
8
|
+
extend Forwardable
|
9
|
+
def_delegators :@keypair, :public_key
|
10
|
+
|
11
|
+
KTY = 'EC'.freeze
|
12
|
+
KTYS = [KTY, OpenSSL::PKey::EC].freeze
|
13
|
+
BINARY = 2
|
14
|
+
|
15
|
+
def initialize(keypair, kid = nil)
|
16
|
+
raise ArgumentError, 'keypair must be of type OpenSSL::PKey::EC' unless keypair.is_a?(OpenSSL::PKey::EC)
|
17
|
+
|
18
|
+
kid ||= generate_kid(keypair)
|
19
|
+
super(keypair, kid)
|
20
|
+
end
|
21
|
+
|
22
|
+
def private?
|
23
|
+
@keypair.private_key?
|
24
|
+
end
|
25
|
+
|
26
|
+
def export(options = {})
|
27
|
+
crv, x_octets, y_octets = keypair_components(keypair)
|
28
|
+
exported_hash = {
|
29
|
+
kty: KTY,
|
30
|
+
crv: crv,
|
31
|
+
x: encode_octets(x_octets),
|
32
|
+
y: encode_octets(y_octets),
|
33
|
+
kid: kid
|
34
|
+
}
|
35
|
+
return exported_hash unless private? && options[:include_private] == true
|
36
|
+
|
37
|
+
append_private_parts(exported_hash)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def append_private_parts(the_hash)
|
43
|
+
octets = keypair.private_key.to_bn.to_s(BINARY)
|
44
|
+
the_hash.merge(
|
45
|
+
d: encode_octets(octets)
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
def generate_kid(ec_keypair)
|
50
|
+
_crv, x_octets, y_octets = keypair_components(ec_keypair)
|
51
|
+
sequence = OpenSSL::ASN1::Sequence([OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(x_octets, BINARY)),
|
52
|
+
OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(y_octets, BINARY))])
|
53
|
+
OpenSSL::Digest::SHA256.hexdigest(sequence.to_der)
|
54
|
+
end
|
55
|
+
|
56
|
+
def keypair_components(ec_keypair)
|
57
|
+
encoded_point = ec_keypair.public_key.to_bn.to_s(BINARY)
|
58
|
+
case ec_keypair.group.curve_name
|
59
|
+
when 'prime256v1'
|
60
|
+
crv = 'P-256'
|
61
|
+
x_octets, y_octets = encoded_point.unpack('xa32a32')
|
62
|
+
when 'secp384r1'
|
63
|
+
crv = 'P-384'
|
64
|
+
x_octets, y_octets = encoded_point.unpack('xa48a48')
|
65
|
+
when 'secp521r1'
|
66
|
+
crv = 'P-521'
|
67
|
+
x_octets, y_octets = encoded_point.unpack('xa66a66')
|
68
|
+
else
|
69
|
+
raise Jwt::JWKError, "Unsupported curve '#{ec_keypair.group.curve_name}'"
|
70
|
+
end
|
71
|
+
[crv, x_octets, y_octets]
|
72
|
+
end
|
73
|
+
|
74
|
+
def encode_octets(octets)
|
75
|
+
::JWT::Base64.url_encode(octets)
|
76
|
+
end
|
77
|
+
|
78
|
+
def encode_open_ssl_bn(key_part)
|
79
|
+
::JWT::Base64.url_encode(key_part.to_s(BINARY))
|
80
|
+
end
|
81
|
+
|
82
|
+
class << self
|
83
|
+
def import(jwk_data)
|
84
|
+
# See https://tools.ietf.org/html/rfc7518#section-6.2.1 for an
|
85
|
+
# explanation of the relevant parameters.
|
86
|
+
|
87
|
+
jwk_crv, jwk_x, jwk_y, jwk_d, jwk_kid = jwk_attrs(jwk_data, %i[crv x y d kid])
|
88
|
+
raise Jwt::JWKError, 'Key format is invalid for EC' unless jwk_crv && jwk_x && jwk_y
|
89
|
+
|
90
|
+
new(ec_pkey(jwk_crv, jwk_x, jwk_y, jwk_d), jwk_kid)
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_openssl_curve(crv)
|
94
|
+
# The JWK specs and OpenSSL use different names for the same curves.
|
95
|
+
# See https://tools.ietf.org/html/rfc5480#section-2.1.1.1 for some
|
96
|
+
# pointers on different names for common curves.
|
97
|
+
case crv
|
98
|
+
when 'P-256' then 'prime256v1'
|
99
|
+
when 'P-384' then 'secp384r1'
|
100
|
+
when 'P-521' then 'secp521r1'
|
101
|
+
else raise JWT::JWKError, 'Invalid curve provided'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def jwk_attrs(jwk_data, attrs)
|
108
|
+
attrs.map do |attr|
|
109
|
+
jwk_data[attr] || jwk_data[attr.to_s]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def ec_pkey(jwk_crv, jwk_x, jwk_y, jwk_d)
|
114
|
+
curve = to_openssl_curve(jwk_crv)
|
115
|
+
|
116
|
+
x_octets = decode_octets(jwk_x)
|
117
|
+
y_octets = decode_octets(jwk_y)
|
118
|
+
|
119
|
+
key = OpenSSL::PKey::EC.new(curve)
|
120
|
+
|
121
|
+
# The details of the `Point` instantiation are covered in:
|
122
|
+
# - https://docs.ruby-lang.org/en/2.4.0/OpenSSL/PKey/EC.html
|
123
|
+
# - https://www.openssl.org/docs/manmaster/man3/EC_POINT_new.html
|
124
|
+
# - https://tools.ietf.org/html/rfc5480#section-2.2
|
125
|
+
# - https://www.secg.org/SEC1-Ver-1.0.pdf
|
126
|
+
# Section 2.3.3 of the last of these references specifies that the
|
127
|
+
# encoding of an uncompressed point consists of the byte `0x04` followed
|
128
|
+
# by the x value then the y value.
|
129
|
+
point = OpenSSL::PKey::EC::Point.new(
|
130
|
+
OpenSSL::PKey::EC::Group.new(curve),
|
131
|
+
OpenSSL::BN.new([0x04, x_octets, y_octets].pack('Ca*a*'), 2)
|
132
|
+
)
|
133
|
+
|
134
|
+
key.public_key = point
|
135
|
+
key.private_key = OpenSSL::BN.new(decode_octets(jwk_d), 2) if jwk_d
|
136
|
+
|
137
|
+
key
|
138
|
+
end
|
139
|
+
|
140
|
+
def decode_octets(jwk_data)
|
141
|
+
::JWT::Base64.url_decode(jwk_data)
|
142
|
+
end
|
143
|
+
|
144
|
+
def decode_open_ssl_bn(jwk_data)
|
145
|
+
OpenSSL::BN.new(::JWT::Base64.url_decode(jwk_data), BINARY)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
data/lib/jwt/jwk/hmac.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module JWK
|
5
|
+
class HMAC < KeyBase
|
6
|
+
KTY = 'oct'.freeze
|
7
|
+
KTYS = [KTY, String].freeze
|
8
|
+
|
9
|
+
def initialize(keypair, kid = nil)
|
10
|
+
raise ArgumentError, 'keypair must be of type String' unless keypair.is_a?(String)
|
11
|
+
|
12
|
+
super
|
13
|
+
@kid = kid || generate_kid
|
14
|
+
end
|
15
|
+
|
16
|
+
def private?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def public_key
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
# See https://tools.ietf.org/html/rfc7517#appendix-A.3
|
25
|
+
def export(options = {})
|
26
|
+
exported_hash = {
|
27
|
+
kty: KTY,
|
28
|
+
kid: kid
|
29
|
+
}
|
30
|
+
|
31
|
+
return exported_hash unless private? && options[:include_private] == true
|
32
|
+
|
33
|
+
exported_hash.merge(
|
34
|
+
k: keypair
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def generate_kid
|
41
|
+
sequence = OpenSSL::ASN1::Sequence([OpenSSL::ASN1::UTF8String.new(keypair),
|
42
|
+
OpenSSL::ASN1::UTF8String.new(KTY)])
|
43
|
+
OpenSSL::Digest::SHA256.hexdigest(sequence.to_der)
|
44
|
+
end
|
45
|
+
|
46
|
+
class << self
|
47
|
+
def import(jwk_data)
|
48
|
+
jwk_k = jwk_data[:k] || jwk_data['k']
|
49
|
+
jwk_kid = jwk_data[:kid] || jwk_data['kid']
|
50
|
+
|
51
|
+
raise JWT::JWKError, 'Key format is invalid for HMAC' unless jwk_k
|
52
|
+
|
53
|
+
self.new(jwk_k, jwk_kid)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module JWK
|
5
|
+
class KeyBase
|
6
|
+
attr_reader :keypair, :kid
|
7
|
+
|
8
|
+
def initialize(keypair, kid = nil)
|
9
|
+
@keypair = keypair
|
10
|
+
@kid = kid
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.inherited(klass)
|
14
|
+
::JWT::JWK.classes << klass
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module JWK
|
5
|
+
class KeyFinder
|
6
|
+
def initialize(options)
|
7
|
+
jwks_or_loader = options[:jwks]
|
8
|
+
@jwks = jwks_or_loader if jwks_or_loader.is_a?(Hash)
|
9
|
+
@jwk_loader = jwks_or_loader if jwks_or_loader.respond_to?(:call)
|
10
|
+
end
|
11
|
+
|
12
|
+
def key_for(kid)
|
13
|
+
raise ::JWT::DecodeError, 'No key id (kid) found from token headers' unless kid
|
14
|
+
|
15
|
+
jwk = resolve_key(kid)
|
16
|
+
|
17
|
+
raise ::JWT::DecodeError, 'No keys found in jwks' if jwks_keys.empty?
|
18
|
+
raise ::JWT::DecodeError, "Could not find public key for kid #{kid}" unless jwk
|
19
|
+
|
20
|
+
::JWT::JWK.import(jwk).keypair
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def resolve_key(kid)
|
26
|
+
jwk = find_key(kid)
|
27
|
+
|
28
|
+
return jwk if jwk
|
29
|
+
|
30
|
+
if reloadable?
|
31
|
+
load_keys(invalidate: true)
|
32
|
+
return find_key(kid)
|
33
|
+
end
|
34
|
+
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def jwks
|
39
|
+
return @jwks if @jwks
|
40
|
+
|
41
|
+
load_keys
|
42
|
+
@jwks
|
43
|
+
end
|
44
|
+
|
45
|
+
def load_keys(opts = {})
|
46
|
+
@jwks = @jwk_loader.call(opts)
|
47
|
+
end
|
48
|
+
|
49
|
+
def jwks_keys
|
50
|
+
Array(jwks[:keys] || jwks['keys'])
|
51
|
+
end
|
52
|
+
|
53
|
+
def find_key(kid)
|
54
|
+
jwks_keys.find { |key| (key[:kid] || key['kid']) == kid }
|
55
|
+
end
|
56
|
+
|
57
|
+
def reloadable?
|
58
|
+
@jwk_loader
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/jwt/jwk/rsa.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module JWK
|
5
|
+
class RSA < KeyBase
|
6
|
+
BINARY = 2
|
7
|
+
KTY = 'RSA'.freeze
|
8
|
+
KTYS = [KTY, OpenSSL::PKey::RSA].freeze
|
9
|
+
RSA_KEY_ELEMENTS = %i[n e d p q dp dq qi].freeze
|
10
|
+
|
11
|
+
def initialize(keypair, kid = nil)
|
12
|
+
raise ArgumentError, 'keypair must be of type OpenSSL::PKey::RSA' unless keypair.is_a?(OpenSSL::PKey::RSA)
|
13
|
+
super(keypair, kid || generate_kid(keypair.public_key))
|
14
|
+
end
|
15
|
+
|
16
|
+
def private?
|
17
|
+
keypair.private?
|
18
|
+
end
|
19
|
+
|
20
|
+
def public_key
|
21
|
+
keypair.public_key
|
22
|
+
end
|
23
|
+
|
24
|
+
def export(options = {})
|
25
|
+
exported_hash = {
|
26
|
+
kty: KTY,
|
27
|
+
n: encode_open_ssl_bn(public_key.n),
|
28
|
+
e: encode_open_ssl_bn(public_key.e),
|
29
|
+
kid: kid
|
30
|
+
}
|
31
|
+
|
32
|
+
return exported_hash unless private? && options[:include_private] == true
|
33
|
+
|
34
|
+
append_private_parts(exported_hash)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def generate_kid(public_key)
|
40
|
+
sequence = OpenSSL::ASN1::Sequence([OpenSSL::ASN1::Integer.new(public_key.n),
|
41
|
+
OpenSSL::ASN1::Integer.new(public_key.e)])
|
42
|
+
OpenSSL::Digest::SHA256.hexdigest(sequence.to_der)
|
43
|
+
end
|
44
|
+
|
45
|
+
def append_private_parts(the_hash)
|
46
|
+
the_hash.merge(
|
47
|
+
d: encode_open_ssl_bn(keypair.d),
|
48
|
+
p: encode_open_ssl_bn(keypair.p),
|
49
|
+
q: encode_open_ssl_bn(keypair.q),
|
50
|
+
dp: encode_open_ssl_bn(keypair.dmp1),
|
51
|
+
dq: encode_open_ssl_bn(keypair.dmq1),
|
52
|
+
qi: encode_open_ssl_bn(keypair.iqmp)
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
def encode_open_ssl_bn(key_part)
|
57
|
+
::JWT::Base64.url_encode(key_part.to_s(BINARY))
|
58
|
+
end
|
59
|
+
|
60
|
+
class << self
|
61
|
+
def import(jwk_data)
|
62
|
+
pkey_params = jwk_attributes(jwk_data, *RSA_KEY_ELEMENTS) do |value|
|
63
|
+
decode_open_ssl_bn(value)
|
64
|
+
end
|
65
|
+
kid = jwk_attributes(jwk_data, :kid)[:kid]
|
66
|
+
self.new(rsa_pkey(pkey_params), kid)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def jwk_attributes(jwk_data, *attributes)
|
72
|
+
attributes.each_with_object({}) do |attribute, hash|
|
73
|
+
value = jwk_data[attribute] || jwk_data[attribute.to_s]
|
74
|
+
value = yield(value) if block_given?
|
75
|
+
hash[attribute] = value
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def rsa_pkey(rsa_parameters)
|
80
|
+
raise JWT::JWKError, 'Key format is invalid for RSA' unless rsa_parameters[:n] && rsa_parameters[:e]
|
81
|
+
|
82
|
+
populate_key(OpenSSL::PKey::RSA.new, rsa_parameters)
|
83
|
+
end
|
84
|
+
|
85
|
+
if OpenSSL::PKey::RSA.new.respond_to?(:set_key)
|
86
|
+
def populate_key(rsa_key, rsa_parameters)
|
87
|
+
rsa_key.set_key(rsa_parameters[:n], rsa_parameters[:e], rsa_parameters[:d])
|
88
|
+
rsa_key.set_factors(rsa_parameters[:p], rsa_parameters[:q]) if rsa_parameters[:p] && rsa_parameters[:q]
|
89
|
+
rsa_key.set_crt_params(rsa_parameters[:dp], rsa_parameters[:dq], rsa_parameters[:qi]) if rsa_parameters[:dp] && rsa_parameters[:dq] && rsa_parameters[:qi]
|
90
|
+
rsa_key
|
91
|
+
end
|
92
|
+
else
|
93
|
+
def populate_key(rsa_key, rsa_parameters)
|
94
|
+
rsa_key.n = rsa_parameters[:n]
|
95
|
+
rsa_key.e = rsa_parameters[:e]
|
96
|
+
rsa_key.d = rsa_parameters[:d] if rsa_parameters[:d]
|
97
|
+
rsa_key.p = rsa_parameters[:p] if rsa_parameters[:p]
|
98
|
+
rsa_key.q = rsa_parameters[:q] if rsa_parameters[:q]
|
99
|
+
rsa_key.dmp1 = rsa_parameters[:dp] if rsa_parameters[:dp]
|
100
|
+
rsa_key.dmq1 = rsa_parameters[:dq] if rsa_parameters[:dq]
|
101
|
+
rsa_key.iqmp = rsa_parameters[:qi] if rsa_parameters[:qi]
|
102
|
+
|
103
|
+
rsa_key
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def decode_open_ssl_bn(jwk_data)
|
108
|
+
return nil unless jwk_data
|
109
|
+
|
110
|
+
OpenSSL::BN.new(::JWT::Base64.url_decode(jwk_data), BINARY)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|