class Blobsterix::S3Auth::V4
Constants
- V4_REGEX
Attributes
access_key[R]
credential[R]
env[R]
scope_date[R]
scope_region[R]
scope_service[R]
signature[R]
signed_headers[R]
Public Class Methods
create(env)
click to toggle source
# File lib/blobsterix/s3/s3_auth_v4.rb, line 9 def self.create(env) matcher = V4_REGEX.match(env["HTTP_AUTHORIZATION"]) matcher ? V4.new(env, matcher[1], matcher[2], matcher[3]) : nil end
new(env, credential, signed_headers, signature)
click to toggle source
# File lib/blobsterix/s3/s3_auth_v4.rb, line 16 def initialize(env, credential, signed_headers, signature) @env = env @credential = credential @signed_headers = signed_headers @signature = signature @access_key, @scope_date, @scope_region, @scope_service = @credential.split("/") end
Public Instance Methods
canonical_headers()
click to toggle source
# File lib/blobsterix/s3/s3_auth_v4.rb, line 68 def canonical_headers canonicalized = @env.select { |key,value| key.is_a?(String) }.inject({}) do |memo, (key,value)| memo[key.gsub("HTTP_","").downcase.gsub("_","-")] = value.to_s.strip memo end headers = "" @signed_headers.split(";").each do |key| raise StandardError.new("Missing signed header") unless canonicalized.key?(key) headers << key + ":" + canonicalized[key] + "\n" end headers end
canonical_query()
click to toggle source
# File lib/blobsterix/s3/s3_auth_v4.rb, line 61 def canonical_query @env["QUERY_STRING"].to_s.split("&").sort.map do |param| escaped = param.split("=").map { |k_or_v| escape(k_or_v) }.join("=") escaped["="] ? escaped : "#{escaped}=" end.join("&") end
canonical_request()
click to toggle source
# File lib/blobsterix/s3/s3_auth_v4.rb, line 50 def canonical_request [ @env["REQUEST_METHOD"].to_s.upcase, @env["REQUEST_PATH"], canonical_query, canonical_headers, @signed_headers, @env["HTTP_X_AMZ_CONTENT_SHA256"] || Digest::SHA256.hexdigest("") ].join("\n") end
check(secret_key_store)
click to toggle source
# File lib/blobsterix/s3/s3_auth_v4.rb, line 25 def check(secret_key_store) return false if is_expired? secret_key = secret_key_store.get_key(@access_key) gen_signature(secret_key) == @signature end
escape(string)
click to toggle source
# File lib/blobsterix/s3/s3_auth_v4.rb, line 100 def escape(string) string.gsub(/([^a-zA-Z0-9_.\-~]+)/) { "%" + $1.unpack("H2" * $1.bytesize).join("%").upcase } end
gen_signature(secret_key)
click to toggle source
# File lib/blobsterix/s3/s3_auth_v4.rb, line 32 def gen_signature(secret_key) signing_key = hmac256("AWS4"+secret_key, @scope_date) signing_key = hmac256(signing_key, @scope_region) signing_key = hmac256(signing_key, @scope_service) signing_key = hmac256(signing_key, "aws4_request") hmac256(signing_key, string_to_sign).unpack('H*').first end
header_datetime()
click to toggle source
# File lib/blobsterix/s3/s3_auth_v4.rb, line 88 def header_datetime Time.parse(@env["HTTP_X_AMZ_DATE"] || @env["HTTP_DATE"] || Time.now.to_s) end
header_datetime_iso8601()
click to toggle source
# File lib/blobsterix/s3/s3_auth_v4.rb, line 92 def header_datetime_iso8601 header_datetime.utc.strftime('%Y%m%dT%H%M%SZ') end
hmac256(key, data)
click to toggle source
# File lib/blobsterix/s3/s3_auth_v4.rb, line 84 def hmac256(key, data) OpenSSL::HMAC.digest(OpenSSL::Digest.new("sha256"), key, data) end
is_expired?()
click to toggle source
# File lib/blobsterix/s3/s3_auth_v4.rb, line 96 def is_expired? ::Blobsterix::S3Auth.current_time > header_datetime+15*60 end
string_to_sign()
click to toggle source
# File lib/blobsterix/s3/s3_auth_v4.rb, line 41 def string_to_sign [ "AWS4-HMAC-SHA256", header_datetime_iso8601, [@scope_date, @scope_region, @scope_service, "aws4_request"].join("/"), Digest::SHA256.hexdigest(canonical_request) ].join("\n") end