ey-hmac 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 993156b2650af65ee323f3a1f5715c6fff44508d
4
- data.tar.gz: 464d21118f68dc3513db89c2fcbaff3ddbf677d4
3
+ metadata.gz: '0238feeb2cc5fd246c384cc561dfe669927b90a2'
4
+ data.tar.gz: dac7a783530d2cc92a0364a91b32ac14d3023152
5
5
  SHA512:
6
- metadata.gz: 16ded2fdf25966104d2dfe09ddfdf19a6a5a1ef6b1e140d9ea6aecb3b721826a288055b106266b56cb2594a31606eaeae49503fa4590b7e779212e5885956b80
7
- data.tar.gz: 0a3b84006e99a02540e5e4a90f61015d2ad336652f63055f9c1c666e28ff86b11fce45ac86bad23ea7e4da4fffb526b18c0e7cf84eb6f22db78adccdde18c807
6
+ metadata.gz: 7353c7b1566e27ab95079204359fd5b1c72a455b8db7291f52674015fe7969741b0c9b8fbb4d0959b3c22c4559341289ed2ec4320f48a04d3b6a44a0b8a697e2
7
+ data.tar.gz: d101baf710250442ea05b29699e7d6f0922784b6fe83342a34f23b0df4defbc35e3ae4ae5c1a98378fbb343ab3b5926840881dbb431e887d0e13e03360923cbb
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  language: ruby
3
3
  rvm:
4
- - 1.9.3
5
- - 2.0.0
4
+ - 2.2
5
+ - 2.3
6
6
 
7
7
  script: bundle exec rspec
@@ -0,0 +1,68 @@
1
+ # Change Log
2
+
3
+ ## [v2.2.0](https://github.com/engineyard/hmac/tree/v2.2.0) (2017-01-09)
4
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v2.1.0...v2.2.0)
5
+
6
+ **Closed issues:**
7
+
8
+ - :sha512 and :sha384 [\#4](https://github.com/engineyard/hmac/issues/4)
9
+
10
+ **Merged pull requests:**
11
+
12
+ - use Base64\#strict\_encode64 when signing requests [\#5](https://github.com/engineyard/hmac/pull/5) ([lanej](https://github.com/lanej))
13
+
14
+ ## [v2.1.0](https://github.com/engineyard/hmac/tree/v2.1.0) (2015-12-03)
15
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v2.0.2...v2.1.0)
16
+
17
+ **Merged pull requests:**
18
+
19
+ - add optional server-side HMAC TTL to prevent replay attacks [\#3](https://github.com/engineyard/hmac/pull/3) ([hudon](https://github.com/hudon))
20
+
21
+ ## [v2.0.2](https://github.com/engineyard/hmac/tree/v2.0.2) (2015-09-17)
22
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v2.0.1...v2.0.2)
23
+
24
+ ## [v2.0.1](https://github.com/engineyard/hmac/tree/v2.0.1) (2015-09-17)
25
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v2.0.0...v2.0.1)
26
+
27
+ **Merged pull requests:**
28
+
29
+ - update faraday usage in the readme [\#2](https://github.com/engineyard/hmac/pull/2) ([svarks](https://github.com/svarks))
30
+
31
+ ## [v2.0.0](https://github.com/engineyard/hmac/tree/v2.0.0) (2014-08-09)
32
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v1.0.0...v2.0.0)
33
+
34
+ ## [v1.0.0](https://github.com/engineyard/hmac/tree/v1.0.0) (2014-04-29)
35
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v0.1.3...v1.0.0)
36
+
37
+ ## [v0.1.3](https://github.com/engineyard/hmac/tree/v0.1.3) (2014-04-29)
38
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v0.1.2...v0.1.3)
39
+
40
+ ## [v0.1.2](https://github.com/engineyard/hmac/tree/v0.1.2) (2014-04-01)
41
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v0.1.1...v0.1.2)
42
+
43
+ **Merged pull requests:**
44
+
45
+ - Fix deprecated usage of Digest::Digest. [\#1](https://github.com/engineyard/hmac/pull/1) ([ericlathrop](https://github.com/ericlathrop))
46
+
47
+ ## [v0.1.1](https://github.com/engineyard/hmac/tree/v0.1.1) (2014-02-19)
48
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v0.1.0...v0.1.1)
49
+
50
+ ## [v0.1.0](https://github.com/engineyard/hmac/tree/v0.1.0) (2014-02-18)
51
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v0.0.5...v0.1.0)
52
+
53
+ ## [v0.0.5](https://github.com/engineyard/hmac/tree/v0.0.5) (2013-10-18)
54
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v0.0.4...v0.0.5)
55
+
56
+ ## [v0.0.4](https://github.com/engineyard/hmac/tree/v0.0.4) (2013-02-08)
57
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v0.0.3...v0.0.4)
58
+
59
+ ## [v0.0.3](https://github.com/engineyard/hmac/tree/v0.0.3) (2013-02-06)
60
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v0.0.2...v0.0.3)
61
+
62
+ ## [v0.0.2](https://github.com/engineyard/hmac/tree/v0.0.2) (2013-02-05)
63
+ [Full Changelog](https://github.com/engineyard/hmac/compare/v0.0.1...v0.0.2)
64
+
65
+ ## [v0.0.1](https://github.com/engineyard/hmac/tree/v0.0.1) (2013-02-05)
66
+
67
+
68
+ \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
@@ -37,7 +37,9 @@ class Ey::Hmac::Adapter
37
37
  # @param [String] signature digest hash function. Defaults to #sign_with
38
38
  # @return [String] HMAC signature of {#request}
39
39
  def signature(key_secret, digest = self.sign_with)
40
- Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new(digest.to_s), key_secret, canonicalize)).strip
40
+ Base64.strict_encode64(
41
+ OpenSSL::HMAC.digest(
42
+ OpenSSL::Digest.new(digest.to_s), key_secret, canonicalize)).strip
41
43
  end
42
44
 
43
45
  # @param [String] key_id public HMAC key
@@ -112,34 +114,30 @@ class Ey::Hmac::Adapter
112
114
 
113
115
  # @see Ey::Hmac#authenticate!
114
116
  def authenticated!(&block)
115
- unless authorization_match = AUTHORIZATION_REGEXP.match(authorization_signature)
116
- raise(Ey::Hmac::MissingAuthorization, "Failed to parse authorization_signature #{authorization_signature}")
117
- end
118
-
119
- key_id = authorization_match[1]
120
- signature_value = authorization_match[2]
117
+ key_id, signature_value = check_signature!
118
+ key_secret = block.call(key_id)
121
119
 
122
- unless key_secret = block.call(key_id)
123
- raise(Ey::Hmac::MissingSecret, "Failed to find secret matching #{key_id.inspect}")
120
+ unless key_secret
121
+ raise Ey::Hmac::MissingSecret,
122
+ "Failed to find secret matching #{key_id.inspect}"
124
123
  end
125
124
 
126
- unless @ttl.nil?
127
- expiry = Time.parse(date).to_i + @ttl
128
- current_time = Time.now.to_i
129
- unless expiry > current_time
130
- raise(Ey::Hmac::ExpiredHmac, "Signature has expired passed #{expiry}. Current time is #{current_time}")
131
- end
132
- end
125
+ check_ttl!
133
126
 
134
- calculated_signatures = self.accept_digests.map { |ad| signature(key_secret, ad) }
127
+ calculated_signatures = accept_digests.map { |ad| signature(key_secret, ad) }
128
+ matching_signature = calculated_signatures.any? { |cs| secure_compare(signature_value, cs) }
135
129
 
136
- unless calculated_signatures.any? { |cs| secure_compare(signature_value, cs) }
137
- raise(Ey::Hmac::SignatureMismatch, "Calculated signature #{signature_value} does not match #{calculated_signatures.inspect} using #{canonicalize.inspect}")
130
+ unless matching_signature
131
+ raise Ey::Hmac::SignatureMismatch,
132
+ "Calculated signature #{signature_value} does not match #{calculated_signatures.inspect} using #{canonicalize.inspect}"
138
133
  end
134
+
139
135
  true
140
136
  end
141
137
  alias authenticate! authenticated!
142
138
 
139
+ protected
140
+
143
141
  # Constant time string comparison.
144
142
  # pulled from https://github.com/rack/rack/blob/master/lib/rack/utils.rb#L399
145
143
  def secure_compare(a, b)
@@ -151,4 +149,27 @@ class Ey::Hmac::Adapter
151
149
  b.each_byte { |v| r |= v ^ l[i+=1] }
152
150
  r == 0
153
151
  end
152
+
153
+ def check_ttl!
154
+ if @ttl && date
155
+ expiry = Time.parse(date).to_i + @ttl
156
+ current_time = Time.now.to_i
157
+
158
+ unless expiry > current_time
159
+ raise Ey::Hmac::ExpiredHmac,
160
+ "Signature has expired passed #{expiry}. Current time is #{current_time}"
161
+ end
162
+ end
163
+ end
164
+
165
+ def check_signature!
166
+ authorization_match = AUTHORIZATION_REGEXP.match(authorization_signature)
167
+
168
+ unless authorization_match
169
+ raise Ey::Hmac::MissingAuthorization,
170
+ "Failed to parse authorization_signature #{authorization_signature}"
171
+ end
172
+
173
+ [authorization_match[1], authorization_match[2]]
174
+ end
154
175
  end
@@ -4,21 +4,29 @@ class Ey::Hmac::Adapter::Faraday < Ey::Hmac::Adapter
4
4
  end
5
5
 
6
6
  def content_type
7
- %w[CONTENT-TYPE CONTENT_TYPE Content-Type Content_Type].inject(nil) { |r,h| r || request[:request_headers][h] }
7
+ @content_type ||= find_header(
8
+ *%w[CONTENT-TYPE CONTENT_TYPE Content-Type Content_Type]
9
+ )
8
10
  end
9
11
 
10
12
  def content_digest
11
- if existing = %w[CONTENT-DIGEST CONTENT_DIGEST Content-Digest Content_Digest].inject(nil) { |r,h| r || request[:request_headers][h] }
12
- existing
13
- elsif body
14
- digestable = if body.respond_to?(:rewind)
15
- body.rewind
16
- body.read.tap { |_| body.rewind }
17
- else
18
- body.to_s
19
- end
20
-
21
- request[:request_headers]['Content-Digest'] = Digest::MD5.hexdigest(digestable)
13
+ @content_digest ||= find_header(
14
+ *%w[CONTENT-DIGEST CONTENT_DIGEST Content-Digest Content_Digest]
15
+ )
16
+ end
17
+
18
+ def set_content_digest
19
+ return if content_digest
20
+
21
+ digestable = if body.respond_to?(:rewind)
22
+ body.rewind
23
+ body.read.tap { |_| body.rewind }
24
+ else
25
+ body.to_s
26
+ end
27
+
28
+ if digestable && digestable != ""
29
+ @content_digest = request[:request_headers]['Content-Digest'] = Digest::MD5.hexdigest(digestable)
22
30
  end
23
31
  end
24
32
 
@@ -29,8 +37,13 @@ class Ey::Hmac::Adapter::Faraday < Ey::Hmac::Adapter
29
37
  end
30
38
 
31
39
  def date
32
- existing = %w[DATE Date].inject(nil) { |r,h| r || request[h] }
33
- existing || (request[:request_headers]['Date'] = Time.now.httpdate)
40
+ find_header(*%w[DATE Date])
41
+ end
42
+
43
+ def set_date
44
+ unless date
45
+ request[:request_headers]['Date'] = Time.now.httpdate
46
+ end
34
47
  end
35
48
 
36
49
  def path
@@ -38,7 +51,8 @@ class Ey::Hmac::Adapter::Faraday < Ey::Hmac::Adapter
38
51
  end
39
52
 
40
53
  def sign!(key_id, key_secret)
41
- %w[CONTENT-TYPE CONTENT_TYPE Content-Type Content_Type].inject(nil) { |r,h| request[:request_headers][h] }
54
+ set_content_digest
55
+ set_date
42
56
 
43
57
  if options[:version]
44
58
  request[:request_headers]['X-Signature-Version'] = options[:version]
@@ -48,6 +62,14 @@ class Ey::Hmac::Adapter::Faraday < Ey::Hmac::Adapter
48
62
  end
49
63
 
50
64
  def authorization_signature
51
- %w[Authorization AUTHORIZATION].inject(nil){|r, h| r || request[:request_headers][h]}
65
+ find_header(*%w[Authorization AUTHORIZATION])
66
+ end
67
+
68
+ private
69
+
70
+ def find_header(*keys)
71
+ value = nil
72
+ keys.find { |k| value = request[:request_headers][k] }
73
+ value
52
74
  end
53
75
  end
@@ -3,10 +3,7 @@ require 'rack'
3
3
  class Ey::Hmac::Adapter::Rack < Ey::Hmac::Adapter
4
4
  def initialize(request, options)
5
5
  super
6
- @request = if request.is_a?(Hash)
7
- ::Rack::Request.new(request)
8
- else request
9
- end
6
+ @request = request.is_a?(Hash) ? ::Rack::Request.new(request) : request
10
7
  end
11
8
 
12
9
  def method
@@ -18,10 +15,12 @@ class Ey::Hmac::Adapter::Rack < Ey::Hmac::Adapter
18
15
  end
19
16
 
20
17
  def content_digest
21
- if existing = request.env['HTTP_CONTENT_DIGEST']
22
- existing
23
- elsif digest = body && Digest::MD5.hexdigest(body)
24
- request.env['HTTP_CONTENT_DIGEST'] = digest
18
+ request.env['HTTP_CONTENT_DIGEST']
19
+ end
20
+
21
+ def set_content_digest
22
+ if body
23
+ request.env['HTTP_CONTENT_DIGEST'] = Digest::MD5.hexdigest(body)
25
24
  end
26
25
  end
27
26
 
@@ -36,7 +35,11 @@ class Ey::Hmac::Adapter::Rack < Ey::Hmac::Adapter
36
35
  end
37
36
 
38
37
  def date
39
- request.env['HTTP_DATE'] ||= Time.now.httpdate
38
+ request.env['HTTP_DATE']
39
+ end
40
+
41
+ def set_date
42
+ request.env['HTTP_DATE'] = Time.now.httpdate
40
43
  end
41
44
 
42
45
  def path
@@ -44,6 +47,9 @@ class Ey::Hmac::Adapter::Rack < Ey::Hmac::Adapter
44
47
  end
45
48
 
46
49
  def sign!(key_id, key_secret)
50
+ set_date
51
+ set_content_digest
52
+
47
53
  if options[:version]
48
54
  request.env['HTTP_X_SIGNATURE_VERSION'] = options[:version]
49
55
  end
@@ -1,5 +1,5 @@
1
1
  module Ey
2
2
  module Hmac
3
- VERSION = "2.1.0"
3
+ VERSION = "2.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ey-hmac
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Lane & Jason Hansen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-03 00:00:00.000000000 Z
11
+ date: 2017-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -47,6 +47,7 @@ extra_rdoc_files: []
47
47
  files:
48
48
  - ".gitignore"
49
49
  - ".travis.yml"
50
+ - CHANGELOG.md
50
51
  - Gemfile
51
52
  - LICENSE.txt
52
53
  - README.md
@@ -83,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
84
  version: '0'
84
85
  requirements: []
85
86
  rubyforge_project:
86
- rubygems_version: 2.4.5.1
87
+ rubygems_version: 2.5.2
87
88
  signing_key:
88
89
  specification_version: 4
89
90
  summary: Lightweight HMAC signing libraries and middleware for Farday and Rack