class Aws::Signers::V4

def self.sign(context)

def self.sign(context)
  new(
    context.config.credentials,
    context.config.sigv4_name,
    context.config.sigv4_region
  ).sign(context.http_request)
end

def authorization(request, datetime)

def authorization(request, datetime)
  parts = []
  parts << "AWS4-HMAC-SHA256 Credential=#{credentials.access_key_id}/#{credential_scope(datetime)}"
  parts << "SignedHeaders=#{signed_headers(request)}"
  parts << "Signature=#{signature(request, datetime)}"
  parts.join(', ')
end

def canonical_header_value(value)

def canonical_header_value(value)
  value.match(/^".*"$/) ? value : value.gsub(/\s+/, ' ').strip
end

def canonical_headers(request)

def canonical_headers(request)
  headers = []
  request.headers.each_pair do |k,v|
    k = k.downcase
    headers << [k,v] unless k == 'authorization'
  end
  headers = headers.sort_by(&:first)
  headers.map{|k,v| "#{k}:#{canonical_header_value(v.to_s)}" }.join("\n")
end

def canonical_request(request)

def canonical_request(request)
  [
    request.http_method,
    request.endpoint.path,
    request.endpoint.querystring,
    canonical_headers(request) + "\n",
    signed_headers(request),
    request.headers['X-Amz-Content-Sha256']
  ].join("\n")
end

def credential_scope(datetime)

def credential_scope(datetime)
  parts = []
  parts << datetime[0,8]
  parts << region
  parts << service_name
  parts << 'aws4_request'
  parts.join("/")
end

def hexdigest(value)

def hexdigest(value)
  digest = Digest::SHA256.new
  if value.respond_to?(:read)
    chunk = nil
    chunk_size = 1024 * 1024 # 1 megabyte
    digest.update(chunk) while chunk = value.read(chunk_size)
    value.rewind
  else
    digest.update(value)
  end
  digest.hexdigest
end

def hexhmac(key, value)

def hexhmac(key, value)
  OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), key, value)
end

def hmac(key, value)

def hmac(key, value)
  OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, value)
end

def initialize(credentials, service_name, region)

Parameters:
  • region (String) -- The region (e.g. 'us-west-1') the request
  • service_name (String) -- The name used by the service in
  • credentials (Credentials) --
def initialize(credentials, service_name, region)
  @credentials = credentials
  @service_name = service_name
  @region = region
end

def sign(request)

Returns:
  • (Seahorse::Client::Http::Request) - the signed request.

Parameters:
  • request (Seahorse::Client::Http::Request) --
def sign(request)
  datetime = Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
  request.headers['X-Amz-Date'] = datetime
  request.headers['Host'] = request.endpoint.host
  request.headers['X-Amz-Security-Token'] = credentials.session_token if
    credentials.session_token
  request.headers['X-Amz-Content-Sha256'] ||= hexdigest(request.body)
  request.headers['Authorization'] = authorization(request, datetime)
  request
end

def signature(request, datetime)

def signature(request, datetime)
  k_secret = credentials.secret_access_key
  k_date = hmac("AWS4" + k_secret, datetime[0,8])
  k_region = hmac(k_date, region)
  k_service = hmac(k_region, service_name)
  k_credentials = hmac(k_service, 'aws4_request')
  hexhmac(k_credentials, string_to_sign(request, datetime))
end

def signed_headers(request)

def signed_headers(request)
  headers = request.headers.keys
  headers.delete('authorization')
  headers.sort.join(';')
end

def string_to_sign(request, datetime)

def string_to_sign(request, datetime)
  parts = []
  parts << 'AWS4-HMAC-SHA256'
  parts << datetime
  parts << credential_scope(datetime)
  parts << hexdigest(canonical_request(request))
  parts.join("\n")
end