mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
[AWS|Signature] V4 parameter signature needs to add X-Amz-Credential etc. before signing
This commit is contained in:
parent
a878fb03c8
commit
1bf86ce4dc
2 changed files with 47 additions and 22 deletions
|
@ -4,6 +4,7 @@ require 'fog/aws/core'
|
|||
module Fog
|
||||
module AWS
|
||||
class SignatureV4
|
||||
ALGORITHM = 'AWS4-HMAC-SHA256'
|
||||
def initialize(aws_access_key_id, secret_key, region,service)
|
||||
@region = region
|
||||
@service = service
|
||||
|
@ -11,35 +12,42 @@ module Fog
|
|||
@hmac = Fog::HMAC.new('sha256', 'AWS4' + secret_key)
|
||||
end
|
||||
|
||||
def signature_parameters(params, date)
|
||||
signature_components(params, date)
|
||||
def signature_parameters(params, date, body_sha = nil)
|
||||
params = params.dup.merge(:query => params[:query].merge(
|
||||
'X-Amz-Algorithm' => ALGORITHM,
|
||||
'X-Amz-Credential' => "#{@aws_access_key_id}/#{credential_scope(date)}",
|
||||
'X-Amz-SignedHeaders' => signed_headers(params[:headers])
|
||||
))
|
||||
signature_components(params, date, body_sha)
|
||||
end
|
||||
|
||||
def signature_header(params, date)
|
||||
components = signature_components(params, date)
|
||||
"#{components['X-Amz-Algorithm']} Credential=#{components['X-Amz-Credential']}, SignedHeaders=#{components['X-Amz-SignedHeaders']}, Signature=#{components['X-Amz-Signature']}"
|
||||
def signature_header(params, date, body_sha = nil)
|
||||
components_to_header(signature_components(params, date, body_sha))
|
||||
end
|
||||
|
||||
def sign(params, date) #legacy method name
|
||||
signature_header(params, date)
|
||||
end
|
||||
|
||||
protected
|
||||
def signature_components(params, date)
|
||||
def components_to_header components
|
||||
"#{components['X-Amz-Algorithm']} Credential=#{components['X-Amz-Credential']}, SignedHeaders=#{components['X-Amz-SignedHeaders']}, Signature=#{components['X-Amz-Signature']}"
|
||||
end
|
||||
|
||||
def signature_components(params, date, body_sha)
|
||||
canonical_request = <<-DATA
|
||||
#{params[:method].to_s.upcase}
|
||||
#{params[:path]}
|
||||
#{canonical_query_string(params[:query])}
|
||||
#{canonical_headers(params[:headers])}
|
||||
#{signed_headers(params[:headers])}
|
||||
#{Digest::SHA256.hexdigest(params[:body] || '')}
|
||||
#{body_sha || Digest::SHA256.hexdigest(params[:body] || '')}
|
||||
DATA
|
||||
canonical_request.chop!
|
||||
credential_scope = "#{date.utc.strftime('%Y%m%d')}/#{@region}/#{@service}/aws4_request"
|
||||
|
||||
string_to_sign = <<-DATA
|
||||
AWS4-HMAC-SHA256
|
||||
#{ALGORITHM}
|
||||
#{date.to_iso8601_basic}
|
||||
#{credential_scope}
|
||||
#{credential_scope(date)}
|
||||
#{Digest::SHA256.hexdigest(canonical_request)}
|
||||
DATA
|
||||
|
||||
|
@ -48,13 +56,26 @@ DATA
|
|||
signature = derived_hmac(date).sign(string_to_sign)
|
||||
|
||||
{
|
||||
'X-Amz-Algorithm' => 'AWS4-HMAC-SHA256',
|
||||
'X-Amz-Credential' => "#{@aws_access_key_id}/#{credential_scope}",
|
||||
'X-Amz-Algorithm' => ALGORITHM,
|
||||
'X-Amz-Credential' => "#{@aws_access_key_id}/#{credential_scope(date)}",
|
||||
'X-Amz-SignedHeaders' => signed_headers(params[:headers]),
|
||||
'X-Amz-Signature' => signature.unpack('H*').first
|
||||
}
|
||||
end
|
||||
|
||||
def derived_hmac(date)
|
||||
kDate = @hmac.sign(date.utc.strftime('%Y%m%d'))
|
||||
kRegion = Fog::HMAC.new('sha256', kDate).sign(@region)
|
||||
kService = Fog::HMAC.new('sha256', kRegion).sign(@service)
|
||||
kSigning = Fog::HMAC.new('sha256', kService).sign('aws4_request')
|
||||
Fog::HMAC.new('sha256', kSigning)
|
||||
end
|
||||
|
||||
|
||||
def credential_scope(date)
|
||||
"#{date.utc.strftime('%Y%m%d')}/#{@region}/#{@service}/aws4_request"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def canonical_query_string(query)
|
||||
|
@ -79,13 +100,6 @@ DATA
|
|||
headers.keys.map {|key| key.to_s}.sort.map {|key| key.downcase}.join(';')
|
||||
end
|
||||
|
||||
def derived_hmac(date)
|
||||
kDate = @hmac.sign(date.utc.strftime('%Y%m%d'))
|
||||
kRegion = Fog::HMAC.new('sha256', kDate).sign(@region)
|
||||
kService = Fog::HMAC.new('sha256', kRegion).sign(@service)
|
||||
kSigning = Fog::HMAC.new('sha256', kService).sign('aws4_request')
|
||||
Fog::HMAC.new('sha256', kSigning)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -44,7 +44,18 @@ Shindo.tests('AWS | signaturev4', ['aws']) do
|
|||
'X-Amz-Algorithm' => 'AWS4-HMAC-SHA256',
|
||||
'X-Amz-Credential' => 'AKIDEXAMPLE/20110909/us-east-1/host/aws4_request',
|
||||
'X-Amz-SignedHeaders' => 'date;host',
|
||||
'X-Amz-Signature' => '0dc122f3b28b831ab48ba65cb47300de53fbe91b577fe113edac383730254a3b'
|
||||
'X-Amz-Signature' => 'a6c6304682c74bcaebeeab2fdfb8041bbb39c6976300791a283057bccf333fb2'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
tests("inject body sha") do
|
||||
returns(@signer.signature_parameters({:query => {'a' => 'foo', 'b' => 'foo'}, :headers => {'Host' => 'host.foo.com', 'Date' => 'Mon, 09 Sep 2011 23:36:00 GMT'}, :method => :get, :path => '/'}, @now, 'STREAMING-AWS4-HMAC-SHA256-PAYLOAD')) do
|
||||
{
|
||||
'X-Amz-Algorithm' => 'AWS4-HMAC-SHA256',
|
||||
'X-Amz-Credential' => 'AKIDEXAMPLE/20110909/us-east-1/host/aws4_request',
|
||||
'X-Amz-SignedHeaders' => 'date;host',
|
||||
'X-Amz-Signature' => '22c32bb0d0b859b94839de4e9360bca1806e73d853f5f97ae0d849f0bdf42fb0'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue