-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AWS4 Authentication Protocol Required by Some Regions #440
Comments
- `amazon_s3_files_bucket_region` See: #440
Holy hell! I dunno what the folks at AWS are thinking! Their signature algo is just ridiculous. haha All of this just to get a signature for the ~ Ugh, 4 hours I'll never get back. It's working now though. I'll merge it in shortly :-) This is one article I hope I don't need to read again anytime soon. /**
* Creates an Amazon S3 AWS4-HMAC-SHA256 signature.
*
* @package s2Member\Files
* @since 150108
*
* @param string $string Input string/data, to be signed by this routine.
*
* @return string An AWS4-HMAC-SHA256 signature for Amazon S3.
*/
public static function amazon_s34_sign($string = '')
{
$s3c = array(); // Initialize config. keys.
foreach($GLOBALS['WS_PLUGIN__']['s2member']['o'] as $option => $option_value)
if(preg_match('/^amazon_s3_files_/', $option) && ($option = preg_replace('/^amazon_s3_files_/', '', $option)))
$s3c[$option] = $option_value;
$s3_date_key = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign(date('Ymd'), 'AWS4'.$s3c['secret_key'], TRUE);
$s3_date_region_key = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign($s3c['bucket_region'], $s3_date_key, TRUE);
$s3_date_region_service_key = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign('s3', $s3_date_region_key, TRUE);
$s3_signing_key = c_ws_plugin__s2member_utils_strings::hmac_sha256_sign('aws4_request', $s3_date_region_service_key, TRUE);
return c_ws_plugin__s2member_utils_strings::hmac_sha256_sign((string)$string, $s3_signing_key);
}
/**
* Creates an Amazon S3 AWS4-HMAC-SHA256 signature/authorization header.
*
* @package s2Member\Files
* @since 150108
*
* @param string $s3_date The date header; e.g. `YYYYMMDD'T'HHMMSS'Z'`.
* @param string $s3_domain The API endpoint domain; e.g. `[bucket].s3.amazonaws.com`.
* @param string $s3_location The API endpoint URI; e.g. `/?acl`.
* @param string $s3_method The request method; e.g. `GET`, `PUT`, `POST`, etc.
* @param array $s3_headers An associative array of all headers.
* @param string $s3_body Any input data sent with the request.
*
* @return string An AWS4-HMAC-SHA256 signature/authorization header for Amazon S3.
*/
public static function amazon_s34_authorization($s3_date = '',
$s3_domain = 's3.amazonaws.com',
$s3_location = '/', $s3_method = 'GET',
$s3_headers = array(), $s3_body = '')
{
$s3_date = trim((string)$s3_date);
$s3_domain = trim(strtolower((string)$s3_domain));
$s3_location = trim((string)$s3_location);
$s3_method = trim(strtoupper((string)$s3_method));
$s3_headers = (array)$s3_headers;
$s3_body = trim((string)$s3_body);
$s3c = array(); // Initialize config. keys.
foreach($GLOBALS['WS_PLUGIN__']['s2member']['o'] as $option => $option_value)
if(preg_match('/^amazon_s3_files_/', $option) && ($option = preg_replace('/^amazon_s3_files_/', '', $option)))
$s3c[$option] = $option_value;
$s3_iso8601_date = date('Ymd\THis\Z');
$s3_location_parts = parse_url($s3_location);
$s3_canonical_path = !empty($s3_location_parts['path']) ? '/'.ltrim($s3_location_parts['path'], '/') : '/';
$s3_scope = date('Ymd').'/'.$s3c['bucket_region'].'/s3/aws4_request';
$s3_canonical_query = ''; // Initialize.
wp_parse_str((string)@$s3_location_parts['query'], $query_args);
ksort($query_args, SORT_STRING);
foreach($query_args as $_key => $_value)
$s3_canonical_query .= '&'.c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(rawurlencode($_key)).
'='.c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(rawurlencode($_value));
$s3_canonical_query = ltrim($s3_canonical_query, '&');
unset($_key, $_value); // Housekeeping.
$s3_canonical_headers = '';
$s3_canonical_header_keys = array();
ksort($s3_headers, SORT_STRING);
foreach($s3_headers as $_key => $_value)
if(is_string($_key) && ($_key = strtolower($_key)))
if(in_array($_key, array('host', 'content-type'), TRUE) || stripos($_key, 'X-Amz-') === 0)
{
$s3_canonical_headers .= strtolower($_key).':'.trim($_value)."\n";
$s3_canonical_header_keys[] = strtolower($_key);
}
unset($_key, $_value); // Housekeeping.
$s3_canonicial_request = $s3_method."\n".
$s3_canonical_path."\n".
$s3_canonical_query."\n".
$s3_canonical_headers."\n".
implode(';', $s3_canonical_header_keys)."\n".
hash('sha256', $s3_body);
$s3_string_to_sign = 'AWS4-HMAC-SHA256'."\n".
$s3_date."\n".
$s3_scope."\n".
hash('sha256', $s3_canonicial_request);
$s3_signature = self::amazon_s34_sign($s3_string_to_sign);
$s3_authorization_header_signature = 'AWS4-HMAC-SHA256 Credential='.$s3c['access_key'].'/'.$s3_scope.','.
'SignedHeaders='.implode(';', $s3_canonical_header_keys).','.
'Signature='.$s3_signature;
return $s3_authorization_header_signature;
} |
ha ~ I'm deleting 38 CloudFront Distros I created while testing this. That's funny 😄 |
Reopening this issue. It's come to my attention that digital signatures leading to specific resources may also require |
Adding AWS v4 authentication to S3 presigned URLs. Closes #440
Next Release Changelog:
|
This issue was resolved in the release of s2Member v150203. Please see: http://www.s2member.com/kb/v150203/ If there are any follow-ups needed, please open a new issue and we will investigate. Thanks! |
Referencing: http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html
The text was updated successfully, but these errors were encountered: