Skip to content

Commit

Permalink
support signatures for requests with no body coming from older versio…
Browse files Browse the repository at this point in the history
…ns of ey_api_hmac
  • Loading branch information
Jacob Burkhart committed Dec 19, 2011
1 parent 45465e2 commit 8f2a3f1
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
18 changes: 13 additions & 5 deletions lib/ey_api_hmac.rb
Expand Up @@ -10,7 +10,7 @@ def self.sign!(env, key_id, secret)
env["HTTP_AUTHORIZATION"] = auth_string(key_id, signature(env, secret))
end

def self.canonical_string(env)
def self.canonical_string(env, legacy = false)
parts = []
expect = Proc.new do |var|
unless env[var]
Expand All @@ -20,7 +20,7 @@ def self.canonical_string(env)
end
parts << expect["REQUEST_METHOD"]
parts << env["CONTENT_TYPE"]
parts << generated_md5(env)
parts << generated_md5(env, legacy)
parts << expect["HTTP_DATE"]
if env["REQUEST_URI"]
parts << URI.parse(env["REQUEST_URI"]).path
Expand All @@ -38,6 +38,10 @@ def self.signature(env, secret)
base64digest(canonical_string(env), secret)
end

def self.signature_legacy(env, secret)
base64digest(canonical_string(env, true), secret)
end

def self.base64digest(data,secret)
digest = OpenSSL::Digest::Digest.new('sha1')
[OpenSSL::HMAC.digest(digest, secret, data)].pack('m').strip
Expand All @@ -54,7 +58,7 @@ def self.authenticate!(env, &lookup)
unless secret
raise HmacAuthFail, "couldn't find auth for #{access_key_id}"
end
unless hmac == signature(env, secret)
unless hmac == signature(env, secret) || hmac == signature_legacy(env, secret)
raise HmacAuthFail, "signature mismatch. Calculated canonical_string: #{canonical_string(env).inspect}"
end
else
Expand All @@ -73,11 +77,15 @@ def self.authenticated?(env, &lookup)

private

def self.generated_md5(env)
def self.generated_md5(env, legacy = false)
env["rack.input"].rewind
request_body = env["rack.input"].read
env["rack.input"].rewind
request_body.empty? ? nil : OpenSSL::Digest::MD5.hexdigest(request_body)
if legacy
OpenSSL::Digest::MD5.hexdigest(request_body)
else
request_body.empty? ? nil : OpenSSL::Digest::MD5.hexdigest(request_body)
end
end

end
Expand Down
11 changes: 10 additions & 1 deletion spec/api_auth_spec.rb
Expand Up @@ -109,8 +109,17 @@ def compatible
end

describe "authenticated?" do
describe "request signed by AuthHMAC" do

it "verifies the old signing method without body" do
@env['rack.input'] = StringIO.new
@env.delete('HTTP_CONTENT_MD5')
@request = Rack::Request.new(@env)
@env["HTTP_AUTHORIZATION"] = "AuthHMAC access key 1:isJ7zHHPrpnSdZ/XbvqxFhVUf0c="
@lookup = Proc.new{ |key| 'secret' if key == 'access key 1' }
EY::ApiHMAC.authenticated?(@env, &@lookup).should be_true
end

describe "request signed by AuthHMAC" do
describe do
before do
AuthHMAC.sign!(@request, 'access key 1', 'secret')
Expand Down

0 comments on commit 8f2a3f1

Please sign in to comment.