jwt 1.5.5 → 1.5.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/lib/jwt.rb +33 -41
- data/lib/jwt/decode.rb +3 -2
- data/lib/jwt/error.rb +1 -0
- data/lib/jwt/json.rb +1 -0
- data/lib/jwt/verify.rb +11 -13
- data/lib/jwt/version.rb +3 -2
- data/spec/jwt/verify_spec.rb +13 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cd1a9ca017dec28c4984e18003e8ae58aee776c
|
4
|
+
data.tar.gz: c5fef77f9a8e42d8fa92c060c468be6ee2e3c561
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0dc92b0ea35004782c8260f8d2d47c9973a1172f5eb6bef33fe42ae3a2e8341c9264e5fafc7cb62442039409194c3aa6fbd3db78667db75af04ffd26586422f
|
7
|
+
data.tar.gz: af9967d4c04b332ef8916d3b837e31c20b2e5db8c96531b277286324f29730edbc65eb66401f6db405b22dbd2701895d2579796fab368c26bd1fca58aae30840
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [v1.5.6](https://github.com/jwt/ruby-jwt/tree/v1.5.6) (2016-09-19)
|
4
|
+
[Full Changelog](https://github.com/jwt/ruby-jwt/compare/v1.5.5...v1.5.6)
|
5
|
+
|
6
|
+
**Fixed bugs:**
|
7
|
+
|
8
|
+
- Fix missing symbol handling in aud verify code [\#166](https://github.com/jwt/ruby-jwt/pull/166) ([excpt](https://github.com/excpt))
|
9
|
+
|
10
|
+
**Merged pull requests:**
|
11
|
+
|
12
|
+
- Fix rubocop code smells [\#167](https://github.com/jwt/ruby-jwt/pull/167) ([excpt](https://github.com/excpt))
|
13
|
+
|
3
14
|
## [v1.5.5](https://github.com/jwt/ruby-jwt/tree/v1.5.5) (2016-09-16)
|
4
15
|
[Full Changelog](https://github.com/jwt/ruby-jwt/compare/v1.5.4...v1.5.5)
|
5
16
|
|
data/lib/jwt.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'base64'
|
2
3
|
require 'openssl'
|
3
4
|
require 'jwt/decode'
|
@@ -17,6 +18,17 @@ module JWT
|
|
17
18
|
'secp521r1' => 'ES512'
|
18
19
|
}.freeze
|
19
20
|
|
21
|
+
DEFAULT_OPTIONS = {
|
22
|
+
verify_expiration: true,
|
23
|
+
verify_not_before: true,
|
24
|
+
verify_iss: false,
|
25
|
+
verify_iat: false,
|
26
|
+
verify_jti: false,
|
27
|
+
verify_aud: false,
|
28
|
+
verify_sub: false,
|
29
|
+
leeway: 0
|
30
|
+
}.freeze
|
31
|
+
|
20
32
|
module_function
|
21
33
|
|
22
34
|
def sign(algorithm, msg, key)
|
@@ -73,7 +85,7 @@ module JWT
|
|
73
85
|
end
|
74
86
|
|
75
87
|
def encoded_payload(payload)
|
76
|
-
raise InvalidPayload,
|
88
|
+
raise InvalidPayload, 'exp claim must be an integer' if payload['exp'] && payload['exp'].is_a?(Time)
|
77
89
|
base64url_encode(encode_json(payload))
|
78
90
|
end
|
79
91
|
|
@@ -98,51 +110,19 @@ module JWT
|
|
98
110
|
def decoded_segments(jwt, key = nil, verify = true, custom_options = {}, &keyfinder)
|
99
111
|
raise(JWT::DecodeError, 'Nil JSON web token') unless jwt
|
100
112
|
|
101
|
-
|
102
|
-
verify_expiration: true,
|
103
|
-
verify_not_before: true,
|
104
|
-
verify_iss: false,
|
105
|
-
verify_iat: false,
|
106
|
-
verify_jti: false,
|
107
|
-
verify_aud: false,
|
108
|
-
verify_sub: false,
|
109
|
-
leeway: 0
|
110
|
-
}
|
111
|
-
|
112
|
-
merged_options = options.merge(custom_options)
|
113
|
+
merged_options = DEFAULT_OPTIONS.merge(custom_options)
|
113
114
|
|
114
115
|
decoder = Decode.new jwt, key, verify, merged_options, &keyfinder
|
115
116
|
decoder.decode_segments
|
116
117
|
end
|
117
118
|
|
118
|
-
|
119
119
|
def decode(jwt, key = nil, verify = true, custom_options = {}, &keyfinder)
|
120
120
|
raise(JWT::DecodeError, 'Nil JSON web token') unless jwt
|
121
121
|
|
122
|
-
|
123
|
-
verify_expiration: true,
|
124
|
-
verify_not_before: true,
|
125
|
-
verify_iss: false,
|
126
|
-
verify_iat: false,
|
127
|
-
verify_jti: false,
|
128
|
-
verify_aud: false,
|
129
|
-
verify_sub: false,
|
130
|
-
leeway: 0
|
131
|
-
}
|
132
|
-
|
133
|
-
merged_options = options.merge(custom_options)
|
134
|
-
|
122
|
+
merged_options = DEFAULT_OPTIONS.merge(custom_options)
|
135
123
|
decoder = Decode.new jwt, key, verify, merged_options, &keyfinder
|
136
124
|
header, payload, signature, signing_input = decoder.decode_segments
|
137
|
-
|
138
|
-
if verify
|
139
|
-
algo, key = signature_algorithm_and_key(header, key, &keyfinder)
|
140
|
-
if merged_options[:algorithm] && algo != merged_options[:algorithm]
|
141
|
-
raise JWT::IncorrectAlgorithm, 'Expected a different algorithm'
|
142
|
-
end
|
143
|
-
verify_signature(algo, key, signing_input, signature)
|
144
|
-
end
|
145
|
-
|
125
|
+
decode_verify_signature(key, header, signature, signing_input, merged_options, &keyfinder) if verify
|
146
126
|
decoder.verify
|
147
127
|
|
148
128
|
raise(JWT::DecodeError, 'Not enough or too many segments') unless header && payload
|
@@ -150,12 +130,28 @@ module JWT
|
|
150
130
|
[payload, header]
|
151
131
|
end
|
152
132
|
|
133
|
+
def decode_verify_signature(key, header, signature, signing_input, options, &keyfinder)
|
134
|
+
algo, key = signature_algorithm_and_key(header, key, &keyfinder)
|
135
|
+
if options[:algorithm] && algo != options[:algorithm]
|
136
|
+
raise JWT::IncorrectAlgorithm, 'Expected a different algorithm'
|
137
|
+
end
|
138
|
+
verify_signature(algo, key, signing_input, signature)
|
139
|
+
end
|
140
|
+
|
153
141
|
def signature_algorithm_and_key(header, key, &keyfinder)
|
154
142
|
key = yield(header) if keyfinder
|
155
143
|
[header['alg'], key]
|
156
144
|
end
|
157
145
|
|
158
146
|
def verify_signature(algo, key, signing_input, signature)
|
147
|
+
verify_signature_algo(algo, key, signing_input, signature)
|
148
|
+
rescue OpenSSL::PKey::PKeyError
|
149
|
+
raise JWT::VerificationError, 'Signature verification raised'
|
150
|
+
ensure
|
151
|
+
OpenSSL.errors.clear
|
152
|
+
end
|
153
|
+
|
154
|
+
def verify_signature_algo(algo, key, signing_input, signature)
|
159
155
|
if %w(HS256 HS384 HS512).include?(algo)
|
160
156
|
raise(JWT::VerificationError, 'Signature verification raised') unless secure_compare(signature, sign_hmac(algo, signing_input, key))
|
161
157
|
elsif %w(RS256 RS384 RS512).include?(algo)
|
@@ -165,10 +161,6 @@ module JWT
|
|
165
161
|
else
|
166
162
|
raise JWT::VerificationError, 'Algorithm not supported'
|
167
163
|
end
|
168
|
-
rescue OpenSSL::PKey::PKeyError
|
169
|
-
raise JWT::VerificationError, 'Signature verification raised'
|
170
|
-
ensure
|
171
|
-
OpenSSL.errors.clear
|
172
164
|
end
|
173
165
|
|
174
166
|
# From devise
|
@@ -179,7 +171,7 @@ module JWT
|
|
179
171
|
|
180
172
|
res = 0
|
181
173
|
b.each_byte { |byte| res |= byte ^ l.shift }
|
182
|
-
res
|
174
|
+
res.zero?
|
183
175
|
end
|
184
176
|
|
185
177
|
def raw_to_asn1(signature, private_key)
|
data/lib/jwt/decode.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'jwt/json'
|
2
3
|
require 'jwt/verify'
|
3
4
|
|
@@ -28,7 +29,7 @@ module JWT
|
|
28
29
|
def raw_segments(jwt, verify)
|
29
30
|
segments = jwt.split('.')
|
30
31
|
required_num_segments = verify ? [3] : [2, 3]
|
31
|
-
|
32
|
+
raise(JWT::DecodeError, 'Not enough or too many segments') unless required_num_segments.include? segments.length
|
32
33
|
segments
|
33
34
|
end
|
34
35
|
private :raw_segments
|
@@ -47,7 +48,7 @@ module JWT
|
|
47
48
|
|
48
49
|
def verify
|
49
50
|
@options.each do |key, val|
|
50
|
-
next unless key.to_s
|
51
|
+
next unless key.to_s =~ /verify/
|
51
52
|
|
52
53
|
Verify.send(key, payload, @options) if val
|
53
54
|
end
|
data/lib/jwt/error.rb
CHANGED
data/lib/jwt/json.rb
CHANGED
data/lib/jwt/verify.rb
CHANGED
@@ -21,19 +21,7 @@ module JWT
|
|
21
21
|
return unless (options_aud = extract_option(:aud))
|
22
22
|
|
23
23
|
if @payload['aud'].is_a?(Array)
|
24
|
-
|
25
|
-
options_aud.each do |aud|
|
26
|
-
raise(
|
27
|
-
JWT::InvalidAudError,
|
28
|
-
'Invalid audience'
|
29
|
-
) unless @payload['aud'].include?(aud)
|
30
|
-
end
|
31
|
-
else
|
32
|
-
raise(
|
33
|
-
JWT::InvalidAudError,
|
34
|
-
'Invalid audience'
|
35
|
-
) unless @payload['aud'].include?(options_aud)
|
36
|
-
end
|
24
|
+
verify_aud_array(@payload['aud'], options_aud)
|
37
25
|
else
|
38
26
|
raise(
|
39
27
|
JWT::InvalidAudError,
|
@@ -42,6 +30,16 @@ module JWT
|
|
42
30
|
end
|
43
31
|
end
|
44
32
|
|
33
|
+
def verify_aud_array(audience, options_aud)
|
34
|
+
if options_aud.is_a?(Array)
|
35
|
+
options_aud.each do |aud|
|
36
|
+
raise(JWT::InvalidAudError, 'Invalid audience') unless audience.include?(aud.to_s)
|
37
|
+
end
|
38
|
+
else
|
39
|
+
raise(JWT::InvalidAudError, 'Invalid audience') unless audience.include?(options_aud.to_s)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
45
43
|
def verify_expiration
|
46
44
|
return unless @payload.include?('exp')
|
47
45
|
|
data/lib/jwt/version.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
# Moments version builder module
|
4
5
|
module JWT
|
@@ -13,9 +14,9 @@ module JWT
|
|
13
14
|
# minor version
|
14
15
|
MINOR = 5
|
15
16
|
# tiny version
|
16
|
-
TINY =
|
17
|
+
TINY = 6
|
17
18
|
# alpha, beta, etc. tag
|
18
|
-
PRE = nil
|
19
|
+
PRE = nil
|
19
20
|
|
20
21
|
# Build version string
|
21
22
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
data/spec/jwt/verify_spec.rb
CHANGED
@@ -46,6 +46,19 @@ module JWT
|
|
46
46
|
it 'must allow an array with any value matching the one in the options with a string options key' do
|
47
47
|
Verify.verify_aud(array_payload, options.merge('aud' => array_aud.first))
|
48
48
|
end
|
49
|
+
|
50
|
+
it 'should allow strings or symbolds in options array' do
|
51
|
+
options['aud'] = [
|
52
|
+
'ruby-jwt-aud',
|
53
|
+
'test-aud',
|
54
|
+
'ruby-ruby-ruby',
|
55
|
+
:test
|
56
|
+
]
|
57
|
+
|
58
|
+
array_payload['aud'].push('test')
|
59
|
+
|
60
|
+
Verify.verify_aud(array_payload, options)
|
61
|
+
end
|
49
62
|
end
|
50
63
|
|
51
64
|
context '.verify_expiration(payload, options)' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jwt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Lindsay
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-09-
|
12
|
+
date: 2016-09-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|