Conversation
… KMS to provide abstract pieces of MaterialsProvider.
…provided AesStreamInterface based classes.
…strategies for handling a MetadataEnvelope in conjunction with a MaterialsProvider. Supports putObject[Async] and getObject[Async] operations.
Codecov Report
@@ Coverage Diff @@
## master #1395 +/- ##
============================================
- Coverage 91.9% 91.56% -0.34%
- Complexity 2472 2521 +49
============================================
Files 142 156 +14
Lines 7545 7045 -500
============================================
- Hits 6934 6451 -483
+ Misses 611 594 -17
Continue to review full report at Codecov.
|
|
Codecov report of decreased coverage is incorrect. Details show that 95.99% of the diff is covered which is higher than the current 91.90% coverage. |
.travis.yml
Outdated
|
|
||
| after_success: | ||
| - bash <(curl -s https://codecov.io/bash) | ||
| - 'if [ $(phpenv version-name) == "7.1" ]; then bash <(curl -s https://codecov.io/bash); fi' |
There was a problem hiding this comment.
I think this may be to blame for the purported coverage drop. There may be code paths not taken in PHP 7.1
There was a problem hiding this comment.
Yeah, it looks like CodeCov is taking the first report and using that, which explains the wild shifts as well. I'm going to set this up to use 7.1 with latest dependencies only, putting us on stable grounds that we can update with further PHP releases.
| Feature: S3 Client Side Encryption | ||
|
|
||
| Scenario: Upload PHP's GCM encrypted fixtures | ||
| When I get all fixtures for "aes_gcm" from "aws-s3-shared-tests" |
There was a problem hiding this comment.
Is this the name of a particular bucket? Including a resource identifier here seems fragile.
There was a problem hiding this comment.
It is a bucket name and it is fragile. This is how the AWS SDK for Go handles it and we do something similar for the other full integration tests as well. These tests need to talk to other SDKs and don't get a getResourcePrefix added. I'm open to suggestions on this.
There was a problem hiding this comment.
The S3 test should be creating and deleting buckets via BeforeSuite and AfterSuite hooks. I understand that this test suite has to work this way to integrate with other SDK tests, but maybe in the future there could a test that works on multiple accounts.
src/Crypto/EncryptionTrait.php
Outdated
| case 'gcm': | ||
| $cipherOptions['TagLength'] = 16; | ||
|
|
||
| $taggedStream = new AesTaggedGcmEncryptingStream( |
There was a problem hiding this comment.
Couldn't AesTaggedGcmEncryptingStream be removed if you just used an AppendStream here?
src/Crypto/KmsMaterialsProvider.php
Outdated
| @@ -0,0 +1,109 @@ | |||
| <?php | |||
|
|
|||
There was a problem hiding this comment.
Very nit but passim: I believe SDK style requires no newline between the file opener and the namespace declaration.
|
|
||
| return new KmsMaterialsProvider( | ||
| $this->kmsClient, | ||
| $materialsDescription['kms_cmk_id'] |
There was a problem hiding this comment.
What's a cmk? Could abbreviations be avoided in this parameter name, or is the expanded version too long to reasonably type?
There was a problem hiding this comment.
'kms_cmk_id' is how the key is indexed in the materials description, this is consistent with the Java (and other) SDK implementations. The 'KeyId' naming on Encrypt is used for the $kmsKeyId variable.
| */ | ||
| public function save(MetadataEnvelope $envelope, array $args) | ||
| { | ||
| $this->client->putObject([ |
There was a problem hiding this comment.
What if saving this instruction file fails? Is the ciphertext blob deleted from S3?
There was a problem hiding this comment.
The $strategy->save() call is made before the PutObject call for the ciphertext. The instruction file will remain on S3 if there is a failure after it has been uploaded, not automatically deleted. I'll add a note to the guide and update the doc block for this file.
|
|
||
| $envelope = new MetadataEnvelope(); | ||
|
|
||
| return Promise\promise_for($this->encrypt( |
There was a problem hiding this comment.
encrypt isn't returning a promise, is it?
There was a problem hiding this comment.
It is not returning a promise, but an AesStreamInterface. This is why it's the only piece wrapped in the Promise\promise_for call.
There was a problem hiding this comment.
I guess it's more of a style issue, but why does this need to be in an async context at all? With the exception of $this->client->putObjectAsync, this chain of functions seems to be operating synchronously and then returning non-promise values. Wouldn't it be easier to read if it was just iterative statements that returned the promise from putObjectAsync at the end?
There was a problem hiding this comment.
The thought on async basing the manipulation was if someone invokes $s3EncryptionClient->putObjectAsync(), let's defer the heavy lifting that makes up the encryption work and other calls until they are executed. If someone invokes $s3EncryptionClient->putObject(), the work is immediately waited for anyways.
| public function plainTextProvider() { | ||
| return [ | ||
| [Psr7\stream_for('The rain in Spain falls mainly on the plain.')], | ||
| [Psr7\stream_for('دست‌نوشته‌ها نمی‌سوزند')], |
There was a problem hiding this comment.
I believe this is a copy-paste error. IIRC, this case (and the following one) were meant to exercise round-tripping of multibyte characters, e.g.:
[Psr7\stream_for('دستنوشتهها نمیسوزند')],
[Psr7\stream_for('Рукописи не горят')],| $provider = new KmsMaterialsProvider($client, $keyId); | ||
|
|
||
| $this->assertEquals( | ||
| ['kms_cmk_id' => $keyId], |
There was a problem hiding this comment.
From context, I'm guessing that CEK stands for "content encryption key" and CMK stands for "content master key"; why not just use EncryptionKey and MasterKey as the parameter names?
| @@ -0,0 +1,42 @@ | |||
| <?php | |||
|
|
|||
There was a problem hiding this comment.
The test classes should probably be in a namespace corresponding to the directory structure.
cjyclaire
left a comment
There was a problem hiding this comment.
Haven't gone through all yet, post my stashed comments before I forget them : )
src/Crypto/AbstractCryptoClient.php
Outdated
| */ | ||
| abstract class AbstractCryptoClient | ||
| { | ||
| private static $supportedCiphers = [ |
There was a problem hiding this comment.
why a hash? why not a array of supported ciphers?
src/Crypto/AbstractCryptoClient.php
Outdated
| * Dependency to provide an interface for building a decryption stream for | ||
| * cipher text given metadata and materials to do so. | ||
| * | ||
| * @param string $cipherText Plain-text data to be encrypted using the |
There was a problem hiding this comment.
Typo, decrypted text data?
src/S3/Crypto/S3EncryptionClient.php
Outdated
| switch ($args['@MetadataStrategy']) { | ||
| case HeadersMetadataStrategy::class: | ||
| return new HeadersMetadataStrategy(); | ||
| break; |
There was a problem hiding this comment.
Hmmm "return" is sufficient without "break"?
| ); | ||
| } | ||
|
|
||
| return null; |
There was a problem hiding this comment.
Hmm PHP will return null if there is no return
There was a problem hiding this comment.
Yeah, I wanted to be explicit here though since there are other return statements in this function.
src/S3/Crypto/S3EncryptionClient.php
Outdated
| * @throws \InvalidArgumentException Thrown when arguments above are not | ||
| * passed or are passed incorrectly. | ||
| */ | ||
| public function putObjectAsync(array $args) { |
There was a problem hiding this comment.
What's the failed scenario look like? Especially for "getObject"? It will be great if some error scenario (besides invalid arguments) can be tested as well
…ream. Remove object reference from encrypt signature.
| Feature: S3 Client Side Encryption | ||
|
|
||
| Scenario: Upload PHP's GCM encrypted fixtures | ||
| When I get all fixtures for "aes_gcm" from "aws-s3-shared-tests" |
There was a problem hiding this comment.
The S3 test should be creating and deleting buckets via BeforeSuite and AfterSuite hooks. I understand that this test suite has to work this way to integrate with other SDK tests, but maybe in the future there could a test that works on multiple accounts.
Adds the
S3EncryptionClientand supporting implementations. This implements envelope encryption and utilizes OpenSSL to provide CBC and GCM (on PHP >= 7.1) support . Uses pluggable strategies (viaMetadataStrategyInterface) for handling aMetadataEnvelopein conjunction with aMaterialsProvider. AKmsMaterialsProvideris provided for key management . Supports->putObject[Async]and->getObject[Async]operations. This is cross compatible with Java, Ruby, Go, and C++ for the provided feature set. A service guide is also included./cc @jeskew @mtdowling @cjyclaire
Resolves #831