Class: EC2::Common::HeadersV4
- Inherits:
-
Object
- Object
- EC2::Common::HeadersV4
- Defined in:
- lib/ec2/common/headersv4.rb
Class Method Summary collapse
-
.hexdigest(value, chunk_size = 1024 * 1024) ⇒ Object
Returns a SHA256 hexdigest of value.
Instance Method Summary collapse
- #add_authorization! ⇒ Object
- #authorization(datetime) ⇒ Object
- #canonical_header_values(values) ⇒ Object
- #canonical_headers ⇒ Object
- #canonical_querystring ⇒ Object
- #canonical_request ⇒ Object
- #credential(datetime) ⇒ Object
- #credential_string(datetime) ⇒ Object
- #get_datetime ⇒ Object
- #hexhmac(key, value) ⇒ Object
- #hmac(key, value) ⇒ Object
-
#initialize(values, headers = {}) ⇒ HeadersV4
constructor
Create an HttpHeaderV4, values = { :host -> http host :hexdigest_body -> hexdigest of the http request’s body :region -> region of the endpoint :service -> the service that should recieve this request :http_method -> http method :path -> URI :querystring -> Everything after ? in URI :access_key_id -> access key :secret_access_key -> secret access kry [optional] :fixed_datetime -> Fix the datetime using DateTime object, do not use Time.now } For more info see: docs.aws.amazon.com/general/latest/gr/signature-version-4.html.
- #signature(datetime) ⇒ Object
- #signed_headers ⇒ Object
- #string_to_sign(datetime) ⇒ Object
Constructor Details
#initialize(values, headers = {}) ⇒ HeadersV4
Create an HttpHeaderV4, values =
:host -> http host
:hexdigest_body -> hexdigest of the http request's body
:region -> region of the endpoint
:service -> the service that should recieve this request
:http_method -> http method
:path -> URI
:querystring -> Everything after ? in URI
:access_key_id -> access key
:secret_access_key -> secret access kry
[optional] :fixed_datetime -> Fix the datetime using DateTime object, do not use Time.now
For more info see: docs.aws.amazon.com/general/latest/gr/signature-version-4.html
44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/ec2/common/headersv4.rb', line 44 def initialize values, headers={} @headers = headers @host = values[:host] @hexdigest_body = values[:hexdigest_body] @region = values[:region] @service = values[:service] @http_method = values[:http_method] @path = values[:path] @querystring = values[:querystring] @access_key_id = values[:access_key_id] @secret_access_key = values[:secret_access_key] @fixed_datetime = values[:fixed_datetime] end |
Class Method Details
.hexdigest(value, chunk_size = 1024 * 1024) ⇒ Object
Returns a SHA256 hexdigest of value. Should be used to hexdigest body of http request.
160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/ec2/common/headersv4.rb', line 160 def self.hexdigest value, chunk_size = 1024 * 1024 digest = Digest::SHA256.new if value.respond_to?(:read) chunk = nil digest.update(chunk) while chunk = value.read(chunk_size) value.rewind else digest.update(value) end digest.hexdigest end |
Instance Method Details
#add_authorization! ⇒ Object
58 59 60 61 62 63 64 65 |
# File 'lib/ec2/common/headersv4.rb', line 58 def datetime = get_datetime @headers['host'] = @host @headers['x-amz-date'] = datetime @headers['x-amz-content-sha256'] ||= @hexdigest_body || EC2::Common::HeadersV4::hexdigest('') @headers['authorization'] = (datetime) @headers end |
#authorization(datetime) ⇒ Object
67 68 69 70 71 72 73 |
# File 'lib/ec2/common/headersv4.rb', line 67 def datetime parts = [] parts << "AWS4-HMAC-SHA256 Credential=#{credential(datetime)}" parts << "SignedHeaders=#{signed_headers}" parts << "Signature=#{signature(datetime)}" parts.join(', ') end |
#canonical_header_values(values) ⇒ Object
140 141 142 143 |
# File 'lib/ec2/common/headersv4.rb', line 140 def canonical_header_values values values = [values] unless values.is_a?(Array) values.map{|v|v.to_s}.join(',').gsub(/\s+/, ' ').strip end |
#canonical_headers ⇒ Object
130 131 132 133 134 135 136 137 138 |
# File 'lib/ec2/common/headersv4.rb', line 130 def canonical_headers headers = [] @headers.each_pair do |k,v| k_lower = k.downcase headers << [k_lower,v] unless k_lower == 'authorization' end headers = headers.sort_by{|k,v| k} headers.map{|k,v| "#{k}:#{canonical_header_values(v)}"}.join("\n") end |
#canonical_querystring ⇒ Object
123 124 125 126 127 128 |
# File 'lib/ec2/common/headersv4.rb', line 123 def canonical_querystring CGI::parse(@querystring).sort_by{|k,v| CGI::escape(k)}.map do |v| value = v[1][0] || "" "#{CGI::escape(v[0])}=#{CGI::escape(value)}" end.join('&') end |
#canonical_request ⇒ Object
106 107 108 109 110 111 112 113 114 115 |
# File 'lib/ec2/common/headersv4.rb', line 106 def canonical_request parts = [] parts << @http_method parts << CGI::unescape(@path) parts << canonical_querystring parts << canonical_headers + "\n" parts << signed_headers parts << @headers['x-amz-content-sha256'] parts.join("\n") end |
#credential(datetime) ⇒ Object
93 94 95 |
# File 'lib/ec2/common/headersv4.rb', line 93 def credential datetime "#{@access_key_id}/#{credential_string(datetime)}" end |
#credential_string(datetime) ⇒ Object
97 98 99 100 101 102 103 104 |
# File 'lib/ec2/common/headersv4.rb', line 97 def credential_string datetime parts = [] parts << datetime[0,8] parts << @region parts << @service parts << 'aws4_request' parts.join("/") end |
#get_datetime ⇒ Object
153 154 155 156 |
# File 'lib/ec2/common/headersv4.rb', line 153 def get_datetime return @fixed_datetime.strftime("%Y%m%dT%H%M%SZ") if @fixed_datetime != nil Time.now.utc.strftime("%Y%m%dT%H%M%SZ") end |
#hexhmac(key, value) ⇒ Object
149 150 151 |
# File 'lib/ec2/common/headersv4.rb', line 149 def hexhmac key, value OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('sha256'), key, value) end |
#hmac(key, value) ⇒ Object
145 146 147 |
# File 'lib/ec2/common/headersv4.rb', line 145 def hmac key, value OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha256'), key, value) end |
#signature(datetime) ⇒ Object
75 76 77 78 79 80 81 82 |
# File 'lib/ec2/common/headersv4.rb', line 75 def signature datetime k_secret = @secret_access_key k_date = hmac("AWS4" + k_secret, datetime[0,8]) k_region = hmac(k_date, @region) k_service = hmac(k_region, @service) k_credentials = hmac(k_service, 'aws4_request') hexhmac(k_credentials, string_to_sign(datetime)) end |
#signed_headers ⇒ Object
117 118 119 120 121 |
# File 'lib/ec2/common/headersv4.rb', line 117 def signed_headers to_sign = @headers.keys.map{|k| k.to_s.downcase} to_sign.delete('authorization') to_sign.sort.join(";") end |
#string_to_sign(datetime) ⇒ Object
84 85 86 87 88 89 90 91 |
# File 'lib/ec2/common/headersv4.rb', line 84 def string_to_sign datetime parts = [] parts << 'AWS4-HMAC-SHA256' parts << datetime parts << credential_string(datetime) parts << EC2::Common::HeadersV4::hexdigest(canonical_request) parts.join("\n") end |