Skip to content

Commit 44b936e

Browse files
authored
bugfix: cloudfront sigv4a (#2857)
1 parent ab796bc commit 44b936e

File tree

6 files changed

+119
-137
lines changed

6 files changed

+119
-137
lines changed

.changes/nextrelease/crt-updates.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{
3+
"type": "bugfix",
4+
"category": "Signature",
5+
"description": "Fixes issues with CloudfrontKeyValueStore sigv4a operations."
6+
}
7+
]

features/crt/cloudfront-kvs.feature

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@crt @integ @cloudfront-kvs
2+
Feature: Cloudfront Kvs Sigv4a
3+
4+
Scenario: Describe a cloudfront kvs
5+
Given I have a cloudfront client and I have a key-value store
6+
Then I can describe my key-value store using sigv4a

src/Signature/S3SignatureV4.php

+36
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
namespace Aws\Signature;
33

44
use Aws\Credentials\CredentialsInterface;
5+
use AWS\CRT\Auth\SignatureType;
6+
use AWS\CRT\Auth\SigningAlgorithm;
7+
use AWS\CRT\Auth\SigningConfigAWS;
58
use Psr\Http\Message\RequestInterface;
69

710
/**
@@ -41,6 +44,39 @@ public function signRequest(
4144
return $this->signWithV4a($credentials, $request, $signingService);
4245
}
4346

47+
/**
48+
* @param CredentialsInterface $credentials
49+
* @param RequestInterface $request
50+
* @param $signingService
51+
* @param SigningConfigAWS|null $signingConfig
52+
* @return RequestInterface
53+
*
54+
* Instantiates a separate sigv4a signing config. All services except S3
55+
* use double encoding. All services except S3 require path normalization.
56+
*/
57+
protected function signWithV4a(
58+
CredentialsInterface $credentials,
59+
RequestInterface $request,
60+
$signingService,
61+
SigningConfigAWS $signingConfig = null
62+
){
63+
$this->verifyCRTLoaded();
64+
$credentials_provider = $this->createCRTStaticCredentialsProvider($credentials);
65+
$signingConfig = new SigningConfigAWS([
66+
'algorithm' => SigningAlgorithm::SIGv4_ASYMMETRIC,
67+
'signature_type' => SignatureType::HTTP_REQUEST_HEADERS,
68+
'credentials_provider' => $credentials_provider,
69+
'signed_body_value' => $this->getPayload($request),
70+
'region' => "*",
71+
'should_normalize_uri_path' => false,
72+
'use_double_uri_encode' => false,
73+
'service' => $signingService,
74+
'date' => time(),
75+
]);
76+
77+
return parent::signWithV4a($credentials, $request, $signingService, $signingConfig);
78+
}
79+
4480
/**
4581
* Always add a x-amz-content-sha-256 for data integrity.
4682
*

src/Signature/SignatureV4.php

+15-8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use Aws\Credentials\CredentialsInterface;
55
use AWS\CRT\Auth\Signable;
66
use AWS\CRT\Auth\SignatureType;
7+
use AWS\CRT\Auth\SignedBodyHeaderType;
78
use AWS\CRT\Auth\Signing;
89
use AWS\CRT\Auth\SigningAlgorithm;
910
use AWS\CRT\Auth\SigningConfigAWS;
@@ -446,7 +447,7 @@ private function buildRequest(array $req)
446447
);
447448
}
448449

449-
private function verifyCRTLoaded()
450+
protected function verifyCRTLoaded()
450451
{
451452
if (!extension_loaded('awscrt')) {
452453
throw new CommonRuntimeException(
@@ -457,7 +458,7 @@ private function verifyCRTLoaded()
457458
}
458459
}
459460

460-
private function createCRTStaticCredentialsProvider($credentials)
461+
protected function createCRTStaticCredentialsProvider($credentials)
461462
{
462463
return new StaticCredentialsProvider([
463464
'access_key_id' => $credentials->getAccessKeyId(),
@@ -472,7 +473,7 @@ private function removeIllegalV4aHeaders(&$request)
472473
self::AMZ_CONTENT_SHA256_HEADER,
473474
"aws-sdk-invocation-id",
474475
"aws-sdk-retry",
475-
'x-amz-region-set'
476+
'x-amz-region-set',
476477
];
477478
$storedHeaders = [];
478479

@@ -500,17 +501,23 @@ private function CRTRequestFromGuzzleRequest($request)
500501
* @param CredentialsInterface $credentials
501502
* @param RequestInterface $request
502503
* @param $signingService
504+
* @param SigningConfigAWS|null $signingConfig
503505
* @return RequestInterface
504506
*/
505-
protected function signWithV4a(CredentialsInterface $credentials, RequestInterface $request, $signingService)
506-
{
507+
protected function signWithV4a(
508+
CredentialsInterface $credentials,
509+
RequestInterface $request,
510+
$signingService,
511+
SigningConfigAWS $signingConfig = null
512+
){
507513
$this->verifyCRTLoaded();
508-
$credentials_provider = $this->createCRTStaticCredentialsProvider($credentials);
509-
$signingConfig = new SigningConfigAWS([
514+
$signingConfig = $signingConfig ?? new SigningConfigAWS([
510515
'algorithm' => SigningAlgorithm::SIGv4_ASYMMETRIC,
511516
'signature_type' => SignatureType::HTTP_REQUEST_HEADERS,
512-
'credentials_provider' => $credentials_provider,
517+
'credentials_provider' => $this->createCRTStaticCredentialsProvider($credentials),
513518
'signed_body_value' => $this->getPayload($request),
519+
'should_normalize_uri_path' => true,
520+
'use_double_uri_encode' => true,
514521
'region' => "*",
515522
'service' => $signingService,
516523
'date' => time(),

tests/Api/Parser/EventParsingIteratorTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public function testParsedEventsMatchExpectedType($iterator)
125125
$shapeProperty->setAccessible(true);
126126
$shape = $shapeProperty->getValue($iterator);
127127
foreach ($iterator as $event) {
128-
$this->testParsedEventMatchExpectedType($shape, $event);
128+
$this->parsedEventMatchesExpectedType($shape, $event);
129129
}
130130
}
131131

@@ -138,7 +138,7 @@ public function testParsedEventsMatchExpectedType($iterator)
138138
*
139139
* @return void
140140
*/
141-
private function testParsedEventMatchExpectedType($shape, $event)
141+
private function parsedEventMatchesExpectedType($shape, $event)
142142
{
143143
foreach ($event as $key => $value) {
144144
$this->assertTrue($shape->hasMember($key), "Shape has not member with name $key");
@@ -148,7 +148,7 @@ private function testParsedEventMatchExpectedType($shape, $event)
148148
'Shape type "'. $shapeMember->getType(). '" does not match parsed value type "' . gettype($value) . '"'
149149
);
150150
if (is_array($value)) {
151-
$this->testParsedEventMatchExpectedType($shapeMember, $value);
151+
$this->parsedEventMatchesExpectedType($shapeMember, $value);
152152
}
153153
}
154154
}

0 commit comments

Comments
 (0)