Skip to content

Commit 247e2d2

Browse files
committed
Extend AwsService:getAuthorizationHeader() / AwsV4Signature:getAuthorizationHeader() so that the caller can pass the arbitrary host name for signer to calculate the hash with.
1 parent 77984d5 commit 247e2d2

File tree

2 files changed

+42
-23
lines changed

2 files changed

+42
-23
lines changed

src/lua/api-gateway/aws/AwsService.lua

+15-8
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,11 @@ function _M:getHttpClient()
187187
end
188188

189189
function _M:getAWSHost()
190-
return self.aws_service .. "." .. self.aws_region .. ".amazonaws.com"
190+
if self.aws_service == "s3" then
191+
return self.aws_service .. "-" .. self.aws_region .. ".amazonaws.com"
192+
else
193+
return self.aws_service .. "." .. self.aws_region .. ".amazonaws.com"
194+
end
191195
end
192196

193197
function _M:getCredentials()
@@ -201,16 +205,18 @@ function _M:getCredentials()
201205
return return_obj
202206
end
203207

204-
function _M:getAuthorizationHeader(http_method, path, uri_args, body)
208+
function _M:getAuthorizationHeader(http_method, path, uri_args, body, host_override)
205209
local credentials = self:getCredentials()
210+
credentials.aws_endpoint = self:getAWSHost()
206211
credentials.aws_region = self.aws_region
207212
credentials.aws_service = self.aws_service
208213
local awsAuth = AWSV4S:new(credentials)
209-
local authorization = awsAuth:getAuthorizationHeader(http_method,
214+
local authorization, payload_hash = awsAuth:getAuthorizationHeader(http_method,
210215
path, -- "/"
211216
uri_args, -- ngx.req.get_uri_args()
212-
body)
213-
return authorization, awsAuth, credentials.token
217+
body,
218+
host_override)
219+
return authorization, awsAuth, credentials.token, payload_hash
214220
end
215221

216222
---
@@ -278,7 +284,7 @@ function _M:performAction(actionName, arguments, path, http_method, useSSL, time
278284
end
279285

280286

281-
local authorization, awsAuth, authToken = self:getAuthorizationHeader(request_method, request_path, uri_args, request_body)
287+
local authorization, awsAuth, authToken, payloadHash = self:getAuthorizationHeader(request_method, request_path, uri_args, request_body)
282288

283289
local t = self.aws_service_name .. "." .. actionName
284290
local request_headers = {
@@ -287,7 +293,8 @@ function _M:performAction(actionName, arguments, path, http_method, useSSL, time
287293
["Accept"] = "application/json",
288294
["Content-Type"] = content_type,
289295
["X-Amz-Target"] = t,
290-
["x-amz-security-token"] = authToken
296+
["x-amz-security-token"] = authToken,
297+
["x-amz-content-sha256"] = payloadHash
291298
}
292299
if ( extra_headers ~= nil ) then
293300
for headerName, headerValue in pairs(extra_headers) do
@@ -329,4 +336,4 @@ function _M:performAction(actionName, arguments, path, http_method, useSSL, time
329336
return ok, code, headers, status, body
330337
end
331338

332-
return _M
339+
return _M

src/lua/api-gateway/aws/AwsV4Signature.lua

+27-15
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ function HmacAuthV4Handler:new(o)
1717
setmetatable(o, self)
1818
self.__index = self
1919
if ( o ~= nil) then
20+
self.aws_endpoint = o.aws_endpoint
2021
self.aws_service = o.aws_service
2122
self.aws_region = o.aws_region
2223
self.aws_secret_key = o.aws_secret_key
2324
self.aws_access_key = o.aws_access_key
25+
self.token = o.token
2426
end
2527
-- set amazon formatted dates
2628
local utc = ngx.utctime()
@@ -52,7 +54,8 @@ local function get_hashed_canonical_request(method, uri, querystring, headers, r
5254
-- add canonicalHeaders
5355
local canonicalHeaders = ""
5456
local signedHeaders = ""
55-
for h_n,h_v in pairs(headers) do
57+
for _, p in ipairs(headers) do
58+
local h_n, h_v = p[1], p[2]
5659
-- todo: trim and lowercase
5760
canonicalHeaders = canonicalHeaders .. h_n .. ":" .. h_v .. "\n"
5861
signedHeaders = signedHeaders .. h_n .. ";"
@@ -63,13 +66,14 @@ local function get_hashed_canonical_request(method, uri, querystring, headers, r
6366
hash = hash .. canonicalHeaders .. "\n"
6467
.. signedHeaders .. "\n"
6568

66-
hash = hash .. _hash(requestPayload or "")
69+
requestPayloadHash = _hash(requestPayload or "")
70+
hash = hash .. requestPayloadHash
6771

6872
ngx.log(ngx.DEBUG, "Canonical String to Sign is:\n" .. hash)
6973

7074
local final_hash = _hash(hash)
7175
ngx.log(ngx.DEBUG, "Canonical String HASHED is:\n" .. final_hash .. "\n")
72-
return final_hash
76+
return final_hash, signedHeaders, requestPayloadHash
7377
end
7478

7579
local function get_string_to_sign(algorithm, request_date, credential_scope, hashed_canonical_request)
@@ -141,36 +145,44 @@ function HmacAuthV4Handler:formatQueryString(uri_args)
141145
return uri
142146
end
143147

144-
function HmacAuthV4Handler:getSignature(http_method, request_uri, uri_arg_table, request_payload )
148+
function HmacAuthV4Handler:getSignature(http_method, request_uri, uri_arg_table, request_payload, host_override)
145149
local uri_args = self:formatQueryString(uri_arg_table)
146150
local utc = ngx.utctime()
147151
local date1 = self.aws_date_short
148152
local date2 = self.aws_date
153+
local host = self.aws_endpoint
154+
if host_override ~= nil then
155+
host = host_override
156+
end
149157

150158
local headers = {}
151-
headers.host = self.aws_service .. "." .. self.aws_region .. ".amazonaws.com"
152-
headers["x-amz-date"] = date2
159+
table.insert(headers, {"host", host})
160+
table.insert(headers, {"x-amz-date", date2})
161+
if self.token ~= nil then
162+
table.insert(headers, {"x-amz-security-token", self.token})
163+
end
153164

154165
-- ensure parameters in query string are in order
166+
local hashed_canonical_request, signed_headers, request_payload_hash = get_hashed_canonical_request(
167+
http_method, request_uri,
168+
uri_args,
169+
headers, request_payload)
155170
local sign = _sign( get_derived_signing_key( self.aws_secret_key,
156171
date1,
157172
self.aws_region,
158173
self.aws_service),
159174
get_string_to_sign("AWS4-HMAC-SHA256",
160175
date2,
161176
date1 .. "/" .. self.aws_region .. "/" .. self.aws_service .. "/aws4_request",
162-
get_hashed_canonical_request(
163-
http_method, request_uri,
164-
uri_args,
165-
headers, request_payload) ) )
166-
return sign
177+
hashed_canonical_request) )
178+
return sign, signed_headers, request_payload_hash
167179
end
168180

169-
function HmacAuthV4Handler:getAuthorizationHeader(http_method, request_uri, uri_arg_table, request_payload )
170-
local auth_signature = self:getSignature(http_method, request_uri, uri_arg_table, request_payload)
181+
function HmacAuthV4Handler:getAuthorizationHeader(http_method, request_uri, uri_arg_table, request_payload, host_override)
182+
local auth_signature, signed_headers, request_payload_hash = self:getSignature(http_method, request_uri, uri_arg_table, request_payload, host_override)
171183
local authHeader = "AWS4-HMAC-SHA256 Credential=" .. self.aws_access_key.."/" .. self.aws_date_short .. "/" .. self.aws_region
172-
.."/" .. self.aws_service.."/aws4_request,SignedHeaders=host;x-amz-date,Signature="..auth_signature
173-
return authHeader
184+
.."/" .. self.aws_service.."/aws4_request,SignedHeaders="..signed_headers..",Signature="..auth_signature
185+
return authHeader, request_payload_hash
174186
end
175187

176188
return HmacAuthV4Handler

0 commit comments

Comments
 (0)