json-jwt 0.0.2 → 0.0.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.

data/Gemfile.lock CHANGED
@@ -1,21 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- json-jwt (0.0.1)
5
- activesupport (>= 2.3)
6
- i18n
4
+ json-jwt (0.0.2)
7
5
  json (>= 1.4.3)
8
6
  url_safe_base64
9
7
 
10
8
  GEM
11
9
  remote: http://rubygems.org/
12
10
  specs:
13
- activesupport (3.1.0)
14
- multi_json (~> 1.0)
15
11
  diff-lcs (1.1.3)
16
- i18n (0.6.0)
17
- json (1.6.0)
18
- multi_json (1.0.3)
12
+ json (1.6.1)
19
13
  rake (0.9.2)
20
14
  rcov (0.9.10)
21
15
  rspec (2.6.0)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
data/json-jwt.gemspec CHANGED
@@ -12,8 +12,6 @@ Gem::Specification.new do |s|
12
12
  s.require_paths = ["lib"]
13
13
  s.add_runtime_dependency "json", ">= 1.4.3"
14
14
  s.add_runtime_dependency "url_safe_base64"
15
- s.add_runtime_dependency "activesupport", ">= 2.3"
16
- s.add_runtime_dependency "i18n"
17
15
  s.add_development_dependency "rake", ">= 0.8"
18
16
  s.add_development_dependency "rcov", ">= 0.9"
19
17
  s.add_development_dependency "rspec", ">= 2"
data/lib/json/jws.rb CHANGED
@@ -14,14 +14,30 @@ module JSON
14
14
  end
15
15
 
16
16
  def verify(signature_base_string, signature, public_key_or_secret)
17
- sign(signature_base_string, public_key_or_secret) == signature or
17
+ valid?(signature_base_string, signature, public_key_or_secret) or
18
18
  raise VerificationFailed
19
19
  end
20
20
 
21
21
  private
22
22
 
23
23
  def algorithm
24
- @header[:alg]
24
+ header[:alg] || header['alg']
25
+ end
26
+
27
+ def digest
28
+ OpenSSL::Digest::Digest.new "SHA#{algorithm.to_s[2, 3]}"
29
+ end
30
+
31
+ def hmac?
32
+ [:HS256, :HS384, :HS512].collect(&:to_s).include? algorithm.to_s
33
+ end
34
+
35
+ def rsa?
36
+ [:RS256, :RS384, :RS512].collect(&:to_s).include? algorithm.to_s
37
+ end
38
+
39
+ def ecdsa?
40
+ [:ES256, :ES384, :ES512].collect(&:to_s).include? algorithm.to_s
25
41
  end
26
42
 
27
43
  def signature_base_string
@@ -34,15 +50,30 @@ module JSON
34
50
  end
35
51
 
36
52
  def sign(signature_base_string, private_key_or_secret)
37
- digest = OpenSSL::Digest::Digest.new "SHA#{algorithm.to_s[2, 3]}"
38
- case algorithm
39
- when :HS256, :HS384, :HS512
53
+ case
54
+ when hmac?
40
55
  secret = private_key_or_secret
41
56
  OpenSSL::HMAC.digest digest, secret, signature_base_string
42
- when :RS256, :RS384, :RS512
57
+ when rsa?
43
58
  private_key = private_key_or_secret
44
59
  private_key.sign digest, signature_base_string
45
- when :ES256, :ES384, :ES512
60
+ when ecdsa?
61
+ # TODO
62
+ raise NotImplementedError.new
63
+ else
64
+ raise InvalidFormat.new('Unknown Signature Algorithm')
65
+ end
66
+ end
67
+
68
+ def valid?(signature_base_string, signature, public_key_or_secret)
69
+ case
70
+ when hmac?
71
+ secret = public_key_or_secret
72
+ sign(signature_base_string, secret) == signature
73
+ when rsa?
74
+ public_key = public_key_or_secret
75
+ public_key.verify digest, signature, signature_base_string
76
+ when ecdsa?
46
77
  # TODO
47
78
  raise NotImplementedError.new
48
79
  else
data/lib/json/jwt.rb CHANGED
@@ -26,12 +26,12 @@ module JSON
26
26
  JWS.new(self).sign!(private_key_or_secret)
27
27
  end
28
28
 
29
- def verify(signature_base_string, signature = '', prublic_key_or_secret = nil)
29
+ def verify(signature_base_string, signature = '', public_key_or_secret = nil)
30
30
  case header[:alg]
31
31
  when :none
32
32
  signature == '' or raise VerificationFailed
33
33
  else
34
- JWS.new(self).verify(signature_base_string, signature, prublic_key_or_secret)
34
+ JWS.new(self).verify(signature_base_string, signature, public_key_or_secret)
35
35
  end
36
36
  end
37
37
 
@@ -51,9 +51,10 @@ module JSON
51
51
  header, claims, signature = jwt_string.split('.').collect do |segment|
52
52
  UrlSafeBase64.decode64 segment.to_s
53
53
  end
54
- jwt = new JSON.parse(claims).with_indifferent_access
55
- jwt.header = JSON.parse(header).with_indifferent_access
56
- jwt.verify [header, claims].join('.'), signature, public_key_or_secret
54
+ signature_base_string = jwt_string.split('.')[0,2].join('.')
55
+ jwt = new JSON.parse(claims)
56
+ jwt.header = JSON.parse header
57
+ jwt.verify signature_base_string, signature, public_key_or_secret
57
58
  jwt
58
59
  rescue JSON::ParserError
59
60
  raise InvalidFormat.new("Invalid JSON Format")
@@ -8,6 +8,8 @@ describe JSON::JWS do
8
8
  _jwt_
9
9
  end
10
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 }
11
13
  let(:claims) do
12
14
  {
13
15
  :iss => 'joe',
@@ -15,6 +17,19 @@ describe JSON::JWS do
15
17
  'http://example.com/is_root' => true
16
18
  }
17
19
  end
20
+ let(:expected_signature) {
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
+ :ES256 => :TODO,
29
+ :ES384 => :TODO,
30
+ :ES512 => :TODO
31
+ }
32
+ }
18
33
 
19
34
  shared_examples_for :jwt_with_alg do
20
35
  it { should == jwt }
@@ -28,44 +43,79 @@ describe JSON::JWS do
28
43
  end
29
44
 
30
45
  describe '#sign!' do
31
- shared_examples_for :jwt_with_expected_signature do
32
- it 'should generate expected signature' do
46
+ shared_examples_for :generate_expected_signature do
47
+ it do
33
48
  UrlSafeBase64.encode64(signed.signature).should == expected_signature[alg]
34
49
  end
35
50
  end
36
- let(:expected_signature) {
37
- {
38
- :HS256 => 'DyuTgO2Ggb5nrhkkhI-RjVYIBe3o8oL4ijkAn94YPxQ',
39
- :HS384 => 'a5-7rr61TG8Snv9xxJ7l064ky-SCq1Mswe9t8HEorvoc_nnfIeUy9WQCLMIli34R',
40
- :HS512 => 'ce-GlHDaNwaHfmAFRGp3QPPKvrpruTug2hC1bf6yNlbuvkMwJw2jFZgq_4wmIPetRdiBy7XFq7rrtmw1Im7tmQ',
41
- :RS256 => 'E5VELqAdla2Bx1axc9KFxO0EiCr0Mw6HPYX070qGQ8zA_XmyxGPUZLyyWU_6Cn399W-oYBWO2ynLlr8pqqjP3jXevyCeYeGRVN0HzLYiBebEugNnc3hevr7WV2UzfksWRA-Ux2bDv2sz9p_LGbL33wWNxGDvIlpDyZUul_a48nCipS0riBjkTLTSE8dfBxQTXEF5GEUUu99ot6aBLzUhc25nHXSXogXF6MHK-hAcE7f4v-vJ0lbPbHLVGUopIoxoqe4XjoBpzE5UvhrVl5LYbdjbyJhu5ZIA8GLsgwtUFh3dfdIechORoR3k5NSFSv8157bAEa8t4iwgWD2MSNSQnw',
42
- :RS384 => 'lT5JbytGKgG9QrwkJuxgw7UjmN9tjkEQW9pVGR2XnKEdC0_wLNIzAmT-jTwyMDGBLUkWO7opDOP6Xy6_DOTg58k9PwVkyQzrLnmxJMEng2Q-aMqcitRSIvUk3DPy8kemp8yUPls9NzWmByM2GoUVHbDsR0r-tZN-g_9QYev32mvMhjMr30JI5S2xiRjc9m2GAaXMOQmNTovJgV4bgCp4UjruCrA0BD1JJwDqKYoR_YYr_ALcVjD_LUgy80udJvbi8MAYJVUf0QYtQDrX2wnT_-eiiWjD5XafLuXEQVDRh-v2MKAwdvtXMq5cZ08Zjl2SyHxJ3OqhEeWPvYGltxZh_A',
43
- :RS512 => 'EHeGM2Mo3ghhUfSB99AlREehrbC6OPE-nYL_rwf88ysTnJ8L1QQ0UuCrXq4SpRutGLK_bYTK3ZALvFRPoOgK_g0QWmqv6qjQRU_QTxoq8y8APP-IgKKDuIiGH6daBV2rAPLDReqYNKsKjmTvZJo2c0a0e_WZkkj_ZwpgjTG3v0gW9lbDAzLJDz18eqtR4ZO7JTu_fyNrUrNk-w2_wpxSsn9sygIMp0lKE0_pt0b01fz3gjTDjlltU0cKSalUp4geaBDH7QRcexrolIctdQFbNKTXQxoigxD3NLNkKGH7f6A8KZdcOm8AnEjullcZs8_OWGnW43p1qrxoBRSivb9pqQ',
44
- :ES256 => :TODO,
45
- :ES384 => :TODO,
46
- :ES512 => :TODO
47
- }
48
- }
49
- let(:signed) do
50
- jws.sign! key
51
- end
52
51
  subject { signed }
53
52
 
54
53
  [:HS256, :HS384, :HS512].each do |algorithm|
55
54
  describe algorithm do
56
- let(:key) { shared_secret }
55
+ let(:private_key_or_secret) { shared_secret }
57
56
  let(:alg) { algorithm }
58
57
  it_behaves_like :jwt_with_alg
59
- it_behaves_like :jwt_with_expected_signature
58
+ it_behaves_like :generate_expected_signature
60
59
  end
61
60
  end
62
61
 
63
62
  [:RS256, :RS384, :RS512].each do |algorithm|
64
63
  describe algorithm do
65
- let(:key) { private_key }
64
+ let(:private_key_or_secret) { private_key }
66
65
  let(:alg) { algorithm }
67
66
  it_behaves_like :jwt_with_alg
68
- it_behaves_like :jwt_with_expected_signature
67
+ it_behaves_like :generate_expected_signature
68
+ end
69
+ end
70
+
71
+ [:ES256, :ES384, :ES512].each do |algorithm|
72
+ describe algorithm do
73
+ let(:alg) { algorithm }
74
+ it :TODO
75
+ end
76
+ end
77
+ end
78
+
79
+ describe '#verify' do
80
+ shared_examples_for :succes_signature_verification do
81
+ it do
82
+ expect { decoded }.should_not raise_error
83
+ decoded.should be_a JSON::JWT
84
+ end
85
+
86
+ describe 'header' do
87
+ let(:header) { decoded.header }
88
+ it 'should be parsed successfully' do
89
+ header['typ'].should == 'JWT'
90
+ header['alg'].should == alg.to_s
91
+ end
92
+ end
93
+
94
+ describe 'claims' do
95
+ it 'should be parsed successfully' do
96
+ decoded['iss'].should == 'joe'
97
+ decoded['exp'].should == 1300819380
98
+ decoded['http://example.com/is_root'] == true
99
+ end
100
+ end
101
+ end
102
+ subject { decoded }
103
+
104
+ [:HS256, :HS384, :HS512].each do |algorithm|
105
+ describe algorithm do
106
+ let(:private_key_or_secret) { shared_secret }
107
+ let(:public_key_or_secret) { shared_secret }
108
+ let(:alg) { algorithm }
109
+ it_behaves_like :succes_signature_verification
110
+ end
111
+ end
112
+
113
+ [:RS256, :RS384, :RS512].each do |algorithm|
114
+ describe algorithm do
115
+ let(:private_key_or_secret) { private_key }
116
+ let(:public_key_or_secret) { public_key }
117
+ let(:alg) { algorithm }
118
+ it_behaves_like :succes_signature_verification
69
119
  end
70
120
  end
71
121
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: json-jwt
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.2
5
+ version: 0.0.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - nov matake
@@ -34,61 +34,39 @@ dependencies:
34
34
  version: "0"
35
35
  type: :runtime
36
36
  version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
38
- name: activesupport
39
- prerelease: false
40
- requirement: &id003 !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- version: "2.3"
46
- type: :runtime
47
- version_requirements: *id003
48
- - !ruby/object:Gem::Dependency
49
- name: i18n
50
- prerelease: false
51
- requirement: &id004 !ruby/object:Gem::Requirement
52
- none: false
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: "0"
57
- type: :runtime
58
- version_requirements: *id004
59
37
  - !ruby/object:Gem::Dependency
60
38
  name: rake
61
39
  prerelease: false
62
- requirement: &id005 !ruby/object:Gem::Requirement
40
+ requirement: &id003 !ruby/object:Gem::Requirement
63
41
  none: false
64
42
  requirements:
65
43
  - - ">="
66
44
  - !ruby/object:Gem::Version
67
45
  version: "0.8"
68
46
  type: :development
69
- version_requirements: *id005
47
+ version_requirements: *id003
70
48
  - !ruby/object:Gem::Dependency
71
49
  name: rcov
72
50
  prerelease: false
73
- requirement: &id006 !ruby/object:Gem::Requirement
51
+ requirement: &id004 !ruby/object:Gem::Requirement
74
52
  none: false
75
53
  requirements:
76
54
  - - ">="
77
55
  - !ruby/object:Gem::Version
78
56
  version: "0.9"
79
57
  type: :development
80
- version_requirements: *id006
58
+ version_requirements: *id004
81
59
  - !ruby/object:Gem::Dependency
82
60
  name: rspec
83
61
  prerelease: false
84
- requirement: &id007 !ruby/object:Gem::Requirement
62
+ requirement: &id005 !ruby/object:Gem::Requirement
85
63
  none: false
86
64
  requirements:
87
65
  - - ">="
88
66
  - !ruby/object:Gem::Version
89
67
  version: "2"
90
68
  type: :development
91
- version_requirements: *id007
69
+ version_requirements: *id005
92
70
  description: JSON Web Token and its family (JSON Web Signature, JSON Web Encryption and JSON Web Key) in Ruby
93
71
  email:
94
72
  - nov@matake.jp