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

Commit 25750f9

Browse files
committed
feat(v4 signatures): start of v4 signature support for S3 endpoint example
FineUploader/fine-uploader#1336
1 parent 04efb49 commit 25750f9

File tree

2 files changed

+54
-8
lines changed

2 files changed

+54
-8
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.idea

endpoint.php

+53-8
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@
7474
// DELETE, in a "_method" parameter.
7575
function getRequestMethod() {
7676

77-
if ($_POST['_method'] != null) {
78-
return $_POST['_method'];
77+
if ($_REQUEST['_method'] != null) {
78+
return $_REQUEST['_method'];
7979
}
8080

8181
return $_SERVER['REQUEST_METHOD'];
@@ -115,7 +115,11 @@ function signRequest() {
115115
}
116116

117117
function signRestRequest($headersStr) {
118-
if (isValidRestRequest($headersStr)) {
118+
if (isset($_REQUEST["v4"])) {
119+
$response = array('signature' => signV4RestRequest($headersStr));
120+
echo json_encode($response);
121+
}
122+
else if (isValidRestRequest($headersStr)) {
119123
$response = array('signature' => sign($headersStr));
120124
echo json_encode($response);
121125
}
@@ -138,8 +142,15 @@ function signPolicy($policyStr) {
138142

139143
if (isPolicyValid($policyObj)) {
140144
$encodedPolicy = base64_encode($policyStr);
141-
$response = array('policy' => $encodedPolicy, 'signature' => sign($encodedPolicy));
145+
146+
if (isset($_REQUEST["v4"])) {
147+
$response = array('policy' => $encodedPolicy, 'signature' => signV4Policy($encodedPolicy, $policyObj));
148+
}
149+
else {
150+
$response = array('policy' => $encodedPolicy, 'signature' => sign($encodedPolicy));
151+
}
142152
echo json_encode($response);
153+
143154
}
144155
else {
145156
echo json_encode(array("invalid" => true));
@@ -178,12 +189,46 @@ function sign($stringToSign) {
178189
));
179190
}
180191

192+
function signV4Policy($stringToSign, $policyObj) {
193+
global $clientPrivateKey;
194+
195+
foreach ($policyObj["conditions"] as $condition) {
196+
if (isset($condition["x-amz-credential"])) {
197+
$credentialCondition = $condition["x-amz-credential"];
198+
}
199+
}
200+
201+
$pattern = "/.+\/(.+)\\/(.+)\/s3\/aws4_request/";
202+
preg_match($pattern, $credentialCondition, $matches);
203+
204+
$dateKey = hash_hmac('sha256', $matches[1], 'AWS4' . $clientPrivateKey, true);
205+
$dateRegionKey = hash_hmac('sha256', $matches[2], $dateKey, true);
206+
$dateRegionServiceKey = hash_hmac('sha256', 's3', $dateRegionKey, true);
207+
$signingKey = hash_hmac('sha256', 'aws4_request', $dateRegionServiceKey, true);
208+
209+
return hash_hmac('sha256', $stringToSign, $signingKey);
210+
}
211+
212+
function signV4RestRequest($stringToSign) {
213+
global $clientPrivateKey;
214+
215+
$pattern = "/.+\\n.+\\n(\\d+)\/(.+)\/s3\/.+\\n(.+)/";
216+
preg_match($pattern, $stringToSign, $matches);
217+
218+
$dateKey = hash_hmac('sha256', $matches[1], 'AWS4' . $clientPrivateKey, true);
219+
$dateRegionKey = hash_hmac('sha256', $matches[2], $dateKey, true);
220+
$dateRegionServiceKey = hash_hmac('sha256', 's3', $dateRegionKey, true);
221+
$signingKey = hash_hmac('sha256', 'aws4_request', $dateRegionServiceKey, true);
222+
223+
return hash_hmac('sha256', $stringToSign, $signingKey);
224+
}
225+
181226
// This is not needed if you don't require a callback on upload success.
182227
function verifyFileInS3($includeThumbnail) {
183228
global $expectedMaxSize;
184229

185-
$bucket = $_POST["bucket"];
186-
$key = $_POST["key"];
230+
$bucket = $_REQUEST["bucket"];
231+
$key = $_REQUEST["key"];
187232

188233
// If utilizing CORS, we return a 200 response with the error message in the body
189234
// to ensure Fine Uploader can parse the error message in IE9 and IE8,
@@ -240,8 +285,8 @@ function isFileViewableImage($filename) {
240285
// (which is our goal here - keep it simple) we only include a link to
241286
// a viewable image and only if the browser is not capable of generating a client-side preview.
242287
function shouldIncludeThumbnail() {
243-
$filename = $_POST["name"];
244-
$isPreviewCapable = $_POST["isBrowserPreviewCapable"] == "true";
288+
$filename = $_REQUEST["name"];
289+
$isPreviewCapable = $_REQUEST["isBrowserPreviewCapable"] == "true";
245290
$isFileViewableImage = isFileViewableImage($filename);
246291

247292
return !$isPreviewCapable && $isFileViewableImage;

0 commit comments

Comments
 (0)