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 +4 -4
- data/.travis.yml +2 -2
- data/CHANGELOG.md +68 -0
- data/lib/ey-hmac/adapter.rb +40 -19
- data/lib/ey-hmac/adapter/faraday.rb +38 -16
- data/lib/ey-hmac/adapter/rack.rb +15 -9
- data/lib/ey-hmac/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0238feeb2cc5fd246c384cc561dfe669927b90a2'
|
4
|
+
data.tar.gz: dac7a783530d2cc92a0364a91b32ac14d3023152
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7353c7b1566e27ab95079204359fd5b1c72a455b8db7291f52674015fe7969741b0c9b8fbb4d0959b3c22c4559341289ed2ec4320f48a04d3b6a44a0b8a697e2
|
7
|
+
data.tar.gz: d101baf710250442ea05b29699e7d6f0922784b6fe83342a34f23b0df4defbc35e3ae4ae5c1a98378fbb343ab3b5926840881dbb431e887d0e13e03360923cbb
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -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)*
|
data/lib/ey-hmac/adapter.rb
CHANGED
@@ -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.
|
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
|
-
|
116
|
-
|
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
|
123
|
-
raise
|
120
|
+
unless key_secret
|
121
|
+
raise Ey::Hmac::MissingSecret,
|
122
|
+
"Failed to find secret matching #{key_id.inspect}"
|
124
123
|
end
|
125
124
|
|
126
|
-
|
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 =
|
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
|
137
|
-
raise
|
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
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
33
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/ey-hmac/adapter/rack.rb
CHANGED
@@ -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 =
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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']
|
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
|
data/lib/ey-hmac/version.rb
CHANGED
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.
|
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:
|
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.
|
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
|