jwt 2.7.1 → 2.9.0
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 +4 -4
- data/CHANGELOG.md +84 -27
- data/README.md +37 -19
- data/lib/jwt/base64.rb +16 -2
- data/lib/jwt/claims/audience.rb +20 -0
- data/lib/jwt/claims/expiration.rb +22 -0
- data/lib/jwt/claims/issued_at.rb +15 -0
- data/lib/jwt/claims/issuer.rb +24 -0
- data/lib/jwt/claims/jwt_id.rb +25 -0
- data/lib/jwt/claims/not_before.rb +22 -0
- data/lib/jwt/claims/numeric.rb +43 -0
- data/lib/jwt/claims/required.rb +23 -0
- data/lib/jwt/claims/subject.rb +20 -0
- data/lib/jwt/claims.rb +38 -0
- data/lib/jwt/configuration/container.rb +14 -3
- data/lib/jwt/configuration/jwk_configuration.rb +1 -1
- data/lib/jwt/decode.rb +12 -21
- data/lib/jwt/deprecations.rb +48 -0
- data/lib/jwt/encode.rb +4 -14
- data/lib/jwt/error.rb +1 -0
- data/lib/jwt/{algos → jwa}/ecdsa.rb +39 -26
- data/lib/jwt/jwa/eddsa.rb +34 -0
- data/lib/jwt/{algos → jwa}/hmac.rb +25 -19
- data/lib/jwt/jwa/hmac_rbnacl.rb +45 -0
- data/lib/jwt/jwa/hmac_rbnacl_fixed.rb +42 -0
- data/lib/jwt/jwa/none.rb +23 -0
- data/lib/jwt/jwa/ps.rb +36 -0
- data/lib/jwt/jwa/rsa.rb +36 -0
- data/lib/jwt/jwa/signing_algorithm.rb +59 -0
- data/lib/jwt/jwa/unsupported.rb +19 -0
- data/lib/jwt/jwa/wrapper.rb +43 -0
- data/lib/jwt/jwa.rb +45 -0
- data/lib/jwt/jwk/ec.rb +42 -27
- data/lib/jwt/jwk/key_base.rb +3 -1
- data/lib/jwt/jwk/key_finder.rb +4 -4
- data/lib/jwt/jwk/set.rb +1 -1
- data/lib/jwt/jwk.rb +1 -1
- data/lib/jwt/version.rb +4 -3
- data/lib/jwt/x5c_key_finder.rb +2 -5
- data/lib/jwt.rb +5 -1
- data/ruby-jwt.gemspec +3 -0
- metadata +58 -20
- data/lib/jwt/algos/algo_wrapper.rb +0 -26
- data/lib/jwt/algos/eddsa.rb +0 -33
- data/lib/jwt/algos/hmac_rbnacl.rb +0 -53
- data/lib/jwt/algos/hmac_rbnacl_fixed.rb +0 -52
- data/lib/jwt/algos/none.rb +0 -19
- data/lib/jwt/algos/ps.rb +0 -41
- data/lib/jwt/algos/rsa.rb +0 -23
- data/lib/jwt/algos/unsupported.rb +0 -19
- data/lib/jwt/algos.rb +0 -66
- data/lib/jwt/claims_validator.rb +0 -37
- data/lib/jwt/verify.rb +0 -113
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module JWA
|
5
|
+
class Wrapper
|
6
|
+
include SigningAlgorithm
|
7
|
+
|
8
|
+
def initialize(algorithm)
|
9
|
+
@algorithm = algorithm
|
10
|
+
end
|
11
|
+
|
12
|
+
def alg
|
13
|
+
return @algorithm.alg if @algorithm.respond_to?(:alg)
|
14
|
+
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid_alg?(alg_to_check)
|
19
|
+
return @algorithm.valid_alg?(alg_to_check) if @algorithm.respond_to?(:valid_alg?)
|
20
|
+
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def header(*args, **kwargs)
|
25
|
+
return @algorithm.header(*args, **kwargs) if @algorithm.respond_to?(:header)
|
26
|
+
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
def sign(*args, **kwargs)
|
31
|
+
return @algorithm.sign(*args, **kwargs) if @algorithm.respond_to?(:sign)
|
32
|
+
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
def verify(*args, **kwargs)
|
37
|
+
return @algorithm.verify(*args, **kwargs) if @algorithm.respond_to?(:verify)
|
38
|
+
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/jwt/jwa.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'openssl'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'rbnacl'
|
7
|
+
rescue LoadError
|
8
|
+
raise if defined?(RbNaCl)
|
9
|
+
end
|
10
|
+
|
11
|
+
require_relative 'jwa/signing_algorithm'
|
12
|
+
require_relative 'jwa/ecdsa'
|
13
|
+
require_relative 'jwa/hmac'
|
14
|
+
require_relative 'jwa/none'
|
15
|
+
require_relative 'jwa/ps'
|
16
|
+
require_relative 'jwa/rsa'
|
17
|
+
require_relative 'jwa/unsupported'
|
18
|
+
require_relative 'jwa/wrapper'
|
19
|
+
|
20
|
+
if JWT.rbnacl?
|
21
|
+
require_relative 'jwa/eddsa'
|
22
|
+
end
|
23
|
+
|
24
|
+
if JWT.rbnacl_6_or_greater?
|
25
|
+
require_relative 'jwa/hmac_rbnacl'
|
26
|
+
elsif JWT.rbnacl?
|
27
|
+
require_relative 'jwa/hmac_rbnacl_fixed'
|
28
|
+
end
|
29
|
+
|
30
|
+
module JWT
|
31
|
+
module JWA
|
32
|
+
class << self
|
33
|
+
def resolve(algorithm)
|
34
|
+
return find(algorithm) if algorithm.is_a?(String) || algorithm.is_a?(Symbol)
|
35
|
+
|
36
|
+
unless algorithm.is_a?(SigningAlgorithm)
|
37
|
+
Deprecations.warning('Custom algorithms are required to include JWT::JWA::SigningAlgorithm')
|
38
|
+
return Wrapper.new(algorithm)
|
39
|
+
end
|
40
|
+
|
41
|
+
algorithm
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/jwt/jwk/ec.rb
CHANGED
@@ -11,6 +11,7 @@ module JWT
|
|
11
11
|
EC_PUBLIC_KEY_ELEMENTS = %i[kty crv x y].freeze
|
12
12
|
EC_PRIVATE_KEY_ELEMENTS = %i[d].freeze
|
13
13
|
EC_KEY_ELEMENTS = (EC_PRIVATE_KEY_ELEMENTS + EC_PUBLIC_KEY_ELEMENTS).freeze
|
14
|
+
ZERO_BYTE = "\0".b.freeze
|
14
15
|
|
15
16
|
def initialize(key, params = nil, options = {})
|
16
17
|
params ||= {}
|
@@ -143,7 +144,6 @@ module JWT
|
|
143
144
|
if ::JWT.openssl_3?
|
144
145
|
def create_ec_key(jwk_crv, jwk_x, jwk_y, jwk_d) # rubocop:disable Metrics/MethodLength
|
145
146
|
curve = EC.to_openssl_curve(jwk_crv)
|
146
|
-
|
147
147
|
x_octets = decode_octets(jwk_x)
|
148
148
|
y_octets = decode_octets(jwk_y)
|
149
149
|
|
@@ -153,26 +153,26 @@ module JWT
|
|
153
153
|
)
|
154
154
|
|
155
155
|
sequence = if jwk_d
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
156
|
+
# https://datatracker.ietf.org/doc/html/rfc5915.html
|
157
|
+
# ECPrivateKey ::= SEQUENCE {
|
158
|
+
# version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
|
159
|
+
# privateKey OCTET STRING,
|
160
|
+
# parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
|
161
|
+
# publicKey [1] BIT STRING OPTIONAL
|
162
|
+
# }
|
163
|
+
|
164
|
+
OpenSSL::ASN1::Sequence([
|
165
|
+
OpenSSL::ASN1::Integer(1),
|
166
|
+
OpenSSL::ASN1::OctetString(OpenSSL::BN.new(decode_octets(jwk_d), 2).to_s(2)),
|
167
|
+
OpenSSL::ASN1::ObjectId(curve, 0, :EXPLICIT),
|
168
|
+
OpenSSL::ASN1::BitString(point.to_octet_string(:uncompressed), 1, :EXPLICIT)
|
169
|
+
])
|
170
|
+
else
|
171
|
+
OpenSSL::ASN1::Sequence([
|
172
|
+
OpenSSL::ASN1::Sequence([OpenSSL::ASN1::ObjectId('id-ecPublicKey'), OpenSSL::ASN1::ObjectId(curve)]),
|
173
|
+
OpenSSL::ASN1::BitString(point.to_octet_string(:uncompressed))
|
174
|
+
])
|
175
|
+
end
|
176
176
|
|
177
177
|
OpenSSL::PKey::EC.new(sequence.to_der)
|
178
178
|
end
|
@@ -205,12 +205,27 @@ module JWT
|
|
205
205
|
end
|
206
206
|
end
|
207
207
|
|
208
|
-
def decode_octets(
|
209
|
-
::JWT::Base64.url_decode(
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
208
|
+
def decode_octets(base64_encoded_coordinate)
|
209
|
+
bytes = ::JWT::Base64.url_decode(base64_encoded_coordinate)
|
210
|
+
# Some base64 encoders on some platform omit a single 0-byte at
|
211
|
+
# the start of either Y or X coordinate of the elliptic curve point.
|
212
|
+
# This leads to an encoding error when data is passed to OpenSSL BN.
|
213
|
+
# It is know to have happend to exported JWKs on a Java application and
|
214
|
+
# on a Flutter/Dart application (both iOS and Android). All that is
|
215
|
+
# needed to fix the problem is adding a leading 0-byte. We know the
|
216
|
+
# required byte is 0 because with any other byte the point is no longer
|
217
|
+
# on the curve - and OpenSSL will actually communicate this via another
|
218
|
+
# exception. The indication of a stripped byte will be the fact that the
|
219
|
+
# coordinates - once decoded into bytes - should always be an even
|
220
|
+
# bytesize. For example, with a P-521 curve, both x and y must be 66 bytes.
|
221
|
+
# With a P-256 curve, both x and y must be 32 and so on. The simplest way
|
222
|
+
# to check for this truncation is thus to check whether the number of bytes
|
223
|
+
# is odd, and restore the leading 0-byte if it is.
|
224
|
+
if bytes.bytesize.odd?
|
225
|
+
ZERO_BYTE + bytes
|
226
|
+
else
|
227
|
+
bytes
|
228
|
+
end
|
214
229
|
end
|
215
230
|
|
216
231
|
class << self
|
data/lib/jwt/jwk/key_base.rb
CHANGED
@@ -38,12 +38,14 @@ module JWT
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def ==(other)
|
41
|
-
self[:kid] == other[:kid]
|
41
|
+
other.is_a?(::JWT::JWK::KeyBase) && self[:kid] == other[:kid]
|
42
42
|
end
|
43
43
|
|
44
44
|
alias eql? ==
|
45
45
|
|
46
46
|
def <=>(other)
|
47
|
+
return nil unless other.is_a?(::JWT::JWK::KeyBase)
|
48
|
+
|
47
49
|
self[:kid] <=> other[:kid]
|
48
50
|
end
|
49
51
|
|
data/lib/jwt/jwk/key_finder.rb
CHANGED
@@ -8,10 +8,10 @@ module JWT
|
|
8
8
|
jwks_or_loader = options[:jwks]
|
9
9
|
|
10
10
|
@jwks_loader = if jwks_or_loader.respond_to?(:call)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
jwks_or_loader
|
12
|
+
else
|
13
|
+
->(_options) { jwks_or_loader }
|
14
|
+
end
|
15
15
|
end
|
16
16
|
|
17
17
|
def key_for(kid)
|
data/lib/jwt/jwk/set.rb
CHANGED
data/lib/jwt/jwk.rb
CHANGED
data/lib/jwt/version.rb
CHANGED
@@ -11,9 +11,9 @@ module JWT
|
|
11
11
|
# major version
|
12
12
|
MAJOR = 2
|
13
13
|
# minor version
|
14
|
-
MINOR =
|
14
|
+
MINOR = 9
|
15
15
|
# tiny version
|
16
|
-
TINY =
|
16
|
+
TINY = 0
|
17
17
|
# alpha, beta, etc. tag
|
18
18
|
PRE = nil
|
19
19
|
|
@@ -23,7 +23,8 @@ module JWT
|
|
23
23
|
|
24
24
|
def self.openssl_3?
|
25
25
|
return false if OpenSSL::OPENSSL_VERSION.include?('LibreSSL')
|
26
|
-
|
26
|
+
|
27
|
+
true if 3 * 0x10000000 <= OpenSSL::OPENSSL_VERSION_NUMBER
|
27
28
|
end
|
28
29
|
|
29
30
|
def self.rbnacl?
|
data/lib/jwt/x5c_key_finder.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'base64'
|
4
|
-
require 'jwt/error'
|
5
|
-
|
6
3
|
module JWT
|
7
4
|
# If the x5c header certificate chain can be validated by trusted root
|
8
5
|
# certificates, and none of the certificates are revoked, returns the public
|
@@ -10,7 +7,7 @@ module JWT
|
|
10
7
|
# See https://tools.ietf.org/html/rfc7515#section-4.1.6
|
11
8
|
class X5cKeyFinder
|
12
9
|
def initialize(root_certificates, crls = nil)
|
13
|
-
raise
|
10
|
+
raise ArgumentError, 'Root certificates must be specified' unless root_certificates
|
14
11
|
|
15
12
|
@store = build_store(root_certificates, crls)
|
16
13
|
end
|
@@ -27,7 +24,7 @@ module JWT
|
|
27
24
|
error = "#{error} Certificate subject: #{current_cert.subject}."
|
28
25
|
end
|
29
26
|
|
30
|
-
raise
|
27
|
+
raise JWT::VerificationError, error
|
31
28
|
end
|
32
29
|
end
|
33
30
|
|
data/lib/jwt.rb
CHANGED
@@ -5,9 +5,11 @@ require 'jwt/base64'
|
|
5
5
|
require 'jwt/json'
|
6
6
|
require 'jwt/decode'
|
7
7
|
require 'jwt/configuration'
|
8
|
+
require 'jwt/deprecations'
|
8
9
|
require 'jwt/encode'
|
9
10
|
require 'jwt/error'
|
10
11
|
require 'jwt/jwk'
|
12
|
+
require 'jwt/claims'
|
11
13
|
|
12
14
|
# JSON Web Token implementation
|
13
15
|
#
|
@@ -26,6 +28,8 @@ module JWT
|
|
26
28
|
end
|
27
29
|
|
28
30
|
def decode(jwt, key = nil, verify = true, options = {}, &keyfinder) # rubocop:disable Style/OptionalBooleanParameter
|
29
|
-
|
31
|
+
Deprecations.context do
|
32
|
+
Decode.new(jwt, key, verify, configuration.decode.to_h.merge(options), &keyfinder).decode_segments
|
33
|
+
end
|
30
34
|
end
|
31
35
|
end
|
data/ruby-jwt.gemspec
CHANGED
@@ -31,9 +31,12 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.executables = []
|
32
32
|
spec.require_paths = %w[lib]
|
33
33
|
|
34
|
+
spec.add_dependency 'base64'
|
35
|
+
|
34
36
|
spec.add_development_dependency 'appraisal'
|
35
37
|
spec.add_development_dependency 'bundler'
|
36
38
|
spec.add_development_dependency 'rake'
|
37
39
|
spec.add_development_dependency 'rspec'
|
40
|
+
spec.add_development_dependency 'rubocop'
|
38
41
|
spec.add_development_dependency 'simplecov'
|
39
42
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jwt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Rudat
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: base64
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: appraisal
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +80,20 @@ dependencies:
|
|
66
80
|
- - ">="
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: simplecov
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,27 +122,38 @@ files:
|
|
94
122
|
- LICENSE
|
95
123
|
- README.md
|
96
124
|
- lib/jwt.rb
|
97
|
-
- lib/jwt/algos.rb
|
98
|
-
- lib/jwt/algos/algo_wrapper.rb
|
99
|
-
- lib/jwt/algos/ecdsa.rb
|
100
|
-
- lib/jwt/algos/eddsa.rb
|
101
|
-
- lib/jwt/algos/hmac.rb
|
102
|
-
- lib/jwt/algos/hmac_rbnacl.rb
|
103
|
-
- lib/jwt/algos/hmac_rbnacl_fixed.rb
|
104
|
-
- lib/jwt/algos/none.rb
|
105
|
-
- lib/jwt/algos/ps.rb
|
106
|
-
- lib/jwt/algos/rsa.rb
|
107
|
-
- lib/jwt/algos/unsupported.rb
|
108
125
|
- lib/jwt/base64.rb
|
109
|
-
- lib/jwt/
|
126
|
+
- lib/jwt/claims.rb
|
127
|
+
- lib/jwt/claims/audience.rb
|
128
|
+
- lib/jwt/claims/expiration.rb
|
129
|
+
- lib/jwt/claims/issued_at.rb
|
130
|
+
- lib/jwt/claims/issuer.rb
|
131
|
+
- lib/jwt/claims/jwt_id.rb
|
132
|
+
- lib/jwt/claims/not_before.rb
|
133
|
+
- lib/jwt/claims/numeric.rb
|
134
|
+
- lib/jwt/claims/required.rb
|
135
|
+
- lib/jwt/claims/subject.rb
|
110
136
|
- lib/jwt/configuration.rb
|
111
137
|
- lib/jwt/configuration/container.rb
|
112
138
|
- lib/jwt/configuration/decode_configuration.rb
|
113
139
|
- lib/jwt/configuration/jwk_configuration.rb
|
114
140
|
- lib/jwt/decode.rb
|
141
|
+
- lib/jwt/deprecations.rb
|
115
142
|
- lib/jwt/encode.rb
|
116
143
|
- lib/jwt/error.rb
|
117
144
|
- lib/jwt/json.rb
|
145
|
+
- lib/jwt/jwa.rb
|
146
|
+
- lib/jwt/jwa/ecdsa.rb
|
147
|
+
- lib/jwt/jwa/eddsa.rb
|
148
|
+
- lib/jwt/jwa/hmac.rb
|
149
|
+
- lib/jwt/jwa/hmac_rbnacl.rb
|
150
|
+
- lib/jwt/jwa/hmac_rbnacl_fixed.rb
|
151
|
+
- lib/jwt/jwa/none.rb
|
152
|
+
- lib/jwt/jwa/ps.rb
|
153
|
+
- lib/jwt/jwa/rsa.rb
|
154
|
+
- lib/jwt/jwa/signing_algorithm.rb
|
155
|
+
- lib/jwt/jwa/unsupported.rb
|
156
|
+
- lib/jwt/jwa/wrapper.rb
|
118
157
|
- lib/jwt/jwk.rb
|
119
158
|
- lib/jwt/jwk/ec.rb
|
120
159
|
- lib/jwt/jwk/hmac.rb
|
@@ -125,7 +164,6 @@ files:
|
|
125
164
|
- lib/jwt/jwk/rsa.rb
|
126
165
|
- lib/jwt/jwk/set.rb
|
127
166
|
- lib/jwt/jwk/thumbprint.rb
|
128
|
-
- lib/jwt/verify.rb
|
129
167
|
- lib/jwt/version.rb
|
130
168
|
- lib/jwt/x5c_key_finder.rb
|
131
169
|
- ruby-jwt.gemspec
|
@@ -134,9 +172,9 @@ licenses:
|
|
134
172
|
- MIT
|
135
173
|
metadata:
|
136
174
|
bug_tracker_uri: https://github.com/jwt/ruby-jwt/issues
|
137
|
-
changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.
|
175
|
+
changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.9.0/CHANGELOG.md
|
138
176
|
rubygems_mfa_required: 'true'
|
139
|
-
post_install_message:
|
177
|
+
post_install_message:
|
140
178
|
rdoc_options: []
|
141
179
|
require_paths:
|
142
180
|
- lib
|
@@ -151,8 +189,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
189
|
- !ruby/object:Gem::Version
|
152
190
|
version: '0'
|
153
191
|
requirements: []
|
154
|
-
rubygems_version: 3.
|
155
|
-
signing_key:
|
192
|
+
rubygems_version: 3.5.16
|
193
|
+
signing_key:
|
156
194
|
specification_version: 4
|
157
195
|
summary: JSON Web Token implementation in Ruby
|
158
196
|
test_files: []
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module JWT
|
4
|
-
module Algos
|
5
|
-
class AlgoWrapper
|
6
|
-
attr_reader :alg, :cls
|
7
|
-
|
8
|
-
def initialize(alg, cls)
|
9
|
-
@alg = alg
|
10
|
-
@cls = cls
|
11
|
-
end
|
12
|
-
|
13
|
-
def valid_alg?(alg_to_check)
|
14
|
-
alg&.casecmp(alg_to_check)&.zero? == true
|
15
|
-
end
|
16
|
-
|
17
|
-
def sign(data:, signing_key:)
|
18
|
-
cls.sign(alg, data, signing_key)
|
19
|
-
end
|
20
|
-
|
21
|
-
def verify(data:, signature:, verification_key:)
|
22
|
-
cls.verify(alg, verification_key, data, signature)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
data/lib/jwt/algos/eddsa.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module JWT
|
4
|
-
module Algos
|
5
|
-
module Eddsa
|
6
|
-
module_function
|
7
|
-
|
8
|
-
SUPPORTED = %w[ED25519 EdDSA].freeze
|
9
|
-
|
10
|
-
def sign(algorithm, msg, key)
|
11
|
-
if key.class != RbNaCl::Signatures::Ed25519::SigningKey
|
12
|
-
raise EncodeError, "Key given is a #{key.class} but has to be an RbNaCl::Signatures::Ed25519::SigningKey"
|
13
|
-
end
|
14
|
-
unless SUPPORTED.map(&:downcase).map(&:to_sym).include?(algorithm.downcase.to_sym)
|
15
|
-
raise IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key.primitive} signing key was provided"
|
16
|
-
end
|
17
|
-
|
18
|
-
key.sign(msg)
|
19
|
-
end
|
20
|
-
|
21
|
-
def verify(algorithm, public_key, signing_input, signature)
|
22
|
-
unless SUPPORTED.map(&:downcase).map(&:to_sym).include?(algorithm.downcase.to_sym)
|
23
|
-
raise IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key.primitive} signing key was provided"
|
24
|
-
end
|
25
|
-
raise DecodeError, "key given is a #{public_key.class} but has to be a RbNaCl::Signatures::Ed25519::VerifyKey" if public_key.class != RbNaCl::Signatures::Ed25519::VerifyKey
|
26
|
-
|
27
|
-
public_key.verify(signature, signing_input)
|
28
|
-
rescue RbNaCl::CryptoError
|
29
|
-
false
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module JWT
|
4
|
-
module Algos
|
5
|
-
module HmacRbNaCl
|
6
|
-
module_function
|
7
|
-
|
8
|
-
MAPPING = {
|
9
|
-
'HS256' => ::RbNaCl::HMAC::SHA256,
|
10
|
-
'HS512256' => ::RbNaCl::HMAC::SHA512256,
|
11
|
-
'HS384' => nil,
|
12
|
-
'HS512' => ::RbNaCl::HMAC::SHA512
|
13
|
-
}.freeze
|
14
|
-
|
15
|
-
SUPPORTED = MAPPING.keys
|
16
|
-
|
17
|
-
def sign(algorithm, msg, key)
|
18
|
-
if (hmac = resolve_algorithm(algorithm))
|
19
|
-
hmac.auth(key_for_rbnacl(hmac, key).encode('binary'), msg.encode('binary'))
|
20
|
-
else
|
21
|
-
Hmac.sign(algorithm, msg, key)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def verify(algorithm, key, signing_input, signature)
|
26
|
-
if (hmac = resolve_algorithm(algorithm))
|
27
|
-
hmac.verify(key_for_rbnacl(hmac, key).encode('binary'), signature.encode('binary'), signing_input.encode('binary'))
|
28
|
-
else
|
29
|
-
Hmac.verify(algorithm, key, signing_input, signature)
|
30
|
-
end
|
31
|
-
rescue ::RbNaCl::BadAuthenticatorError, ::RbNaCl::LengthError
|
32
|
-
false
|
33
|
-
end
|
34
|
-
|
35
|
-
def key_for_rbnacl(hmac, key)
|
36
|
-
key ||= ''
|
37
|
-
raise JWT::DecodeError, 'HMAC key expected to be a String' unless key.is_a?(String)
|
38
|
-
|
39
|
-
return padded_empty_key(hmac.key_bytes) if key == ''
|
40
|
-
|
41
|
-
key
|
42
|
-
end
|
43
|
-
|
44
|
-
def resolve_algorithm(algorithm)
|
45
|
-
MAPPING.fetch(algorithm)
|
46
|
-
end
|
47
|
-
|
48
|
-
def padded_empty_key(length)
|
49
|
-
Array.new(length, 0x0).pack('C*').encode('binary')
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module JWT
|
4
|
-
module Algos
|
5
|
-
module HmacRbNaClFixed
|
6
|
-
module_function
|
7
|
-
|
8
|
-
MAPPING = {
|
9
|
-
'HS256' => ::RbNaCl::HMAC::SHA256,
|
10
|
-
'HS512256' => ::RbNaCl::HMAC::SHA512256,
|
11
|
-
'HS384' => nil,
|
12
|
-
'HS512' => ::RbNaCl::HMAC::SHA512
|
13
|
-
}.freeze
|
14
|
-
|
15
|
-
SUPPORTED = MAPPING.keys
|
16
|
-
|
17
|
-
def sign(algorithm, msg, key)
|
18
|
-
key ||= ''
|
19
|
-
|
20
|
-
raise JWT::DecodeError, 'HMAC key expected to be a String' unless key.is_a?(String)
|
21
|
-
|
22
|
-
if (hmac = resolve_algorithm(algorithm)) && key.bytesize <= hmac.key_bytes
|
23
|
-
hmac.auth(padded_key_bytes(key, hmac.key_bytes), msg.encode('binary'))
|
24
|
-
else
|
25
|
-
Hmac.sign(algorithm, msg, key)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def verify(algorithm, key, signing_input, signature)
|
30
|
-
key ||= ''
|
31
|
-
|
32
|
-
raise JWT::DecodeError, 'HMAC key expected to be a String' unless key.is_a?(String)
|
33
|
-
|
34
|
-
if (hmac = resolve_algorithm(algorithm)) && key.bytesize <= hmac.key_bytes
|
35
|
-
hmac.verify(padded_key_bytes(key, hmac.key_bytes), signature.encode('binary'), signing_input.encode('binary'))
|
36
|
-
else
|
37
|
-
Hmac.verify(algorithm, key, signing_input, signature)
|
38
|
-
end
|
39
|
-
rescue ::RbNaCl::BadAuthenticatorError, ::RbNaCl::LengthError
|
40
|
-
false
|
41
|
-
end
|
42
|
-
|
43
|
-
def resolve_algorithm(algorithm)
|
44
|
-
MAPPING.fetch(algorithm)
|
45
|
-
end
|
46
|
-
|
47
|
-
def padded_key_bytes(key, bytesize)
|
48
|
-
key.bytes.fill(0, key.bytesize...bytesize).pack('C*')
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
data/lib/jwt/algos/none.rb
DELETED