ey-hmac 2.1.0 → 2.2.0

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.
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