json-jwt 1.9.1 → 1.17.2

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.
@@ -1,75 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe JSON::JWK::Set do
4
- let(:jwk) { public_key.to_jwk }
5
- let(:set) { JSON::JWK::Set.new jwk }
6
-
7
- describe '#content_type' do
8
- it do
9
- set.content_type.should == 'application/jwk-set+json'
10
- end
11
- end
12
-
13
- context 'when single JWK given' do
14
- subject { JSON::JWK::Set.new jwk }
15
- it { should == [jwk] }
16
- end
17
-
18
- context 'when multiple JWKs given' do
19
- subject { JSON::JWK::Set.new jwk, jwk }
20
- it { should == [jwk, jwk] }
21
- end
22
-
23
- context 'when an Array of JWKs given' do
24
- subject { JSON::JWK::Set.new [jwk, jwk] }
25
- it { should == [jwk, jwk] }
26
- end
27
-
28
- context 'when JSON::JWK given' do
29
- subject { JSON::JWK::Set.new jwk }
30
-
31
- it 'should keep JSON::JWK' do
32
- subject.each do |jwk|
33
- jwk.should be_instance_of JSON::JWK
34
- end
35
- end
36
- end
37
-
38
- context 'when pure Hash given' do
39
- subject { JSON::JWK::Set.new jwk.as_json }
40
-
41
- it 'should convert into JSON::JWK' do
42
- subject.each do |jwk|
43
- jwk.should be_instance_of JSON::JWK
44
- end
45
- end
46
- end
47
-
48
- context 'when pure Hash with :keys key given' do
49
- subject do
50
- JSON::JWK::Set.new(
51
- keys: jwk.as_json
52
- )
53
- end
54
-
55
- it 'should convert into JSON::JWK' do
56
- subject.each do |jwk|
57
- jwk.should be_instance_of JSON::JWK
58
- end
59
- end
60
- end
61
-
62
- describe '#as_json' do
63
- it 'should become proper JWK set format' do
64
- json = set.as_json
65
- json.should include :keys
66
- json[:keys].should == [jwk]
67
- end
68
- end
69
-
70
- describe '#to_json' do
71
- it do
72
- expect { set.to_json }.not_to raise_error
73
- end
74
- end
75
- end
@@ -1,194 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe JSON::JWK do
4
- describe '#initialize' do
5
- let(:jwk) { JSON::JWK.new key }
6
- subject { jwk }
7
-
8
- shared_examples_for :jwk_with_kid do
9
- it { should be_instance_of JSON::JWK }
10
- describe 'kid' do
11
- subject { jwk[:kid] }
12
- it { should == jwk.thumbprint }
13
- end
14
- end
15
-
16
- shared_examples_for :jwk_without_kid do
17
- it { should be_instance_of JSON::JWK }
18
- describe 'kid' do
19
- subject { jwk[:kid] }
20
- it { should be_blank }
21
- end
22
- end
23
-
24
- context 'when no imput' do
25
- it do
26
- JSON::JWK.new.should be_blank
27
- end
28
- end
29
-
30
- context 'with OpenSSL::PKey::RSA' do
31
- let(:key) { public_key }
32
- it_behaves_like :jwk_with_kid
33
- end
34
-
35
- context 'with OpenSSL::PKey::EC' do
36
- let(:key) { public_key :ecdsa }
37
- it_behaves_like :jwk_with_kid
38
- end
39
-
40
- context 'with String' do
41
- let(:key) { 'secret' }
42
- it_behaves_like :jwk_with_kid
43
- end
44
-
45
- context 'with JSON::JWK' do
46
- let(:key) do
47
- JSON::JWK.new(
48
- k: 'secret',
49
- kty: :oct
50
- )
51
- end
52
- it_behaves_like :jwk_with_kid
53
- end
54
-
55
- context 'with Hash' do
56
- let(:key) do
57
- {
58
- k: 'secret',
59
- kty: :oct
60
- }
61
- end
62
- it_behaves_like :jwk_with_kid
63
- end
64
-
65
- context 'with nothing' do
66
- let(:jwk) { JSON::JWK.new }
67
- it_behaves_like :jwk_without_kid
68
- end
69
- end
70
-
71
- describe '#content_type' do
72
- let(:jwk) { JSON::JWK.new public_key }
73
- it do
74
- jwk.content_type.should == 'application/jwk+json'
75
- end
76
- end
77
-
78
- context 'when RSA public key given' do
79
- let(:jwk) { JSON::JWK.new public_key }
80
- it { jwk.keys.collect(&:to_sym).should include :kty, :e, :n }
81
- its(:kty) { jwk[:kty].should == :RSA }
82
- its(:e) { jwk[:e].should == UrlSafeBase64.encode64(public_key.e.to_s(2)) }
83
- its(:n) { jwk[:n].should == UrlSafeBase64.encode64(public_key.n.to_s(2)) }
84
-
85
- context 'when kid/use options given' do
86
- let(:jwk) { JSON::JWK.new public_key, kid: '12345', use: :sig }
87
- it { jwk.keys.collect(&:to_sym).should include :kid, :use }
88
- its(:kid) { jwk[:kid].should == '12345' }
89
- its(:use) { jwk[:use].should == :sig }
90
- end
91
-
92
- describe '#thumbprint' do
93
- context 'using default hash function' do
94
- subject { jwk.thumbprint }
95
- it { should == 'nuBTimkcSt_AuEsD8Yv3l8CoGV31bu_3gsRDGN1iVKA' }
96
- end
97
-
98
- context 'using SHA512 hash function' do
99
- subject { jwk.thumbprint :SHA512 }
100
- it { should == '6v7pXTnQLMiQgvJlPJUdhAUSuGLzgF8C1r3ABAMFet6bc53ea-Pq4ZGbGu3RoAFsNRT1-RhTzDqtqXuLU6NOtw' }
101
- end
102
- end
103
-
104
- describe '#to_key' do
105
- it { jwk.to_key.should be_instance_of OpenSSL::PKey::RSA }
106
- end
107
- end
108
-
109
- context 'when EC public key given' do
110
- let(:jwk) { JSON::JWK.new public_key(:ecdsa) }
111
- let(:expected_coordinates) do
112
- {
113
- 256 => {
114
- x: 'saPyrO4Lh9kh2FxrF9y1QVmZznWnRRJwpr12UHqzrVY',
115
- y: 'MMz4W9zzqlrJhqr-JyrpvlnaIIyZQE6DfrgPkxMAw1M'
116
- },
117
- 384 => {
118
- x: 'plzApyFnK7qzhg5XnIZbFj2hZoH2Vdl4-RFm7DnsNMG9tyqrpfq2RyjfKABbcFRt',
119
- y: 'ixBzffhk3fcbmeipGLkvQBNCzeNm6QL3hOUTH6IFBzOL0Y7HsGTopNTTspLjlivb'
120
- },
121
- 512 => {
122
- x: 'AcMCD-a0a6rnE9TvC0mOqF_DGXRg5Y3iTb4eHNwTm2kD6iujx9M_f8d_FGHr0OhpqzEn4rYPYZouGsbIPEgL0q__',
123
- y: 'AULYEd8l-bV_BI289aezhSLZ1RDF2ltgDPEy9Y7YtqYa4cJcpiyzVDMpXWwBp6cjg6TXINkoVrVXZhN404ihu4I2'
124
- }
125
- }
126
- end
127
-
128
- [256, 384, 512].each do |digest_length|
129
- describe "EC#{digest_length}" do
130
- let(:jwk) { JSON::JWK.new public_key(:ecdsa, digest_length: digest_length) }
131
- it { jwk.keys.collect(&:to_sym).should include :kty, :crv, :x, :y }
132
- its(:kty) { jwk[:kty].should == :EC }
133
- its(:x) { jwk[:x].should == expected_coordinates[digest_length][:x] }
134
- its(:y) { jwk[:y].should == expected_coordinates[digest_length][:y] }
135
- end
136
- end
137
-
138
- describe 'unknown curve' do
139
- it do
140
- key = OpenSSL::PKey::EC.new('secp112r2').generate_key
141
- expect do
142
- JSON::JWK.new key
143
- end.to raise_error JSON::JWK::UnknownAlgorithm, 'Unknown EC Curve'
144
- end
145
- end
146
-
147
- describe '#thumbprint' do
148
- context 'using default hash function' do
149
- subject { jwk.thumbprint }
150
- it { should == '-egRpLjyZCqxBh4OOfd8JSvXwayHmNFAUNkbi8exfhc' }
151
- end
152
-
153
- context 'using SHA512 hash function' do
154
- subject { jwk.thumbprint :SHA512 }
155
- it { should == 'B_yXDZJ9doudaVCj5q5vqxshvVtW2IFnz_ypvRt5O60gemkDAhO78L6YMyTWH0ZRm15cO2_laTSaNO9yZQFsvQ' }
156
- end
157
- end
158
-
159
- describe '#to_key' do
160
- it { jwk.to_key.should be_instance_of OpenSSL::PKey::EC }
161
- end
162
- end
163
-
164
- context 'when shared secret given' do
165
- let(:jwk) { JSON::JWK.new 'secret' }
166
- its(:kty) { jwk[:kty].should == :oct }
167
- its(:x) { jwk[:k].should == 'secret' }
168
-
169
- describe '#thumbprint' do
170
- context 'using default hash function' do
171
- subject { jwk.thumbprint }
172
- it { should == 'XZPWsTEZFIerowAF9GHzBtq5CkAOcVvIBnkMu0IIQH0' }
173
- end
174
-
175
- context 'using SHA512 hash function' do
176
- subject { jwk.thumbprint :SHA512 }
177
- it { should == 'rK7EtcEe9Xr0kryR9lNnyOTRe7Vb_BglbTBtbcVG2LzvL26_PFaMCwOtiUiXWfCK-wV8vcxjmvbcvV4ZxDE0FQ' }
178
- end
179
- end
180
-
181
- describe '#to_key' do
182
- it { jwk.to_key.should be_instance_of String }
183
- end
184
- end
185
-
186
- describe 'unknown key type' do
187
- it do
188
- key = OpenSSL::PKey::DSA.generate 256
189
- expect do
190
- JSON::JWK.new key
191
- end.to raise_error JSON::JWK::UnknownAlgorithm, 'Unknown Key Type'
192
- end
193
- end
194
- end
@@ -1,324 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe JSON::JWS do
4
- let(:alg) { :none }
5
- let(:jwt) do
6
- _jwt_ = JSON::JWT.new claims
7
- _jwt_.alg = alg
8
- _jwt_
9
- end
10
- let(:jws) { JSON::JWS.new jwt }
11
- let(:signed) { jws.sign! private_key_or_secret }
12
- let(:decoded) { JSON::JWT.decode signed.to_s, public_key_or_secret }
13
- let(:claims) do
14
- {
15
- iss: 'joe',
16
- exp: 1300819380,
17
- :'http://example.com/is_root' => true
18
- }
19
- end
20
- let(:expected_signature) do
21
- {
22
- :HS256 => 'DyuTgO2Ggb5nrhkkhI-RjVYIBe3o8oL4ijkAn94YPxQ',
23
- :HS384 => 'a5-7rr61TG8Snv9xxJ7l064ky-SCq1Mswe9t8HEorvoc_nnfIeUy9WQCLMIli34R',
24
- :HS512 => 'ce-GlHDaNwaHfmAFRGp3QPPKvrpruTug2hC1bf6yNlbuvkMwJw2jFZgq_4wmIPetRdiBy7XFq7rrtmw1Im7tmQ',
25
- :RS256 => 'E5VELqAdla2Bx1axc9KFxO0EiCr0Mw6HPYX070qGQ8zA_XmyxGPUZLyyWU_6Cn399W-oYBWO2ynLlr8pqqjP3jXevyCeYeGRVN0HzLYiBebEugNnc3hevr7WV2UzfksWRA-Ux2bDv2sz9p_LGbL33wWNxGDvIlpDyZUul_a48nCipS0riBjkTLTSE8dfBxQTXEF5GEUUu99ot6aBLzUhc25nHXSXogXF6MHK-hAcE7f4v-vJ0lbPbHLVGUopIoxoqe4XjoBpzE5UvhrVl5LYbdjbyJhu5ZIA8GLsgwtUFh3dfdIechORoR3k5NSFSv8157bAEa8t4iwgWD2MSNSQnw',
26
- :RS384 => 'lT5JbytGKgG9QrwkJuxgw7UjmN9tjkEQW9pVGR2XnKEdC0_wLNIzAmT-jTwyMDGBLUkWO7opDOP6Xy6_DOTg58k9PwVkyQzrLnmxJMEng2Q-aMqcitRSIvUk3DPy8kemp8yUPls9NzWmByM2GoUVHbDsR0r-tZN-g_9QYev32mvMhjMr30JI5S2xiRjc9m2GAaXMOQmNTovJgV4bgCp4UjruCrA0BD1JJwDqKYoR_YYr_ALcVjD_LUgy80udJvbi8MAYJVUf0QYtQDrX2wnT_-eiiWjD5XafLuXEQVDRh-v2MKAwdvtXMq5cZ08Zjl2SyHxJ3OqhEeWPvYGltxZh_A',
27
- :RS512 => 'EHeGM2Mo3ghhUfSB99AlREehrbC6OPE-nYL_rwf88ysTnJ8L1QQ0UuCrXq4SpRutGLK_bYTK3ZALvFRPoOgK_g0QWmqv6qjQRU_QTxoq8y8APP-IgKKDuIiGH6daBV2rAPLDReqYNKsKjmTvZJo2c0a0e_WZkkj_ZwpgjTG3v0gW9lbDAzLJDz18eqtR4ZO7JTu_fyNrUrNk-w2_wpxSsn9sygIMp0lKE0_pt0b01fz3gjTDjlltU0cKSalUp4geaBDH7QRcexrolIctdQFbNKTXQxoigxD3NLNkKGH7f6A8KZdcOm8AnEjullcZs8_OWGnW43p1qrxoBRSivb9pqQ'
28
- }
29
- end
30
-
31
- shared_examples_for :jwt_with_alg do
32
- it { should == jwt }
33
- its(:header) { should == jwt.header }
34
- end
35
-
36
- context 'before sign' do
37
- subject { jws }
38
- it_behaves_like :jwt_with_alg
39
- its(:signature) { should be_nil }
40
- end
41
-
42
- describe '#content_type' do
43
- it do
44
- jws.content_type.should == 'application/jose'
45
- end
46
- end
47
-
48
- describe '#sign!' do
49
- shared_examples_for :generate_expected_signature do
50
- it do
51
- UrlSafeBase64.encode64(signed.signature).should == expected_signature[alg]
52
- end
53
- end
54
- subject { signed }
55
-
56
- [:HS256, :HS384, :HS512].each do |algorithm|
57
- describe algorithm do
58
- let(:alg) { algorithm }
59
-
60
- context 'when String key given' do
61
- let(:private_key_or_secret) { shared_secret }
62
- it_behaves_like :jwt_with_alg
63
- it_behaves_like :generate_expected_signature
64
- end
65
-
66
- context 'when JSON::JWK key given' do
67
- let(:private_key_or_secret) { JSON::JWK.new shared_secret }
68
- it_behaves_like :jwt_with_alg
69
- it_behaves_like :generate_expected_signature
70
- end
71
- end
72
- end
73
-
74
- [:RS256, :RS384, :RS512].each do |algorithm|
75
- describe algorithm do
76
- let(:alg) { algorithm }
77
-
78
- context 'when OpenSSL::PKey::RSA key given' do
79
- let(:private_key_or_secret) { private_key }
80
- it_behaves_like :jwt_with_alg
81
- it_behaves_like :generate_expected_signature
82
- end
83
-
84
- context 'when JSON::JWK key given' do
85
- let(:private_key_or_secret) { JSON::JWK.new private_key }
86
- it_behaves_like :jwt_with_alg
87
- it_behaves_like :generate_expected_signature
88
- end
89
- end
90
- end
91
-
92
- [:ES256, :ES384, :ES512].each do |algorithm|
93
- describe algorithm do
94
- let(:alg) { algorithm }
95
-
96
- shared_examples_for :self_verifiable do
97
- it 'should be self-verifiable' do
98
- expect do
99
- JSON::JWT.decode(
100
- JSON::JWT.new(claims).sign(
101
- private_key_or_secret, algorithm
102
- ).to_s, public_key_or_secret
103
- )
104
- end.not_to raise_error
105
- end
106
- end
107
-
108
- context 'when OpenSSL::PKey::EC key given' do
109
- let(:private_key_or_secret) { private_key :ecdsa, digest_length: algorithm.to_s[2,3].to_i }
110
- let(:public_key_or_secret) { public_key :ecdsa, digest_length: algorithm.to_s[2,3].to_i }
111
- it_behaves_like :jwt_with_alg
112
- it_behaves_like :self_verifiable
113
- end
114
-
115
- context 'when JSON::JWK key given' do
116
- let(:private_key_or_secret) { JSON::JWK.new(private_key :ecdsa, digest_length: algorithm.to_s[2,3].to_i) }
117
- let(:public_key_or_secret) { JSON::JWK.new(public_key :ecdsa, digest_length: algorithm.to_s[2,3].to_i) }
118
- it_behaves_like :jwt_with_alg
119
- it_behaves_like :self_verifiable
120
- end
121
- end
122
- end
123
-
124
- context 'when JSON::JWK::Set key given' do
125
- let(:alg) { :HS256 }
126
- let(:kid) { 'kid' }
127
- let(:jwks) do
128
- jwk = JSON::JWK.new shared_secret, kid: kid
129
- JSON::JWK::Set.new jwk, JSON::JWK.new('another')
130
- end
131
- let(:signed) { jws.sign!(jwks) }
132
-
133
- context 'when jwk is found by given kid' do
134
- before { jws.kid = kid }
135
- it { should == jws.sign!('secret') }
136
- end
137
-
138
- context 'otherwise' do
139
- it do
140
- expect do
141
- subject
142
- end.to raise_error JSON::JWK::Set::KidNotFound
143
- end
144
- end
145
- end
146
-
147
- describe 'unknown algorithm' do
148
- let(:alg) { :unknown }
149
- it do
150
- expect do
151
- jws.sign! 'key'
152
- end.to raise_error JSON::JWS::UnexpectedAlgorithm
153
- end
154
- end
155
- end
156
-
157
- describe '#verify!' do
158
- shared_examples_for :success_signature_verification do
159
- it do
160
- expect { decoded }.not_to raise_error
161
- decoded.should be_a JSON::JWT
162
- end
163
-
164
- describe 'header' do
165
- let(:header) { decoded.header }
166
- it 'should be parsed successfully' do
167
- header[:typ].should == 'JWT'
168
- header[:alg].should == alg.to_s
169
- end
170
- end
171
-
172
- describe 'claims' do
173
- it 'should be parsed successfully' do
174
- decoded[:iss].should == 'joe'
175
- decoded[:exp].should == 1300819380
176
- decoded[:'http://example.com/is_root'] == true
177
- end
178
- end
179
- end
180
- subject { decoded }
181
-
182
- [:HS256, :HS384, :HS512].each do |algorithm|
183
- describe algorithm do
184
- let(:alg) { algorithm }
185
- let(:private_key_or_secret) { shared_secret }
186
-
187
- context 'when String key given' do
188
- let(:public_key_or_secret) { shared_secret }
189
- it_behaves_like :success_signature_verification
190
- end
191
-
192
- context 'when JSON::JWK key given' do
193
- let(:public_key_or_secret) { JSON::JWK.new shared_secret }
194
- it_behaves_like :success_signature_verification
195
- end
196
- end
197
- end
198
-
199
- [:RS256, :RS384, :RS512].each do |algorithm|
200
- describe algorithm do
201
- let(:alg) { algorithm }
202
- let(:private_key_or_secret) { private_key }
203
-
204
- context 'when OpenSSL::PKey::RSA key given' do
205
- let(:public_key_or_secret) { public_key }
206
- it_behaves_like :success_signature_verification
207
- end
208
-
209
- context 'when JSON::JWK key given' do
210
- let(:public_key_or_secret) { JSON::JWK.new public_key }
211
- it_behaves_like :success_signature_verification
212
- end
213
- end
214
- end
215
-
216
- [:ES256, :ES384, :ES512].each do |algorithm|
217
- describe algorithm do
218
- let(:alg) { algorithm }
219
- let(:private_key_or_secret) { private_key :ecdsa, digest_length: algorithm.to_s[2,3].to_i }
220
-
221
- context 'when OpenSSL::PKey::EC key given' do
222
- let(:public_key_or_secret) { public_key :ecdsa, digest_length: algorithm.to_s[2,3].to_i }
223
- it_behaves_like :success_signature_verification
224
- end
225
-
226
- context 'when JSON::JWK key given' do
227
- let(:public_key_or_secret) { JSON::JWK.new public_key(:ecdsa, digest_length: algorithm.to_s[2,3].to_i) }
228
- it_behaves_like :success_signature_verification
229
- end
230
- end
231
- end
232
-
233
- context 'when JSON::JWK::Set key given' do
234
- subject { JSON::JWT.decode signed.to_s, jwks }
235
-
236
- let(:alg) { :HS256 }
237
- let(:kid) { 'kid' }
238
- let(:jwks) do
239
- jwk = JSON::JWK.new shared_secret, kid: kid
240
- JSON::JWK::Set.new jwk, JSON::JWK.new('another')
241
- end
242
- let(:signed) { jws.sign!(jwks) }
243
-
244
- context 'when jwk is found by given kid' do
245
- before { jws.kid = kid }
246
- it { should == signed }
247
- end
248
-
249
- context 'otherwise' do
250
- it do
251
- expect do
252
- subject
253
- end.to raise_error JSON::JWK::Set::KidNotFound
254
- end
255
- end
256
- end
257
-
258
- describe 'unknown algorithm' do
259
- let(:alg) { :unknown }
260
- it do
261
- expect do
262
- jws.verify! 'key'
263
- end.to raise_error JSON::JWS::UnexpectedAlgorithm
264
- end
265
- end
266
- end
267
-
268
- describe '#to_json' do
269
- let(:alg) { :RS256 }
270
- let(:private_key_or_secret) { private_key }
271
-
272
- context 'as default' do
273
- it 'should JSONize payload' do
274
- jws.to_json.should == claims.to_json
275
- end
276
- end
277
-
278
- context 'when syntax option given' do
279
- context 'when general' do
280
- it 'should return General JWS JSON Serialization' do
281
- signed.to_json(syntax: :general).should == {
282
- payload: UrlSafeBase64.encode64(claims.to_json),
283
- signatures: [{
284
- protected: UrlSafeBase64.encode64(signed.header.to_json),
285
- signature: UrlSafeBase64.encode64(signed.signature)
286
- }]
287
- }.to_json
288
- end
289
-
290
- context 'when not signed yet' do
291
- it 'should not fail' do
292
- jws.to_json(syntax: :general).should == {
293
- payload: UrlSafeBase64.encode64(claims.to_json),
294
- signatures: [{
295
- protected: UrlSafeBase64.encode64(jws.header.to_json),
296
- signature: UrlSafeBase64.encode64('')
297
- }]
298
- }.to_json
299
- end
300
- end
301
- end
302
-
303
- context 'when flattened' do
304
- it 'should return Flattened JWS JSON Serialization' do
305
- signed.to_json(syntax: :flattened).should == {
306
- protected: UrlSafeBase64.encode64(signed.header.to_json),
307
- payload: UrlSafeBase64.encode64(claims.to_json),
308
- signature: UrlSafeBase64.encode64(signed.signature)
309
- }.to_json
310
- end
311
-
312
- context 'when not signed yet' do
313
- it 'should not fail' do
314
- jws.to_json(syntax: :flattened).should == {
315
- protected: UrlSafeBase64.encode64(jws.header.to_json),
316
- payload: UrlSafeBase64.encode64(claims.to_json),
317
- signature: UrlSafeBase64.encode64('')
318
- }.to_json
319
- end
320
- end
321
- end
322
- end
323
- end
324
- end