Implemented SigV4A (#40)

* Implemented should_sign_header callback

* Added SigV4A to SigningAlgorithm

* Added SigV4A test

* Added debugging info to README

* Fixed memory leak from argument vectors

* Fixed memory leak of stream read buffers

* Added support for callables as option values

* Added should_sign_header support and test

* Fixed ELG type bug exposed by aws-crt-ffi change

* Updated to aws-crt-ffi v0.2.0
This commit is contained in:
Justin Boswell
2021-07-28 12:54:37 -07:00
committed by GitHub
parent 3f77a01fbf
commit 92724b8d51
17 changed files with 361 additions and 132 deletions
+86 -3
View File
@@ -61,10 +61,13 @@ final class SigningTest extends CrtTestCase {
const SIGV4TEST_SESSION_TOKEN = null;
const SIGV4TEST_SERVICE = 'service';
const SIGV4TEST_REGION = 'us-east-1';
public function testSigv4HeaderSigning() {
private static function SIGV4TEST_DATE() {
return mktime(12, 36, 0, 8, 30, 2015);
}
public function testShouldSignHeader() {
$this->skipFFI();
$date = mktime(12, 36, 0, 8, 30, 2015);
$credentials_provider = new StaticCredentialsProvider([
'access_key_id' => self::SIGV4TEST_ACCESS_KEY_ID,
'secret_access_key' => self::SIGV4TEST_SECRET_ACCESS_KEY,
@@ -76,7 +79,48 @@ final class SigningTest extends CrtTestCase {
'credentials_provider' => $credentials_provider,
'region' => self::SIGV4TEST_REGION,
'service' => self::SIGV4TEST_SERVICE,
'date' => $date,
'date' => self::SIGV4TEST_DATE(),
'should_sign_header' => function($header) {
return strtolower($header) != 'x-do-not-sign';
}
]);
$http_request = new Request('GET', '/', [], [
'Host' => 'example.amazonaws.com',
'X-Do-Not-Sign' => 'DO NOT SIGN THIS']);
$this->assertNotNull($http_request, "Unable to create HttpRequest for signing");
$signable = Signable::fromHttpRequest($http_request);
$this->assertNotNull($signable, "Unable to create signable from HttpRequest");
Signing::signRequestAws(
$signable, $signing_config,
function($signing_result, $error_code) use (&$http_request) {
$this->assertEquals(0, $error_code);
$signing_result->applyToHttpRequest($http_request);
}
);
// This signature value is computed without the X-Do-Not-Sign header above
$headers = $http_request->headers();
$this->assertEquals(
'AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31',
$headers->get('Authorization'));
}
public function testSigv4HeaderSigning() {
$this->skipFFI();
$credentials_provider = new StaticCredentialsProvider([
'access_key_id' => self::SIGV4TEST_ACCESS_KEY_ID,
'secret_access_key' => self::SIGV4TEST_SECRET_ACCESS_KEY,
'session_token' => self::SIGV4TEST_SESSION_TOKEN,
]);
$signing_config = new SigningConfigAWS([
'algorithm' => SigningAlgorithm::SIGv4,
'signature_type' => SignatureType::HTTP_REQUEST_HEADERS,
'credentials_provider' => $credentials_provider,
'region' => self::SIGV4TEST_REGION,
'service' => self::SIGV4TEST_SERVICE,
'date' => self::SIGV4TEST_DATE(),
]);
$http_request = new Request('GET', '/', [], ['Host' => 'example.amazonaws.com']);
$this->assertNotNull($http_request, "Unable to create HttpRequest for signing");
@@ -97,4 +141,43 @@ final class SigningTest extends CrtTestCase {
$headers->get('Authorization'));
$this->assertEquals('20150830T123600Z', $headers->get('X-Amz-Date'));
}
public function testSigV4aHeaderSigning() {
$this->skipFFI();
$credentials_provider = new StaticCredentialsProvider([
'access_key_id' => self::SIGV4TEST_ACCESS_KEY_ID,
'secret_access_key' => self::SIGV4TEST_SECRET_ACCESS_KEY,
'session_token' => self::SIGV4TEST_SESSION_TOKEN,
]);
$signing_config = new SigningConfigAWS([
'algorithm' => SigningAlgorithm::SIGv4_ASYMMETRIC,
'signature_type' => SignatureType::HTTP_REQUEST_HEADERS,
'credentials_provider' => $credentials_provider,
'region' => self::SIGV4TEST_REGION,
'service' => self::SIGV4TEST_SERVICE,
'date' => self::SIGV4TEST_DATE(),
]);
$http_request = new Request('GET', '/', [], ['Host' => 'example.amazonaws.com']);
$this->assertNotNull($http_request, "Unable to create HttpRequest for signing");
$signable = Signable::fromHttpRequest($http_request);
$this->assertNotNull($signable, "Unable to create signable from HttpRequest");
Signing::signRequestAws(
$signable, $signing_config,
function($signing_result, $error_code) use (&$http_request) {
$this->assertEquals(0, $error_code);
$signing_result->applyToHttpRequest($http_request);
}
);
$headers = $http_request->headers();
$auth_header_value = $headers->get('Authorization');
$this->assertNotNull($auth_header_value);
$this->assertStringStartsWith(
'AWS4-ECDSA-P256-SHA256 Credential=AKIDEXAMPLE/20150830/service/aws4_request, SignedHeaders=host;x-amz-date;x-amz-region-set, Signature=',
$auth_header_value);
$this->assertEquals('20150830T123600Z', $headers->get('X-Amz-Date'));
}
}