summaryrefslogtreecommitdiff
path: root/vendor/aws/aws-sdk-php/src/S3/Crypto/S3EncryptionClient.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/aws/aws-sdk-php/src/S3/Crypto/S3EncryptionClient.php')
-rw-r--r--vendor/aws/aws-sdk-php/src/S3/Crypto/S3EncryptionClient.php340
1 files changed, 340 insertions, 0 deletions
diff --git a/vendor/aws/aws-sdk-php/src/S3/Crypto/S3EncryptionClient.php b/vendor/aws/aws-sdk-php/src/S3/Crypto/S3EncryptionClient.php
new file mode 100644
index 0000000..30b5100
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/S3/Crypto/S3EncryptionClient.php
@@ -0,0 +1,340 @@
+<?php
+namespace Aws\S3\Crypto;
+
+use Aws\Crypto\DecryptionTrait;
+use Aws\HashingStream;
+use Aws\PhpHash;
+use Aws\Crypto\AbstractCryptoClient;
+use Aws\Crypto\EncryptionTrait;
+use Aws\Crypto\MetadataEnvelope;
+use Aws\Crypto\MaterialsProvider;
+use Aws\Crypto\Cipher\CipherBuilderTrait;
+use Aws\S3\S3Client;
+use GuzzleHttp\Promise;
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\Psr7;
+
+/**
+ * Provides a wrapper for an S3Client that supplies functionality to encrypt
+ * data on putObject[Async] calls and decrypt data on getObject[Async] calls.
+ *
+ * Legacy implementation using older encryption workflow.
+ *
+ * AWS strongly recommends the upgrade to the S3EncryptionClientV2 (over the
+ * S3EncryptionClient), as it offers updated data security best practices to our
+ * customers who upgrade. S3EncryptionClientV2 contains breaking changes, so this
+ * will require planning by engineering teams to migrate. New workflows should
+ * just start with S3EncryptionClientV2.
+ *
+ * @deprecated
+ */
+class S3EncryptionClient extends AbstractCryptoClient
+{
+ use CipherBuilderTrait;
+ use CryptoParamsTrait;
+ use DecryptionTrait;
+ use EncryptionTrait;
+ use UserAgentTrait;
+
+ const CRYPTO_VERSION = '1n';
+
+ private $client;
+ private $instructionFileSuffix;
+
+ /**
+ * @param S3Client $client The S3Client to be used for true uploading and
+ * retrieving objects from S3 when using the
+ * encryption client.
+ * @param string|null $instructionFileSuffix Suffix for a client wide
+ * default when using instruction
+ * files for metadata storage.
+ */
+ public function __construct(
+ S3Client $client,
+ $instructionFileSuffix = null
+ ) {
+ $this->appendUserAgent($client, 'feat/s3-encrypt/' . self::CRYPTO_VERSION);
+ $this->client = $client;
+ $this->instructionFileSuffix = $instructionFileSuffix;
+ }
+
+ private static function getDefaultStrategy()
+ {
+ return new HeadersMetadataStrategy();
+ }
+
+ /**
+ * Encrypts the data in the 'Body' field of $args and promises to upload it
+ * to the specified location on S3.
+ *
+ * @param array $args Arguments for encrypting an object and uploading it
+ * to S3 via PutObject.
+ *
+ * The required configuration arguments are as follows:
+ *
+ * - @MaterialsProvider: (MaterialsProvider) Provides Cek, Iv, and Cek
+ * encrypting/decrypting for encryption metadata.
+ * - @CipherOptions: (array) Cipher options for encrypting data. Only the
+ * Cipher option is required. Accepts the following:
+ * - Cipher: (string) cbc|gcm
+ * See also: AbstractCryptoClient::$supportedCiphers. Note that
+ * cbc is deprecated and gcm should be used when possible.
+ * - KeySize: (int) 128|192|256
+ * See also: MaterialsProvider::$supportedKeySizes
+ * - Aad: (string) Additional authentication data. This option is
+ * passed directly to OpenSSL when using gcm. It is ignored when
+ * using cbc. Note if you pass in Aad for gcm encryption, the
+ * PHP SDK will be able to decrypt the resulting object, but other
+ * AWS SDKs may not be able to do so.
+ *
+ * The optional configuration arguments are as follows:
+ *
+ * - @MetadataStrategy: (MetadataStrategy|string|null) Strategy for storing
+ * MetadataEnvelope information. Defaults to using a
+ * HeadersMetadataStrategy. Can either be a class implementing
+ * MetadataStrategy, a class name of a predefined strategy, or empty/null
+ * to default.
+ * - @InstructionFileSuffix: (string|null) Suffix used when writing to an
+ * instruction file if using an InstructionFileMetadataHandler.
+ *
+ * @return PromiseInterface
+ *
+ * @throws \InvalidArgumentException Thrown when arguments above are not
+ * passed or are passed incorrectly.
+ */
+ public function putObjectAsync(array $args)
+ {
+ $provider = $this->getMaterialsProvider($args);
+ unset($args['@MaterialsProvider']);
+
+ $instructionFileSuffix = $this->getInstructionFileSuffix($args);
+ unset($args['@InstructionFileSuffix']);
+
+ $strategy = $this->getMetadataStrategy($args, $instructionFileSuffix);
+ unset($args['@MetadataStrategy']);
+
+ $envelope = new MetadataEnvelope();
+
+ return Promise\Create::promiseFor($this->encrypt(
+ Psr7\Utils::streamFor($args['Body']),
+ $args['@CipherOptions'] ?: [],
+ $provider,
+ $envelope
+ ))->then(
+ function ($encryptedBodyStream) use ($args) {
+ $hash = new PhpHash('sha256');
+ $hashingEncryptedBodyStream = new HashingStream(
+ $encryptedBodyStream,
+ $hash,
+ self::getContentShaDecorator($args)
+ );
+ return [$hashingEncryptedBodyStream, $args];
+ }
+ )->then(
+ function ($putObjectContents) use ($strategy, $envelope) {
+ list($bodyStream, $args) = $putObjectContents;
+ if ($strategy === null) {
+ $strategy = self::getDefaultStrategy();
+ }
+
+ $updatedArgs = $strategy->save($envelope, $args);
+ $updatedArgs['Body'] = $bodyStream;
+ return $updatedArgs;
+ }
+ )->then(
+ function ($args) {
+ unset($args['@CipherOptions']);
+ return $this->client->putObjectAsync($args);
+ }
+ );
+ }
+
+ private static function getContentShaDecorator(&$args)
+ {
+ return function ($hash) use (&$args) {
+ $args['ContentSHA256'] = bin2hex($hash);
+ };
+ }
+
+ /**
+ * Encrypts the data in the 'Body' field of $args and uploads it to the
+ * specified location on S3.
+ *
+ * @param array $args Arguments for encrypting an object and uploading it
+ * to S3 via PutObject.
+ *
+ * The required configuration arguments are as follows:
+ *
+ * - @MaterialsProvider: (MaterialsProvider) Provides Cek, Iv, and Cek
+ * encrypting/decrypting for encryption metadata.
+ * - @CipherOptions: (array) Cipher options for encrypting data. A Cipher
+ * is required. Accepts the following options:
+ * - Cipher: (string) cbc|gcm
+ * See also: AbstractCryptoClient::$supportedCiphers. Note that
+ * cbc is deprecated and gcm should be used when possible.
+ * - KeySize: (int) 128|192|256
+ * See also: MaterialsProvider::$supportedKeySizes
+ * - Aad: (string) Additional authentication data. This option is
+ * passed directly to OpenSSL when using gcm. It is ignored when
+ * using cbc. Note if you pass in Aad for gcm encryption, the
+ * PHP SDK will be able to decrypt the resulting object, but other
+ * AWS SDKs may not be able to do so.
+ *
+ * The optional configuration arguments are as follows:
+ *
+ * - @MetadataStrategy: (MetadataStrategy|string|null) Strategy for storing
+ * MetadataEnvelope information. Defaults to using a
+ * HeadersMetadataStrategy. Can either be a class implementing
+ * MetadataStrategy, a class name of a predefined strategy, or empty/null
+ * to default.
+ * - @InstructionFileSuffix: (string|null) Suffix used when writing to an
+ * instruction file if an using an InstructionFileMetadataHandler was
+ * determined.
+ *
+ * @return \Aws\Result PutObject call result with the details of uploading
+ * the encrypted file.
+ *
+ * @throws \InvalidArgumentException Thrown when arguments above are not
+ * passed or are passed incorrectly.
+ */
+ public function putObject(array $args)
+ {
+ return $this->putObjectAsync($args)->wait();
+ }
+
+ /**
+ * Promises to retrieve an object from S3 and decrypt the data in the
+ * 'Body' field.
+ *
+ * @param array $args Arguments for retrieving an object from S3 via
+ * GetObject and decrypting it.
+ *
+ * The required configuration argument is as follows:
+ *
+ * - @MaterialsProvider: (MaterialsProvider) Provides Cek, Iv, and Cek
+ * encrypting/decrypting for decryption metadata. May have data loaded
+ * from the MetadataEnvelope upon decryption.
+ *
+ * The optional configuration arguments are as follows:
+ *
+ * - SaveAs: (string) The path to a file on disk to save the decrypted
+ * object data. This will be handled by file_put_contents instead of the
+ * Guzzle sink.
+ *
+ * - @MetadataStrategy: (MetadataStrategy|string|null) Strategy for reading
+ * MetadataEnvelope information. Defaults to determining based on object
+ * response headers. Can either be a class implementing MetadataStrategy,
+ * a class name of a predefined strategy, or empty/null to default.
+ * - @InstructionFileSuffix: (string) Suffix used when looking for an
+ * instruction file if an InstructionFileMetadataHandler is being used.
+ * - @CipherOptions: (array) Cipher options for decrypting data. A Cipher
+ * is required. Accepts the following options:
+ * - Aad: (string) Additional authentication data. This option is
+ * passed directly to OpenSSL when using gcm. It is ignored when
+ * using cbc.
+ *
+ * @return PromiseInterface
+ *
+ * @throws \InvalidArgumentException Thrown when required arguments are not
+ * passed or are passed incorrectly.
+ */
+ public function getObjectAsync(array $args)
+ {
+ $provider = $this->getMaterialsProvider($args);
+ unset($args['@MaterialsProvider']);
+
+ $instructionFileSuffix = $this->getInstructionFileSuffix($args);
+ unset($args['@InstructionFileSuffix']);
+
+ $strategy = $this->getMetadataStrategy($args, $instructionFileSuffix);
+ unset($args['@MetadataStrategy']);
+
+ $saveAs = null;
+ if (!empty($args['SaveAs'])) {
+ $saveAs = $args['SaveAs'];
+ }
+
+ $promise = $this->client->getObjectAsync($args)
+ ->then(
+ function ($result) use (
+ $provider,
+ $instructionFileSuffix,
+ $strategy,
+ $args
+ ) {
+ if ($strategy === null) {
+ $strategy = $this->determineGetObjectStrategy(
+ $result,
+ $instructionFileSuffix
+ );
+ }
+
+ $envelope = $strategy->load($args + [
+ 'Metadata' => $result['Metadata']
+ ]);
+
+ $provider = $provider->fromDecryptionEnvelope($envelope);
+
+ $result['Body'] = $this->decrypt(
+ $result['Body'],
+ $provider,
+ $envelope,
+ isset($args['@CipherOptions'])
+ ? $args['@CipherOptions']
+ : []
+ );
+ return $result;
+ }
+ )->then(
+ function ($result) use ($saveAs) {
+ if (!empty($saveAs)) {
+ file_put_contents(
+ $saveAs,
+ (string)$result['Body'],
+ LOCK_EX
+ );
+ }
+ return $result;
+ }
+ );
+
+ return $promise;
+ }
+
+ /**
+ * Retrieves an object from S3 and decrypts the data in the 'Body' field.
+ *
+ * @param array $args Arguments for retrieving an object from S3 via
+ * GetObject and decrypting it.
+ *
+ * The required configuration argument is as follows:
+ *
+ * - @MaterialsProvider: (MaterialsProvider) Provides Cek, Iv, and Cek
+ * encrypting/decrypting for decryption metadata. May have data loaded
+ * from the MetadataEnvelope upon decryption.
+ *
+ * The optional configuration arguments are as follows:
+ *
+ * - SaveAs: (string) The path to a file on disk to save the decrypted
+ * object data. This will be handled by file_put_contents instead of the
+ * Guzzle sink.
+ * - @InstructionFileSuffix: (string|null) Suffix used when looking for an
+ * instruction file if an InstructionFileMetadataHandler was detected.
+ * - @CipherOptions: (array) Cipher options for encrypting data. A Cipher
+ * is required. Accepts the following options:
+ * - Aad: (string) Additional authentication data. This option is
+ * passed directly to OpenSSL when using gcm. It is ignored when
+ * using cbc.
+ *
+ * @return \Aws\Result GetObject call result with the 'Body' field
+ * wrapped in a decryption stream with its metadata
+ * information.
+ *
+ * @throws \InvalidArgumentException Thrown when arguments above are not
+ * passed or are passed incorrectly.
+ */
+ public function getObject(array $args)
+ {
+ return $this->getObjectAsync($args)->wait();
+ }
+}