Class: Fog::AWS::SignatureV4

Inherits:
Object
  • Object
show all
Defined in:
lib/fog/aws/signaturev4.rb

Constant Summary collapse

ALGORITHM =
'AWS4-HMAC-SHA256'

Instance Method Summary collapse

Constructor Details

#initialize(aws_access_key_id, secret_key, region, service) ⇒ SignatureV4

Returns a new instance of SignatureV4.



8
9
10
11
12
13
# File 'lib/fog/aws/signaturev4.rb', line 8

def initialize(aws_access_key_id, secret_key, region, service)
  @region = region
  @service = service
  @aws_access_key_id  = aws_access_key_id
  @hmac = Fog::HMAC.new('sha256', 'AWS4' + secret_key)
end

Instance Method Details

#components_to_header(components) ⇒ Object



32
33
34
# File 'lib/fog/aws/signaturev4.rb', line 32

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

#credential_scope(date) ⇒ Object



75
76
77
# File 'lib/fog/aws/signaturev4.rb', line 75

def credential_scope(date)
  "#{date.utc.strftime('%Y%m%d')}/#{@region}/#{@service}/aws4_request"
end

#derived_hmac(date) ⇒ Object



66
67
68
69
70
71
72
# File 'lib/fog/aws/signaturev4.rb', line 66

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

#sign(params, date) ⇒ Object

legacy method name



28
29
30
# File 'lib/fog/aws/signaturev4.rb', line 28

def sign(params, date) #legacy method name
  signature_header(params, date)
end

#signature_components(params, date, body_sha) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/fog/aws/signaturev4.rb', line 36

def signature_components(params, date, body_sha)
  canonical_request = <<-DATA
#{params[:method].to_s.upcase}
#{canonical_path(params[:path])}
#{canonical_query_string(params[:query])}
#{canonical_headers(params[:headers])}
#{signed_headers(params[:headers])}
#{body_sha || OpenSSL::Digest::SHA256.hexdigest(params[:body] || '')}
DATA
  canonical_request.chop!

  string_to_sign = <<-DATA
#{ALGORITHM}
#{date.to_iso8601_basic}
#{credential_scope(date)}
#{OpenSSL::Digest::SHA256.hexdigest(canonical_request)}
DATA

  string_to_sign.chop!

  signature = derived_hmac(date).sign(string_to_sign)

  {
    '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

#signature_header(params, date, body_sha = nil) ⇒ Object



24
25
26
# File 'lib/fog/aws/signaturev4.rb', line 24

def signature_header(params, date, body_sha = nil)
  components_to_header(signature_components(params, date, body_sha))
end

#signature_parameters(params, date, body_sha = nil) ⇒ Object



15
16
17
18
19
20
21
22
# File 'lib/fog/aws/signaturev4.rb', line 15

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