class BucketClient::AWS4RequestSigner

Public Class Methods

new(id, secret) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 10
def initialize(id, secret)
        @id = id
        @secret = secret
        @algorithm = "AWS4-HMAC-SHA256"
end

Public Instance Methods

sign(request, service, region) click to toggle source

Signs the http request using the AWS4 signing protocol

@param [KirinHttp::Message] request http request message to sign @param [String] service service type @param [String] region region of service @return [KirinHttp::Message]

# File lib/bucket_client/aws4_request_signer.rb, line 22
def sign(request, service, region)

        request.header["x-amz-date"] = amz_date
        request.header["Content-MD5"] = request_md5(request)
        request.header["x-amz-content-sha256"] = sha256 request.content

        cred = credential region, service
        canonical_req = canonical_request request
        signed_payload = string_to_sign(cred, canonical_req)
        signature = get_signature @secret, date_stamp, region, service, signed_payload
        request.header["Authorization"] = auth cred, signed_headers(request), signature
        request
end

Protected Instance Methods

amz_date() click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 109
def amz_date
        Time.now.utc.strftime('%Y%m%dT%H%M%SZ')
end
canonical_query_params(request) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 126
def canonical_query_params(request)
        q = Addressable::URI.parse(request.uri).query || ""
        param_map = Hash[q.split("&").map {|x| x.split("=")}].sort_by(&:to_s)
        param_map.select {|k| !k.nil?}.map {|k, v| "#{k}=#{v}"}.to_a.join "&"
end
date_stamp() click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 113
def date_stamp
        Time.now.utc.strftime('%Y%m%d')
end
header_format(request) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 86
def header_format(request)
        sorted = request.header.dup.transform_keys {|k| k.to_s.downcase}.sort_by {|k| k}
        sorted.map {|k, v| "#{k}:#{v.strip}"}.join("\n") + "\n"
end
hmac(key, data) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 117
def hmac(key, data)
        OpenSSL::HMAC.digest('sha256', key, data)
end
hmac_hex(key, data) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 121
def hmac_hex(key, data)
        OpenSSL::HMAC.hexdigest('sha256', key, data)
end
message_path(request) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 95
def message_path(request)
        Addressable::URI.parse(request.uri).path
end
request_md5(request) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 103
def request_md5(request)
        np = Digest::MD5.new
        np << (request.content || "")
        Base64.encode64(np.digest)
end
sha256(payload) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 99
def sha256(payload)
        Digest::SHA256.new.update(payload || '').hexdigest
end
signed_headers(request) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 91
def signed_headers(request)
        request.header.dup.to_h.transform_keys(&:to_s).keys.map(&:downcase).sort.join(";")
end

Private Instance Methods

auth(cred, signed_headers, signature) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 38
def auth(cred, signed_headers, signature)
        [
                "#{@algorithm} Credential=#{@id}/#{cred}",
                "SignedHeaders=#{signed_headers}",
                "Signature=#{signature}"
        ].join ","
end
canonical_request(request) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 72
def canonical_request(request)
        [
                request.method.to_s.upcase,
                message_path(request),
                canonical_query_params(request),
                header_format(request),
                signed_headers(request),
                sha256(request.content || '')
        ].join "\n"
end
credential(region, service) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 63
def credential(region, service)
        [
                date_stamp,
                region,
                service,
                "aws4_request"
        ].join "/"
end
get_signature(key, date, region, service, signed_payload) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 46
def get_signature(key, date, region, service, signed_payload)
        k_date = hmac("AWS4" + key, date)
        k_region = hmac(k_date, region)
        k_service = hmac(k_region, service)
        token = hmac(k_service, "aws4_request")
        hmac_hex token, signed_payload
end
string_to_sign(cred, can_req) click to toggle source
# File lib/bucket_client/aws4_request_signer.rb, line 54
def string_to_sign(cred, can_req)
        [
                @algorithm,
                amz_date,
                cred,
                sha256(can_req)
        ].join "\n"
end