Skip to content

Commit c2955de

Browse files
author
sfomuseumbot
committed
initial commit; incomplete
0 parents  commit c2955de

File tree

4 files changed

+224
-0
lines changed

4 files changed

+224
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*~

LICENSE

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Copyright (c) 2024, City and County of San Francisco, acting by and through its
2+
Airport Commission ("City"). All rights reserved.
3+
4+
The City and County of San Francisco, acting by and through its Airport
5+
Commission, created and operates the SFO Museum.
6+
7+
Redistribution and use in source and binary forms, with or without modification,
8+
are permitted provided that the following conditions are met:
9+
10+
1. Redistributions of source code must retain the above copyright notice, this
11+
list of conditions and the following disclaimer.
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
3. Neither the name of the City nor the names of its contributors may be used
16+
to endorse or promote products derived from this software without specific
17+
prior written permission.
18+
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# flamework-aws
2+
3+
## Important
4+
5+
This is work in progress. It is not complete and it will change.
6+
7+
## See also
8+
9+
* https://github.com/sfomuseum/flamework

www/include/lib_aws_signer_v4.php

+186
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
<?php
2+
3+
# WORK IN PROGRESS. EVERYTHING WILL CHANGE.
4+
# Derived from https://github.com/avi-wish/aws4-signature-php
5+
6+
# If you need to verify / sanity check things against a known-working implementation:
7+
# https://github.com/aaronland/go-aws-auth?tab=readme-ov-file#aws-sign-request
8+
9+
function aws_signer_v4_headers($host, $uri, $requestUrl, $accessKey, $secretKey, $securityToken, $region, $service, $httpRequestMethod, $data, $debug = TRUE){
10+
11+
$headers_to_sign = array(
12+
"content-length",
13+
"content-type",
14+
"host",
15+
"x-amz-date",
16+
);
17+
18+
if ($securityToken != ""){
19+
$headers_to_sign[] = "x-amz-security-token";
20+
}
21+
22+
$terminationString = 'aws4_request';
23+
$algorithm = 'AWS4-HMAC-SHA256';
24+
$phpAlgorithm = 'sha256';
25+
$canonicalURI = $uri;
26+
$canonicalQueryString = '';
27+
$signedHeaders = implode(";", $headers_to_sign);
28+
29+
$currentDateTime = new DateTime('UTC');
30+
$reqDate = $currentDateTime->format('Ymd');
31+
$reqDateTime = $currentDateTime->format('Ymd\THis\Z');
32+
33+
// Create signing key
34+
$kSecret = $secretKey;
35+
$kDate = hash_hmac($phpAlgorithm, $reqDate, "AWS4{$kSecret}", true);
36+
$kRegion = hash_hmac($phpAlgorithm, $region, $kDate, true);
37+
$kService = hash_hmac($phpAlgorithm, $service, $kRegion, true);
38+
$kSigning = hash_hmac($phpAlgorithm, $terminationString, $kService, true);
39+
40+
// Create canonical headers
41+
$canonicalHeaders = array();
42+
$canonicalHeaders[] = 'content-length:' . strlen($data);
43+
$canonicalHeaders[] = 'content-type:application/json';
44+
$canonicalHeaders[] = 'host:' . $host;
45+
$canonicalHeaders[] = 'x-amz-date:' . $reqDateTime;
46+
47+
if ($securityToken != ""){
48+
$canonicalHeaders[] = 'x-amz-security-token:' . $securityToken;
49+
}
50+
51+
$canonicalHeadersStr = implode("\n", $canonicalHeaders);
52+
53+
// Create request payload
54+
$requestHashedPayload = strtolower(bin2hex(hash($phpAlgorithm, $data, true)));
55+
56+
// Create canonical request
57+
$canonicalRequest = array();
58+
$canonicalRequest[] = $httpRequestMethod;
59+
$canonicalRequest[] = $canonicalURI;
60+
$canonicalRequest[] = $canonicalQueryString;
61+
$canonicalRequest[] = $canonicalHeadersStr . "\n";
62+
$canonicalRequest[] = $signedHeaders;
63+
$canonicalRequest[] = $requestHashedPayload;
64+
$requestCanonicalRequest = implode("\n", $canonicalRequest);
65+
66+
if ($debug){
67+
echo "[CANONICAL STRING]\n";
68+
echo "---\n";
69+
echo "{$requestCanonicalRequest}\n";
70+
echo "---\n";
71+
}
72+
73+
$requestHashedCanonicalRequest = strtolower(bin2hex(hash($phpAlgorithm, $requestCanonicalRequest, true)));
74+
75+
// Create scope
76+
$credentialScope = array();
77+
$credentialScope[] = $reqDate;
78+
$credentialScope[] = $region;
79+
$credentialScope[] = $service;
80+
$credentialScope[] = $terminationString;
81+
$credentialScopeStr = implode('/', $credentialScope);
82+
83+
// Create string to signing
84+
$stringToSign = array();
85+
$stringToSign[] = $algorithm;
86+
$stringToSign[] = $reqDateTime;
87+
$stringToSign[] = $credentialScopeStr;
88+
$stringToSign[] = $requestHashedCanonicalRequest;
89+
$stringToSignStr = implode("\n", $stringToSign);
90+
91+
if($debug){
92+
echo "[STRING TO SIGN]\n";
93+
echo "---\n";
94+
echo "{$stringToSignStr}\n";
95+
echo "---\n";
96+
}
97+
98+
// Create signature
99+
100+
$signature = hash_hmac($phpAlgorithm, $stringToSignStr, $kSigning);
101+
102+
// Create authorization header
103+
$authorizationHeader = array();
104+
$authorizationHeader[] = 'Credential=' . $accessKey . '/' . $credentialScopeStr;
105+
$authorizationHeader[] = 'SignedHeaders=' . $signedHeaders;
106+
$authorizationHeader[] = 'Signature=' . ($signature);
107+
$authorizationHeaderStr = $algorithm . ' ' . implode(', ', $authorizationHeader);
108+
109+
// Request headers
110+
$headers = array();
111+
$headers[] = 'accept:';
112+
$headers[] = 'authorization: '.$authorizationHeaderStr;
113+
$headers[] = 'content-length: '.strlen($data);
114+
$headers[] = 'content-type: application/json';
115+
$headers[] = 'host: ' . $host;
116+
$headers[] = 'x-amz-date: ' . $reqDateTime;
117+
118+
if ($securityToken != ""){
119+
$headers[] = 'x-amz-security-token: ' . $securityToken;
120+
}
121+
122+
return $headers;
123+
}
124+
125+
/**
126+
* This function is in use
127+
* for send request with authorization header
128+
*/
129+
function callToAPI($requestUrl, $httpRequestMethod, $headers, $data, $debug=TRUE)
130+
{
131+
132+
// Execute the call
133+
$curl = curl_init();
134+
curl_setopt_array($curl, array(
135+
CURLOPT_URL => $requestUrl,
136+
CURLOPT_RETURNTRANSFER => true,
137+
CURLOPT_FOLLOWLOCATION => true,
138+
CURLOPT_TIMEOUT => 30,
139+
CURLOPT_POST => true,
140+
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
141+
CURLOPT_CUSTOMREQUEST => $httpRequestMethod,
142+
CURLOPT_POSTFIELDS => $data,
143+
CURLOPT_VERBOSE => 0,
144+
CURLOPT_SSL_VERIFYHOST => 0,
145+
CURLOPT_SSL_VERIFYPEER => 0,
146+
CURLOPT_HEADER => false,
147+
CURLINFO_HEADER_OUT=>true,
148+
CURLOPT_HTTPHEADER => $headers,
149+
));
150+
151+
$response = curl_exec($curl);
152+
$err = curl_error($curl);
153+
$responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
154+
155+
if($debug){
156+
$headers = curl_getinfo($curl, CURLINFO_HEADER_OUT);
157+
echo "[REQUEST]\n";
158+
echo "---\n";
159+
echo "{$headers}\n";
160+
echo "---\n";
161+
}
162+
163+
curl_close($curl);
164+
165+
if ($err) {
166+
if($debug){
167+
echo "<h5>Error:" . $responseCode . "</h5>";
168+
echo "<pre>";
169+
echo $err;
170+
echo "</pre>";
171+
}
172+
} else {
173+
if($debug){
174+
echo "<h5>Response:" . $responseCode . "</h5>";
175+
echo "<pre>";
176+
echo $response;
177+
echo "</pre>";
178+
}
179+
}
180+
181+
return array(
182+
"responseCode" => $responseCode,
183+
"response" => $response,
184+
"error" => $err
185+
);
186+
}// End callToAPI

0 commit comments

Comments
 (0)