Skip to content
This repository has been archived by the owner on Nov 19, 2018. It is now read-only.

Commit

Permalink
feat(v4 signatures): handle raw canonical request for v4 REST signature
Browse files Browse the repository at this point in the history
  • Loading branch information
rnicholus committed Nov 4, 2015
1 parent 4e1d95c commit da0c7be
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions nodejs/s3/s3handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var express = require("express"),

// Set these two values to match your environment
expectedBucket = "fineuploadertest",
expectedHostname = "fineuploadertest.s3.amazonaws.com",

// CHANGE TO INTEGERS TO ENABLE POLICY DOCUMENT VERIFICATION ON FILE SIZE
// (recommended)
Expand Down Expand Up @@ -96,16 +97,17 @@ function signRequest(req, res) {

// Signs multipart (chunked) requests. Omit if you don't want to support chunking.
function signRestRequest(req, res) {
var stringToSign = req.body.headers,
signature = req.query.v4 ? signV4RestRequest(stringToSign) : signV2RestRequest(stringToSign);
var version = req.query.v4 ? 4 : 2,
stringToSign = req.body.headers,
signature = version === 4 ? signV4RestRequest(stringToSign) : signV2RestRequest(stringToSign);

var jsonResponse = {
signature: signature
};

res.setHeader("Content-Type", "application/json");

if (req.query.v4 || isValidRestRequest(stringToSign)) {
if (isValidRestRequest(stringToSign, version)) {
res.end(JSON.stringify(jsonResponse));
}
else {
Expand All @@ -119,8 +121,11 @@ function signV2RestRequest(headersStr) {
}

function signV4RestRequest(headersStr) {
var matches = /.+\n.+\n(\d+)\/(.+)\/s3\/.+\n(.+)/.exec(headersStr);
return getV4SignatureKey(clientSecretKey, matches[1], matches[2], "s3", headersStr);
var matches = /.+\n.+\n(\d+)\/(.+)\/s3\/aws4_request\n([\s\S]+)/.exec(headersStr),
hashedCanonicalRequest = CryptoJS.SHA256(matches[3]),
stringToSign = headersStr.replace(/(.+s3\/aws4_request\n)[\s\S]+/, '$1' + hashedCanonicalRequest);

return getV4SignatureKey(clientSecretKey, matches[1], matches[2], "s3", stringToSign);
}

// Signs "simple" (non-chunked) upload requests.
Expand Down Expand Up @@ -166,7 +171,11 @@ function signV4Policy(policy, base64Policy) {

// Ensures the REST request is targeting the correct bucket.
// Omit if you don't want to support chunking.
function isValidRestRequest(headerStr) {
function isValidRestRequest(headerStr, version) {
if (version === 4) {
return new RegExp("host:" + expectedHostname).exec(headerStr) != null;
}

return new RegExp("\/" + expectedBucket + "\/.+$").exec(headerStr) != null;
}

Expand Down

0 comments on commit da0c7be

Please sign in to comment.