json-jwt 1.2.2 → 1.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.

Potentially problematic release.


This version of json-jwt might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4956348cf3828c6139ccc4d07759b219e57bb251
4
- data.tar.gz: 68f781f2de2c2503eda3abf3418f8f80f908d5dc
3
+ metadata.gz: 1815ea41a4fd9ae6a1d6232259a7956ba070b713
4
+ data.tar.gz: 2efa46ef39b82e61e5d58817cd804eb3dd50d053
5
5
  SHA512:
6
- metadata.gz: c3f0df77b65f72a920743330dd3fbc9338c73e6df493746abafdf4ca2b370090892eb6b6b7c636b4db569af03a6e0e288425ea0d0df56fee28b6ae7dbee90cf3
7
- data.tar.gz: 66b3c28180bd8573f1813e1db5922de6b7253ac4965cf30c9b307ffb6820520b4e76fdd1ba9d0d467bee2533a8eb6ba7a5b510d2e5ca480b5ab9e0d31abd966d
6
+ metadata.gz: a3ecc9a34475f36916f12242f2293db9d9c5a0382619bf250ef1b5aa5650ae0030cfbcc533a56ebbd63a2f43e065f27322c4dc747fee850310f6d8ecab30ce93
7
+ data.tar.gz: e4c2d71d75053fc1357e1d0e88b9f88e048587d11189dfdb934e24f3a74b33f7e9dec885aeb1874ffff16609e4bcae15b893efd68d5e5cf6490a90771a4dd3e3
data/README.md CHANGED
@@ -15,7 +15,9 @@ JSON Web Token and its family (JSON Web Signature, JSON Web Encryption and JSON
15
15
 
16
16
  ## Examples
17
17
 
18
- ### Encoding
18
+ ### JWT, JWS and JWE
19
+
20
+ #### Encoding
19
21
 
20
22
  ```ruby
21
23
  require 'json/jwt'
@@ -40,11 +42,38 @@ jwe = jws.encrypt(key, algorithm, encryption_method) # algorithm & encryption_me
40
42
  jwe.to_s # => header.encrypted_key.iv.cipher_text.authentication_tag
41
43
  ```
42
44
 
43
- For details about `key` and `algorithm`, see
44
- [JWS Spec](https://github.com/nov/json-jwt/blob/master/spec/json/jws_spec.rb) and
45
- [Sign Key Fixture Generator](https://github.com/nov/json-jwt/blob/master/spec/helpers/sign_key_fixture_helper.rb).
46
-
47
- ### Decoding
45
+ Supported `key` are
46
+ * `String`
47
+ * `OpenSSL::PKey::RSA`
48
+ * `OpenSSL::PKey::EC`
49
+ * `JSON::JWK`
50
+ * `JSON::JWK::Set` # NOTE: proper `JSON::JWK` in the set will be selected by `kid` in the header.
51
+
52
+ Supported `algorithm` are
53
+
54
+ For JWS
55
+ * `HS256`
56
+ * `HS384`
57
+ * `HS512`
58
+ * `RS256`
59
+ * `RS384`
60
+ * `RS512`
61
+ * `ES256`
62
+ * `ES384`
63
+ * `ES512`
64
+
65
+ For JWE
66
+ * `RSA1_5`
67
+ * `RSA-OAEP`
68
+ * `dir`
69
+
70
+ Supported `encryption_method` are
71
+ * `A128GCM`
72
+ * `A256GCM`
73
+ * `A128CBC-HS256`
74
+ * `A256CBC-HS512`
75
+
76
+ #### Decoding
48
77
 
49
78
  ```ruby
50
79
  jwt_string = "jwt_header.jwt_claims.jwt_signature"
@@ -52,6 +81,44 @@ jwt_string = "jwt_header.jwt_claims.jwt_signature"
52
81
  JSON::JWT.decode(jwt_string, key)
53
82
  ```
54
83
 
84
+ ### JWK
85
+
86
+ #### RSA
87
+
88
+ ```ruby
89
+ k = OpenSSL::PKey::RSA.new(2048)
90
+ p k.to_jwk
91
+ # => JSON::JWK
92
+
93
+ jwk = JSON::JWK.new(
94
+ kty: "RSA",
95
+ e: "AQAB",
96
+ n: "utwietJHu65N7kIa52bMkKgbS1CGmhKNDx3gTBEvQmQhg1BbKHfdmqapMt699T-aloeslYxeO9ItOhprnE0vG-pbDUE7Jg51gtK6kjpLFZOLNpRHJnRikyF6dav1IdJa4fSpOiEJiHk_DuFnAMI04_1H_NISn1TzEBflbyb6BSyIPkfO9433zR2-clvHdIXppq-N272vHA64Xp5hslzY91QodXo5--9iIblPVxzd9aH-aBMSkRbmlIKuz14tWhR-6RLNsWtqxWfKvgeoBLh5e9E5MrlNuRnaaLqHOMWrW1l9985eqmCD3PD4wjwINFKrU4L0fMBCHgCDAZLhbLfUJw",
97
+ d: "NtFBpDpwJNT7s7vc3KnBtWY7q5qSAj0S-K5REL-x1448bqNyOqr_bdEarfu-SmZAWYyvyqeFNZNxBSyfCRlzioLz9y19xqpTOu_LH_7N7CR-oKJbRSK7kGIv5Llvjl6BnuwBgTYT799x6lGhwA05KvEw3zBZmjh3ne8Etdj_W-i2LDBDUimgmVrgXWY1KvWFgh2zpptIINX2Q8UxV121bdcBIbj008Cs64m2mMpaa3ggqqNoXnYb8HnJDnYx-WIbUMHJ2-hpZAsVFNet8ZVEMt4cTKaTHY23m9Ditj-7VfFzkoiH9Yj45ewJMpcssadnAPrBgKbjTFuTdJfP8IqMoQ"
98
+ )
99
+ jwk.to_key
100
+ # => OpenSSL::PKey::RSA
101
+ ```
102
+
103
+ #### EC
104
+
105
+ ```ruby
106
+ k = OpenSSL::PKey::RSA.new(2048)
107
+ k.to_jwk
108
+ # => JSON::JWK
109
+
110
+ jwk = JSON::JWK.new(
111
+ kty: "RSA",
112
+ e: "AQAB",
113
+ n: "0OIOijENzP0AXnxP-X8Dnazt3m4NTamfNsSCkH4xzgZAJj2Eur9-zmq9IukwN37lIrm3oAE6lL4ytNkv-DQpAivKLE8bh4c9qlB9o32VWyg-mg-2af-JlfGXYoaCW2GDMOV6EKqHBxE0x1EI0tG4gcNwO6A_kYtK6_ACgTQudWz_gnPrL-QCunjIMbbrK9JqgMZhgMARMQpB-j8oet2FFsEcquR5MWtBeAn7qC1AD2ya0EmzplZJP6oCka_VVuxAnyWfRGA0bzCBRIVbcGUXVNIXpRtA_4960e7AlGfMSA-ofN-vo7v0CMkA8BwpZHai9CAJ-cTCX1AVbov83LVIWw",
114
+ d: "BZCgNopMBdQPuHSzZMA_hmnfBHgGHrWQKlNd7x-NkCGWf-5PpPIJHNK3K0DvKetVi3FLNRYTS3ctvqeyoXgyR36HKlsJLrkpqWnvjvV_jygpUs1sXLKUJcyD7foLawfUCO90KxF_-24367967rLrqXldehkw2F3Ppy2Dw5FyU2qBqcpLeruBt6-UdMmBufzNQLisPJ67vhCTVrTNaHDDeCK2gHI3gqsnnbzOMS45VknmFOgKUp1C8GZu5BsT-AdDApEtY-DRZqnr6BxZv4-hG5OdEUA4_LCaI6JwlaAzv0Z74jpBZDC73cXWKJPgVuhARZcll5cexB2_EpgZDB6akQ",
115
+ p: "6GFVNgaXcW39NG-sRqKPzFtz1usfAkdCydPmfZirfHRhSh3OojX3Glbe7BI_SRSOLc2d2xw2_ZwKRlruY44aGEf4s5gD_nKgq2QS-1cA5uNAU91wRtY2rdoAuCnk2BX3WTZPnzyxkokFY0S0R_9IpJhRz72ggxYyhx0ymRUBIWc",
116
+ q: "5h1QX2JWLbcIT_cfrkmMoES1z06Fu88MLORYppiRDqkXl3CJFxKFtKJtDPLTf0MeTFexh81V52Ztsd8UttPInyDl9l5T0AOy8NmqHKqjI1063uy4bnHWetN7ovHftc_TOlnldAoQh9bmhZAhEyGlwa5Kros2YD2amIgDhcOmRO0"
117
+ )
118
+ jwk.to_key
119
+ # => OpenSSL::PKey::EC
120
+ ```
121
+
55
122
  ## Note on Patches/Pull Requests
56
123
 
57
124
  * Fork the project.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.2
1
+ 1.2.3
data/lib/json/jwk.rb CHANGED
@@ -2,15 +2,19 @@ module JSON
2
2
  class JWK < ActiveSupport::HashWithIndifferentAccess
3
3
  class UnknownAlgorithm < JWT::Exception; end
4
4
 
5
- def initialize(constructor = {}, ex_params = {})
6
- if constructor.is_a? OpenSSL::PKey::PKey
7
- if constructor.respond_to? :to_jwk
8
- super constructor.to_jwk(ex_params)
9
- else
10
- raise UnknownAlgorithm.new('Unknown Key Type')
11
- end
5
+ def initialize(params = {}, ex_params = {})
6
+ case params
7
+ when OpenSSL::PKey::RSA, OpenSSL::PKey::EC
8
+ super params.to_jwk(ex_params)
9
+ when OpenSSL::PKey::PKey
10
+ raise UnknownAlgorithm.new('Unknown Key Type')
11
+ when String
12
+ super(
13
+ k: params,
14
+ kty: :oct
15
+ )
12
16
  else
13
- super constructor
17
+ super params
14
18
  merge! ex_params
15
19
  end
16
20
  end
@@ -88,7 +92,7 @@ module JSON
88
92
  end
89
93
 
90
94
  def to_rsa_key
91
- e, n, d = [:e, :n, :d].collect do |key|
95
+ e, n, d, p, q = [:e, :n, :d, :p, :q].collect do |key|
92
96
  if self[key]
93
97
  OpenSSL::BN.new UrlSafeBase64.decode64(self[key]), 2
94
98
  end
@@ -97,6 +101,8 @@ module JSON
97
101
  key.e = e
98
102
  key.n = n
99
103
  key.d = d if d
104
+ key.p = p if p
105
+ key.q = q if q
100
106
  key
101
107
  end
102
108
 
@@ -8,7 +8,13 @@ module JSON
8
8
  e: UrlSafeBase64.encode64(e.to_s(2)),
9
9
  n: UrlSafeBase64.encode64(n.to_s(2))
10
10
  }.merge ex_params
11
- params[:d] = UrlSafeBase64.encode64(d.to_s(2)) if private?
11
+ if private?
12
+ params.merge!(
13
+ d: UrlSafeBase64.encode64(d.to_s(2)),
14
+ p: UrlSafeBase64.encode64(p.to_s(2)),
15
+ q: UrlSafeBase64.encode64(q.to_s(2))
16
+ )
17
+ end
12
18
  JWK.new params
13
19
  end
14
20
  end
@@ -2,7 +2,42 @@ require 'spec_helper'
2
2
 
3
3
  describe JSON::JWK do
4
4
  describe '#initialize' do
5
- it :TODO
5
+ subject { JSON::JWK.new key }
6
+
7
+ context 'with OpenSSL::PKey::RSA' do
8
+ let(:key) { public_key }
9
+ it { should be_instance_of JSON::JWK }
10
+ end
11
+
12
+ context 'with OpenSSL::PKey::EC' do
13
+ let(:key) { public_key :ecdsa }
14
+ it { should be_instance_of JSON::JWK }
15
+ end
16
+
17
+ context 'with String' do
18
+ let(:key) { 'secret' }
19
+ it { should be_instance_of JSON::JWK }
20
+ end
21
+
22
+ context 'with JSON::JWK' do
23
+ let(:key) do
24
+ JSON::JWK.new(
25
+ k: 'secret',
26
+ kty: :oct
27
+ )
28
+ end
29
+ it { should be_instance_of JSON::JWK }
30
+ end
31
+
32
+ context 'with Hash' do
33
+ let(:key) do
34
+ {
35
+ k: 'secret',
36
+ kty: :oct
37
+ }
38
+ end
39
+ it { should be_instance_of JSON::JWK }
40
+ end
6
41
  end
7
42
 
8
43
  describe '#content_type' do
@@ -85,6 +120,41 @@ describe JSON::JWK do
85
120
  end
86
121
  end
87
122
 
123
+ describe '#thumbprint' do
124
+ context 'when kty=RSA' do
125
+ subject do
126
+ JSON::JWK.new(
127
+ kty: :RSA,
128
+ e: 'AQAB',
129
+ n: '0OIOijENzP0AXnxP-X8Dnazt3m4NTamfNsSCkH4xzgZAJj2Eur9-zmq9IukwN37lIrm3oAE6lL4ytNkv-DQpAivKLE8bh4c9qlB9o32VWyg-mg-2af-JlfGXYoaCW2GDMOV6EKqHBxE0x1EI0tG4gcNwO6A_kYtK6_ACgTQudWz_gnPrL-QCunjIMbbrK9JqgMZhgMARMQpB-j8oet2FFsEcquR5MWtBeAn7qC1AD2ya0EmzplZJP6oCka_VVuxAnyWfRGA0bzCBRIVbcGUXVNIXpRtA_4960e7AlGfMSA-ofN-vo7v0CMkA8BwpZHai9CAJ-cTCX1AVbov83LVIWw'
130
+ )
131
+ end
132
+ its(:thumbprint) { should == 'fFn3D1P0H7Qo1ugQ-5LM6LC63LtArbkPsbQcs2F-1yA' }
133
+ end
134
+
135
+ context 'when kty=EC' do
136
+ subject do
137
+ JSON::JWK.new(
138
+ kty: 'EC',
139
+ crv: 'P-256',
140
+ x: 'saPyrO4Lh9kh2FxrF9y1QVmZznWnRRJwpr12UHqzrVY',
141
+ y: 'MMz4W9zzqlrJhqr-JyrpvlnaIIyZQE6DfrgPkxMAw1M'
142
+ )
143
+ end
144
+ its(:thumbprint) { should == '-egRpLjyZCqxBh4OOfd8JSvXwayHmNFAUNkbi8exfhc' }
145
+ end
146
+
147
+ context 'when kty=oct' do
148
+ subject do
149
+ JSON::JWK.new(
150
+ kty: 'oct',
151
+ k: 'secret'
152
+ )
153
+ end
154
+ its(:thumbprint) { should == 'XZPWsTEZFIerowAF9GHzBtq5CkAOcVvIBnkMu0IIQH0' }
155
+ end
156
+ end
157
+
88
158
  describe '.decode' do
89
159
  context 'when RSA' do
90
160
  subject do
@@ -55,25 +55,45 @@ describe JSON::JWS do
55
55
 
56
56
  [:HS256, :HS384, :HS512].each do |algorithm|
57
57
  describe algorithm do
58
- let(:private_key_or_secret) { shared_secret }
59
58
  let(:alg) { algorithm }
60
- it_behaves_like :jwt_with_alg
61
- it_behaves_like :generate_expected_signature
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
62
71
  end
63
72
  end
64
73
 
65
74
  [:RS256, :RS384, :RS512].each do |algorithm|
66
75
  describe algorithm do
67
- let(:private_key_or_secret) { private_key }
68
76
  let(:alg) { algorithm }
69
- it_behaves_like :jwt_with_alg
70
- it_behaves_like :generate_expected_signature
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
71
89
  end
90
+ end
72
91
 
73
- [:ES256, :ES384, :ES512].each do |algorithm|
74
- describe algorithm do
75
- let(:private_key_or_secret) { private_key :ecdsa, digest_length: algorithm.to_s[2,3].to_i }
76
- let(:public_key_or_secret) { public_key :ecdsa, digest_length: algorithm.to_s[2,3].to_i }
92
+ [:ES256, :ES384, :ES512].each do |algorithm|
93
+ describe algorithm do
94
+ let(:alg) { algorithm }
95
+
96
+ shared_examples_for :self_verifiable do
77
97
  it 'should be self-verifiable' do
78
98
  expect do
79
99
  JSON::JWT.decode(
@@ -84,9 +104,27 @@ describe JSON::JWS do
84
104
  end.not_to raise_error
85
105
  end
86
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
87
121
  end
88
122
  end
89
123
 
124
+ context 'when JSON::JWK::Set key given' do
125
+ it :TODO
126
+ end
127
+
90
128
  describe 'unknown algorithm' do
91
129
  let(:alg) { :unknown }
92
130
  it do
@@ -124,28 +162,52 @@ describe JSON::JWS do
124
162
 
125
163
  [:HS256, :HS384, :HS512].each do |algorithm|
126
164
  describe algorithm do
127
- let(:private_key_or_secret) { shared_secret }
128
- let(:public_key_or_secret) { shared_secret }
129
165
  let(:alg) { algorithm }
130
- it_behaves_like :success_signature_verification
166
+ let(:private_key_or_secret) { shared_secret }
167
+
168
+ context 'when String key given' do
169
+ let(:public_key_or_secret) { shared_secret }
170
+ it_behaves_like :success_signature_verification
171
+ end
172
+
173
+ context 'when JSON::JWK key given' do
174
+ let(:public_key_or_secret) { JSON::JWK.new shared_secret }
175
+ it_behaves_like :success_signature_verification
176
+ end
131
177
  end
132
178
  end
133
179
 
134
180
  [:RS256, :RS384, :RS512].each do |algorithm|
135
181
  describe algorithm do
136
- let(:private_key_or_secret) { private_key }
137
- let(:public_key_or_secret) { public_key }
138
182
  let(:alg) { algorithm }
139
- it_behaves_like :success_signature_verification
183
+ let(:private_key_or_secret) { private_key }
184
+
185
+ context 'when OpenSSL::PKey::RSA key given' do
186
+ let(:public_key_or_secret) { public_key }
187
+ it_behaves_like :success_signature_verification
188
+ end
189
+
190
+ context 'when JSON::JWK key given' do
191
+ let(:public_key_or_secret) { JSON::JWK.new public_key }
192
+ it_behaves_like :success_signature_verification
193
+ end
140
194
  end
141
195
  end
142
196
 
143
197
  [:ES256, :ES384, :ES512].each do |algorithm|
144
198
  describe algorithm do
145
- let(:private_key_or_secret) { private_key :ecdsa, digest_length: algorithm.to_s[2,3].to_i }
146
- let(:public_key_or_secret) { public_key :ecdsa, digest_length: algorithm.to_s[2,3].to_i }
147
199
  let(:alg) { algorithm }
148
- it_behaves_like :success_signature_verification
200
+ let(:private_key_or_secret) { private_key :ecdsa, digest_length: algorithm.to_s[2,3].to_i }
201
+
202
+ context 'when OpenSSL::PKey::EC key given' do
203
+ let(:public_key_or_secret) { public_key :ecdsa, digest_length: algorithm.to_s[2,3].to_i }
204
+ it_behaves_like :success_signature_verification
205
+ end
206
+
207
+ context 'when JSON::JWK key given' do
208
+ let(:public_key_or_secret) { JSON::JWK.new public_key(:ecdsa, digest_length: algorithm.to_s[2,3].to_i) }
209
+ it_behaves_like :success_signature_verification
210
+ end
149
211
  end
150
212
  end
151
213
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json-jwt
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - nov matake