summaryrefslogtreecommitdiff
path: root/vendor/aws/aws-sdk-php/src/Crypto
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2022-11-23 21:14:33 +0300
committerAndrew Dolgov <[email protected]>2022-11-23 21:14:33 +0300
commit0c8af4992cb0f7589dcafaad65ada12753c64594 (patch)
tree18e83d068c3e7dd2499331de977782b382279396 /vendor/aws/aws-sdk-php/src/Crypto
initial
Diffstat (limited to 'vendor/aws/aws-sdk-php/src/Crypto')
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/AbstractCryptoClient.php121
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/AbstractCryptoClientV2.php119
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/AesDecryptingStream.php146
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/AesEncryptingStream.php151
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/AesGcmDecryptingStream.php107
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/AesGcmEncryptingStream.php125
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/AesStreamInterface.php30
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/AesStreamInterfaceV2.php31
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/Cipher/Cbc.php88
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/Cipher/CipherBuilderTrait.php72
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/Cipher/CipherMethod.php59
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/DecryptionTrait.php181
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/DecryptionTraitV2.php249
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/EncryptionTrait.php192
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/EncryptionTraitV2.php196
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/KmsMaterialsProvider.php121
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/KmsMaterialsProviderV2.php100
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/MaterialsProvider.php105
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/MaterialsProviderInterface.php61
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/MaterialsProviderInterfaceV2.php53
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/MaterialsProviderV2.php66
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/MetadataEnvelope.php61
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/MetadataStrategyInterface.php30
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/Polyfill/AesGcm.php228
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/Polyfill/ByteArray.php258
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/Polyfill/Gmac.php223
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/Polyfill/Key.php77
-rw-r--r--vendor/aws/aws-sdk-php/src/Crypto/Polyfill/NeedsTrait.php38
28 files changed, 3288 insertions, 0 deletions
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/AbstractCryptoClient.php b/vendor/aws/aws-sdk-php/src/Crypto/AbstractCryptoClient.php
new file mode 100644
index 0000000..823467b
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/AbstractCryptoClient.php
@@ -0,0 +1,121 @@
+<?php
+namespace Aws\Crypto;
+
+use Aws\Crypto\Cipher\CipherMethod;
+use Aws\Crypto\Cipher\Cbc;
+use GuzzleHttp\Psr7\Stream;
+
+/**
+ * Legacy abstract encryption client. New workflows should use
+ * AbstractCryptoClientV2.
+ *
+ * @deprecated
+ * @internal
+ */
+abstract class AbstractCryptoClient
+{
+ public static $supportedCiphers = ['cbc', 'gcm'];
+
+ public static $supportedKeyWraps = [
+ KmsMaterialsProvider::WRAP_ALGORITHM_NAME
+ ];
+
+ /**
+ * Returns if the passed cipher name is supported for encryption by the SDK.
+ *
+ * @param string $cipherName The name of a cipher to verify is registered.
+ *
+ * @return bool If the cipher passed is in our supported list.
+ */
+ public static function isSupportedCipher($cipherName)
+ {
+ return in_array($cipherName, self::$supportedCiphers);
+ }
+
+ /**
+ * Returns an identifier recognizable by `openssl_*` functions, such as
+ * `aes-256-cbc` or `aes-128-ctr`.
+ *
+ * @param string $cipherName Name of the cipher being used for encrypting
+ * or decrypting.
+ * @param int $keySize Size of the encryption key, in bits, that will be
+ * used.
+ *
+ * @return string
+ */
+ abstract protected function getCipherOpenSslName($cipherName, $keySize);
+
+ /**
+ * Constructs a CipherMethod for the given name, initialized with the other
+ * data passed for use in encrypting or decrypting.
+ *
+ * @param string $cipherName Name of the cipher to generate for encrypting.
+ * @param string $iv Base Initialization Vector for the cipher.
+ * @param int $keySize Size of the encryption key, in bits, that will be
+ * used.
+ *
+ * @return CipherMethod
+ *
+ * @internal
+ */
+ abstract protected function buildCipherMethod($cipherName, $iv, $keySize);
+
+ /**
+ * Performs a reverse lookup to get the openssl_* cipher name from the
+ * AESName passed in from the MetadataEnvelope.
+ *
+ * @param $aesName
+ *
+ * @return string
+ *
+ * @internal
+ */
+ abstract protected function getCipherFromAesName($aesName);
+
+ /**
+ * Dependency to provide an interface for building an encryption stream for
+ * data given cipher details, metadata, and materials to do so.
+ *
+ * @param Stream $plaintext Plain-text data to be encrypted using the
+ * materials, algorithm, and data provided.
+ * @param array $cipherOptions Options for use in determining the cipher to
+ * be used for encrypting data.
+ * @param MaterialsProvider $provider A provider to supply and encrypt
+ * materials used in encryption.
+ * @param MetadataEnvelope $envelope A storage envelope for encryption
+ * metadata to be added to.
+ *
+ * @return AesStreamInterface
+ *
+ * @internal
+ */
+ abstract public function encrypt(
+ Stream $plaintext,
+ array $cipherOptions,
+ MaterialsProvider $provider,
+ MetadataEnvelope $envelope
+ );
+
+ /**
+ * 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 decrypted using the
+ * materials, algorithm, and data provided.
+ * @param MaterialsProviderInterface $provider A provider to supply and encrypt
+ * materials used in encryption.
+ * @param MetadataEnvelope $envelope A storage envelope for encryption
+ * metadata to be read from.
+ * @param array $cipherOptions Additional verification options.
+ *
+ * @return AesStreamInterface
+ *
+ * @internal
+ */
+ abstract public function decrypt(
+ $cipherText,
+ MaterialsProviderInterface $provider,
+ MetadataEnvelope $envelope,
+ array $cipherOptions = []
+ );
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/AbstractCryptoClientV2.php b/vendor/aws/aws-sdk-php/src/Crypto/AbstractCryptoClientV2.php
new file mode 100644
index 0000000..2c7e7c2
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/AbstractCryptoClientV2.php
@@ -0,0 +1,119 @@
+<?php
+namespace Aws\Crypto;
+
+use Aws\Crypto\Cipher\CipherMethod;
+use GuzzleHttp\Psr7\Stream;
+
+/**
+ * @internal
+ */
+abstract class AbstractCryptoClientV2
+{
+ public static $supportedCiphers = ['gcm'];
+
+ public static $supportedKeyWraps = [
+ KmsMaterialsProviderV2::WRAP_ALGORITHM_NAME
+ ];
+
+ public static $supportedSecurityProfiles = ['V2', 'V2_AND_LEGACY'];
+
+ public static $legacySecurityProfiles = ['V2_AND_LEGACY'];
+
+ /**
+ * Returns if the passed cipher name is supported for encryption by the SDK.
+ *
+ * @param string $cipherName The name of a cipher to verify is registered.
+ *
+ * @return bool If the cipher passed is in our supported list.
+ */
+ public static function isSupportedCipher($cipherName)
+ {
+ return in_array($cipherName, self::$supportedCiphers, true);
+ }
+
+ /**
+ * Returns an identifier recognizable by `openssl_*` functions, such as
+ * `aes-256-gcm`
+ *
+ * @param string $cipherName Name of the cipher being used for encrypting
+ * or decrypting.
+ * @param int $keySize Size of the encryption key, in bits, that will be
+ * used.
+ *
+ * @return string
+ */
+ abstract protected function getCipherOpenSslName($cipherName, $keySize);
+
+ /**
+ * Constructs a CipherMethod for the given name, initialized with the other
+ * data passed for use in encrypting or decrypting.
+ *
+ * @param string $cipherName Name of the cipher to generate for encrypting.
+ * @param string $iv Base Initialization Vector for the cipher.
+ * @param int $keySize Size of the encryption key, in bits, that will be
+ * used.
+ *
+ * @return CipherMethod
+ *
+ * @internal
+ */
+ abstract protected function buildCipherMethod($cipherName, $iv, $keySize);
+
+ /**
+ * Performs a reverse lookup to get the openssl_* cipher name from the
+ * AESName passed in from the MetadataEnvelope.
+ *
+ * @param $aesName
+ *
+ * @return string
+ *
+ * @internal
+ */
+ abstract protected function getCipherFromAesName($aesName);
+
+ /**
+ * Dependency to provide an interface for building an encryption stream for
+ * data given cipher details, metadata, and materials to do so.
+ *
+ * @param Stream $plaintext Plain-text data to be encrypted using the
+ * materials, algorithm, and data provided.
+ * @param array $options Options for use in encryption.
+ * @param MaterialsProviderV2 $provider A provider to supply and encrypt
+ * materials used in encryption.
+ * @param MetadataEnvelope $envelope A storage envelope for encryption
+ * metadata to be added to.
+ *
+ * @return AesStreamInterface
+ *
+ * @internal
+ */
+ abstract public function encrypt(
+ Stream $plaintext,
+ array $options,
+ MaterialsProviderV2 $provider,
+ MetadataEnvelope $envelope
+ );
+
+ /**
+ * 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 decrypted using the
+ * materials, algorithm, and data provided.
+ * @param MaterialsProviderInterface $provider A provider to supply and encrypt
+ * materials used in encryption.
+ * @param MetadataEnvelope $envelope A storage envelope for encryption
+ * metadata to be read from.
+ * @param array $options Options used for decryption.
+ *
+ * @return AesStreamInterface
+ *
+ * @internal
+ */
+ abstract public function decrypt(
+ $cipherText,
+ MaterialsProviderInterfaceV2 $provider,
+ MetadataEnvelope $envelope,
+ array $options = []
+ );
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/AesDecryptingStream.php b/vendor/aws/aws-sdk-php/src/Crypto/AesDecryptingStream.php
new file mode 100644
index 0000000..c1524cc
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/AesDecryptingStream.php
@@ -0,0 +1,146 @@
+<?php
+namespace Aws\Crypto;
+
+use GuzzleHttp\Psr7\StreamDecoratorTrait;
+use \LogicException;
+use Psr\Http\Message\StreamInterface;
+use Aws\Crypto\Cipher\CipherMethod;
+
+/**
+ * @internal Represents a stream of data to be decrypted with passed cipher.
+ */
+class AesDecryptingStream implements AesStreamInterface
+{
+ const BLOCK_SIZE = 16; // 128 bits
+
+ use StreamDecoratorTrait;
+
+ /**
+ * @var string
+ */
+ private $buffer = '';
+
+ /**
+ * @var CipherMethod
+ */
+ private $cipherMethod;
+
+ /**
+ * @var string
+ */
+ private $key;
+
+ /**
+ * @var StreamInterface
+ */
+ private $stream;
+
+ /**
+ * @param StreamInterface $cipherText
+ * @param string $key
+ * @param CipherMethod $cipherMethod
+ */
+ public function __construct(
+ StreamInterface $cipherText,
+ $key,
+ CipherMethod $cipherMethod
+ ) {
+ $this->stream = $cipherText;
+ $this->key = $key;
+ $this->cipherMethod = clone $cipherMethod;
+ }
+
+ public function getOpenSslName()
+ {
+ return $this->cipherMethod->getOpenSslName();
+ }
+
+ public function getAesName()
+ {
+ return $this->cipherMethod->getAesName();
+ }
+
+ public function getCurrentIv()
+ {
+ return $this->cipherMethod->getCurrentIv();
+ }
+
+ public function getSize()
+ {
+ $plainTextSize = $this->stream->getSize();
+
+ if ($this->cipherMethod->requiresPadding()) {
+ // PKCS7 padding requires that between 1 and self::BLOCK_SIZE be
+ // added to the plaintext to make it an even number of blocks. The
+ // plaintext is between strlen($cipherText) - self::BLOCK_SIZE and
+ // strlen($cipherText) - 1
+ return null;
+ }
+
+ return $plainTextSize;
+ }
+
+ public function isWritable()
+ {
+ return false;
+ }
+
+ public function read($length)
+ {
+ if ($length > strlen($this->buffer)) {
+ $this->buffer .= $this->decryptBlock(
+ (int) (
+ self::BLOCK_SIZE * ceil(($length - strlen($this->buffer)) / self::BLOCK_SIZE)
+ )
+ );
+ }
+
+ $data = substr($this->buffer, 0, $length);
+ $this->buffer = substr($this->buffer, $length);
+
+ return $data ? $data : '';
+ }
+
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ if ($offset === 0 && $whence === SEEK_SET) {
+ $this->buffer = '';
+ $this->cipherMethod->seek(0, SEEK_SET);
+ $this->stream->seek(0, SEEK_SET);
+ } else {
+ throw new LogicException('AES encryption streams only support being'
+ . ' rewound, not arbitrary seeking.');
+ }
+ }
+
+ private function decryptBlock($length)
+ {
+ if ($this->stream->eof()) {
+ return '';
+ }
+
+ $cipherText = '';
+ do {
+ $cipherText .= $this->stream->read((int) ($length - strlen($cipherText)));
+ } while (strlen($cipherText) < $length && !$this->stream->eof());
+
+ $options = OPENSSL_RAW_DATA;
+ if (!$this->stream->eof()
+ && $this->stream->getSize() !== $this->stream->tell()
+ ) {
+ $options |= OPENSSL_ZERO_PADDING;
+ }
+
+ $plaintext = openssl_decrypt(
+ $cipherText,
+ $this->cipherMethod->getOpenSslName(),
+ $this->key,
+ $options,
+ $this->cipherMethod->getCurrentIv()
+ );
+
+ $this->cipherMethod->update($cipherText);
+
+ return $plaintext;
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/AesEncryptingStream.php b/vendor/aws/aws-sdk-php/src/Crypto/AesEncryptingStream.php
new file mode 100644
index 0000000..3b7c446
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/AesEncryptingStream.php
@@ -0,0 +1,151 @@
+<?php
+namespace Aws\Crypto;
+
+use GuzzleHttp\Psr7\StreamDecoratorTrait;
+use \LogicException;
+use Psr\Http\Message\StreamInterface;
+use Aws\Crypto\Cipher\CipherMethod;
+
+/**
+ * @internal Represents a stream of data to be encrypted with a passed cipher.
+ */
+class AesEncryptingStream implements AesStreamInterface
+{
+ const BLOCK_SIZE = 16; // 128 bits
+
+ use StreamDecoratorTrait;
+
+ /**
+ * @var string
+ */
+ private $buffer = '';
+
+ /**
+ * @var CipherMethod
+ */
+ private $cipherMethod;
+
+ /**
+ * @var string
+ */
+ private $key;
+
+ /**
+ * @var StreamInterface
+ */
+ private $stream;
+
+ /**
+ * @param StreamInterface $plainText
+ * @param string $key
+ * @param CipherMethod $cipherMethod
+ */
+ public function __construct(
+ StreamInterface $plainText,
+ $key,
+ CipherMethod $cipherMethod
+ ) {
+ $this->stream = $plainText;
+ $this->key = $key;
+ $this->cipherMethod = clone $cipherMethod;
+ }
+
+ public function getOpenSslName()
+ {
+ return $this->cipherMethod->getOpenSslName();
+ }
+
+ public function getAesName()
+ {
+ return $this->cipherMethod->getAesName();
+ }
+
+ public function getCurrentIv()
+ {
+ return $this->cipherMethod->getCurrentIv();
+ }
+
+ public function getSize()
+ {
+ $plainTextSize = $this->stream->getSize();
+
+ if ($this->cipherMethod->requiresPadding() && $plainTextSize !== null) {
+ // PKCS7 padding requires that between 1 and self::BLOCK_SIZE be
+ // added to the plaintext to make it an even number of blocks.
+ $padding = self::BLOCK_SIZE - $plainTextSize % self::BLOCK_SIZE;
+ return $plainTextSize + $padding;
+ }
+
+ return $plainTextSize;
+ }
+
+ public function isWritable()
+ {
+ return false;
+ }
+
+ public function read($length)
+ {
+ if ($length > strlen($this->buffer)) {
+ $this->buffer .= $this->encryptBlock(
+ (int)
+ self::BLOCK_SIZE * ceil(($length - strlen($this->buffer)) / self::BLOCK_SIZE)
+ );
+ }
+
+ $data = substr($this->buffer, 0, $length);
+ $this->buffer = substr($this->buffer, $length);
+
+ return $data ? $data : '';
+ }
+
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ if ($whence === SEEK_CUR) {
+ $offset = $this->tell() + $offset;
+ $whence = SEEK_SET;
+ }
+
+ if ($whence === SEEK_SET) {
+ $this->buffer = '';
+ $wholeBlockOffset
+ = (int) ($offset / self::BLOCK_SIZE) * self::BLOCK_SIZE;
+ $this->stream->seek($wholeBlockOffset);
+ $this->cipherMethod->seek($wholeBlockOffset);
+ $this->read($offset - $wholeBlockOffset);
+ } else {
+ throw new LogicException('Unrecognized whence.');
+ }
+ }
+
+ private function encryptBlock($length)
+ {
+ if ($this->stream->eof()) {
+ return '';
+ }
+
+ $plainText = '';
+ do {
+ $plainText .= $this->stream->read((int) ($length - strlen($plainText)));
+ } while (strlen($plainText) < $length && !$this->stream->eof());
+
+ $options = OPENSSL_RAW_DATA;
+ if (!$this->stream->eof()
+ || $this->stream->getSize() !== $this->stream->tell()
+ ) {
+ $options |= OPENSSL_ZERO_PADDING;
+ }
+
+ $cipherText = openssl_encrypt(
+ $plainText,
+ $this->cipherMethod->getOpenSslName(),
+ $this->key,
+ $options,
+ $this->cipherMethod->getCurrentIv()
+ );
+
+ $this->cipherMethod->update($cipherText);
+
+ return $cipherText;
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/AesGcmDecryptingStream.php b/vendor/aws/aws-sdk-php/src/Crypto/AesGcmDecryptingStream.php
new file mode 100644
index 0000000..76feaa1
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/AesGcmDecryptingStream.php
@@ -0,0 +1,107 @@
+<?php
+namespace Aws\Crypto;
+
+use Aws\Exception\CryptoException;
+use GuzzleHttp\Psr7;
+use GuzzleHttp\Psr7\StreamDecoratorTrait;
+use Psr\Http\Message\StreamInterface;
+use Aws\Crypto\Polyfill\AesGcm;
+use Aws\Crypto\Polyfill\Key;
+
+/**
+ * @internal Represents a stream of data to be gcm decrypted.
+ */
+class AesGcmDecryptingStream implements AesStreamInterface
+{
+ use StreamDecoratorTrait;
+
+ private $aad;
+
+ private $initializationVector;
+
+ private $key;
+
+ private $keySize;
+
+ private $cipherText;
+
+ private $tag;
+
+ private $tagLength;
+
+ /**
+ * @param StreamInterface $cipherText
+ * @param string $key
+ * @param string $initializationVector
+ * @param string $tag
+ * @param string $aad
+ * @param int $tagLength
+ * @param int $keySize
+ */
+ public function __construct(
+ StreamInterface $cipherText,
+ $key,
+ $initializationVector,
+ $tag,
+ $aad = '',
+ $tagLength = 128,
+ $keySize = 256
+ ) {
+ $this->cipherText = $cipherText;
+ $this->key = $key;
+ $this->initializationVector = $initializationVector;
+ $this->tag = $tag;
+ $this->aad = $aad;
+ $this->tagLength = $tagLength;
+ $this->keySize = $keySize;
+ }
+
+ public function getOpenSslName()
+ {
+ return "aes-{$this->keySize}-gcm";
+ }
+
+ public function getAesName()
+ {
+ return 'AES/GCM/NoPadding';
+ }
+
+ public function getCurrentIv()
+ {
+ return $this->initializationVector;
+ }
+
+ public function createStream()
+ {
+ if (version_compare(PHP_VERSION, '7.1', '<')) {
+ return Psr7\Utils::streamFor(AesGcm::decrypt(
+ (string) $this->cipherText,
+ $this->initializationVector,
+ new Key($this->key),
+ $this->aad,
+ $this->tag,
+ $this->keySize
+ ));
+ } else {
+ $result = \openssl_decrypt(
+ (string)$this->cipherText,
+ $this->getOpenSslName(),
+ $this->key,
+ OPENSSL_RAW_DATA,
+ $this->initializationVector,
+ $this->tag,
+ $this->aad
+ );
+ if ($result === false) {
+ throw new CryptoException('The requested object could not be'
+ . ' decrypted due to an invalid authentication tag.');
+ }
+ return Psr7\Utils::streamFor($result);
+ }
+ }
+
+ public function isWritable()
+ {
+ return false;
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/AesGcmEncryptingStream.php b/vendor/aws/aws-sdk-php/src/Crypto/AesGcmEncryptingStream.php
new file mode 100644
index 0000000..13357f5
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/AesGcmEncryptingStream.php
@@ -0,0 +1,125 @@
+<?php
+namespace Aws\Crypto;
+
+use Aws\Crypto\Polyfill\AesGcm;
+use Aws\Crypto\Polyfill\Key;
+use GuzzleHttp\Psr7;
+use GuzzleHttp\Psr7\StreamDecoratorTrait;
+use Psr\Http\Message\StreamInterface;
+use \RuntimeException;
+
+/**
+ * @internal Represents a stream of data to be gcm encrypted.
+ */
+class AesGcmEncryptingStream implements AesStreamInterface, AesStreamInterfaceV2
+{
+ use StreamDecoratorTrait;
+
+ private $aad;
+
+ private $initializationVector;
+
+ private $key;
+
+ private $keySize;
+
+ private $plaintext;
+
+ private $tag = '';
+
+ private $tagLength;
+
+ /**
+ * Same as non-static 'getAesName' method, allowing calls in a static
+ * context.
+ *
+ * @return string
+ */
+ public static function getStaticAesName()
+ {
+ return 'AES/GCM/NoPadding';
+ }
+
+ /**
+ * @param StreamInterface $plaintext
+ * @param string $key
+ * @param string $initializationVector
+ * @param string $aad
+ * @param int $tagLength
+ * @param int $keySize
+ */
+ public function __construct(
+ StreamInterface $plaintext,
+ $key,
+ $initializationVector,
+ $aad = '',
+ $tagLength = 16,
+ $keySize = 256
+ ) {
+
+ $this->plaintext = $plaintext;
+ $this->key = $key;
+ $this->initializationVector = $initializationVector;
+ $this->aad = $aad;
+ $this->tagLength = $tagLength;
+ $this->keySize = $keySize;
+ }
+
+ public function getOpenSslName()
+ {
+ return "aes-{$this->keySize}-gcm";
+ }
+
+ /**
+ * Same as static method and retained for backwards compatibility
+ *
+ * @return string
+ */
+ public function getAesName()
+ {
+ return self::getStaticAesName();
+ }
+
+ public function getCurrentIv()
+ {
+ return $this->initializationVector;
+ }
+
+ public function createStream()
+ {
+ if (version_compare(PHP_VERSION, '7.1', '<')) {
+ return Psr7\Utils::streamFor(AesGcm::encrypt(
+ (string) $this->plaintext,
+ $this->initializationVector,
+ new Key($this->key),
+ $this->aad,
+ $this->tag,
+ $this->keySize
+ ));
+ } else {
+ return Psr7\Utils::streamFor(\openssl_encrypt(
+ (string)$this->plaintext,
+ $this->getOpenSslName(),
+ $this->key,
+ OPENSSL_RAW_DATA,
+ $this->initializationVector,
+ $this->tag,
+ $this->aad,
+ $this->tagLength
+ ));
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function getTag()
+ {
+ return $this->tag;
+ }
+
+ public function isWritable()
+ {
+ return false;
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/AesStreamInterface.php b/vendor/aws/aws-sdk-php/src/Crypto/AesStreamInterface.php
new file mode 100644
index 0000000..ce7b85d
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/AesStreamInterface.php
@@ -0,0 +1,30 @@
+<?php
+namespace Aws\Crypto;
+
+use Psr\Http\Message\StreamInterface;
+
+interface AesStreamInterface extends StreamInterface
+{
+ /**
+ * Returns an identifier recognizable by `openssl_*` functions, such as
+ * `aes-256-cbc` or `aes-128-ctr`.
+ *
+ * @return string
+ */
+ public function getOpenSslName();
+
+ /**
+ * Returns an AES recognizable name, such as 'AES/GCM/NoPadding'.
+ *
+ * @return string
+ */
+ public function getAesName();
+
+ /**
+ * Returns the IV that should be used to initialize the next block in
+ * encrypt or decrypt.
+ *
+ * @return string
+ */
+ public function getCurrentIv();
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/AesStreamInterfaceV2.php b/vendor/aws/aws-sdk-php/src/Crypto/AesStreamInterfaceV2.php
new file mode 100644
index 0000000..4bd2d46
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/AesStreamInterfaceV2.php
@@ -0,0 +1,31 @@
+<?php
+namespace Aws\Crypto;
+
+use Psr\Http\Message\StreamInterface;
+
+interface AesStreamInterfaceV2 extends StreamInterface
+{
+ /**
+ * Returns an AES recognizable name, such as 'AES/GCM/NoPadding'. V2
+ * interface is accessible from a static context.
+ *
+ * @return string
+ */
+ public static function getStaticAesName();
+
+ /**
+ * Returns an identifier recognizable by `openssl_*` functions, such as
+ * `aes-256-cbc` or `aes-128-ctr`.
+ *
+ * @return string
+ */
+ public function getOpenSslName();
+
+ /**
+ * Returns the IV that should be used to initialize the next block in
+ * encrypt or decrypt.
+ *
+ * @return string
+ */
+ public function getCurrentIv();
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/Cipher/Cbc.php b/vendor/aws/aws-sdk-php/src/Crypto/Cipher/Cbc.php
new file mode 100644
index 0000000..926f87c
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/Cipher/Cbc.php
@@ -0,0 +1,88 @@
+<?php
+namespace Aws\Crypto\Cipher;
+
+use \InvalidArgumentException;
+use \LogicException;
+
+/**
+ * An implementation of the CBC cipher for use with an AesEncryptingStream or
+ * AesDecrypting stream.
+ *
+ * This cipher method is deprecated and in maintenance mode - no new updates will be
+ * released. Please see https://docs.aws.amazon.com/general/latest/gr/aws_sdk_cryptography.html
+ * for more information.
+ *
+ * @deprecated
+ */
+class Cbc implements CipherMethod
+{
+ const BLOCK_SIZE = 16;
+
+ /**
+ * @var string
+ */
+ private $baseIv;
+
+ /**
+ * @var string
+ */
+ private $iv;
+
+ /**
+ * @var int
+ */
+ private $keySize;
+
+ /**
+ * @param string $iv Base Initialization Vector for the cipher.
+ * @param int $keySize Size of the encryption key, in bits, that will be
+ * used.
+ *
+ * @throws InvalidArgumentException Thrown if the passed iv does not match
+ * the iv length required by the cipher.
+ */
+ public function __construct($iv, $keySize = 256)
+ {
+ $this->baseIv = $this->iv = $iv;
+ $this->keySize = $keySize;
+
+ if (strlen($iv) !== openssl_cipher_iv_length($this->getOpenSslName())) {
+ throw new InvalidArgumentException('Invalid initialization vector');
+ }
+ }
+
+ public function getOpenSslName()
+ {
+ return "aes-{$this->keySize}-cbc";
+ }
+
+ public function getAesName()
+ {
+ return 'AES/CBC/PKCS5Padding';
+ }
+
+ public function getCurrentIv()
+ {
+ return $this->iv;
+ }
+
+ public function requiresPadding()
+ {
+ return true;
+ }
+
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ if ($offset === 0 && $whence === SEEK_SET) {
+ $this->iv = $this->baseIv;
+ } else {
+ throw new LogicException('CBC initialization only support being'
+ . ' rewound, not arbitrary seeking.');
+ }
+ }
+
+ public function update($cipherTextBlock)
+ {
+ $this->iv = substr($cipherTextBlock, self::BLOCK_SIZE * -1);
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/Cipher/CipherBuilderTrait.php b/vendor/aws/aws-sdk-php/src/Crypto/Cipher/CipherBuilderTrait.php
new file mode 100644
index 0000000..ed9feb9
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/Cipher/CipherBuilderTrait.php
@@ -0,0 +1,72 @@
+<?php
+namespace Aws\Crypto\Cipher;
+
+use Aws\Exception\CryptoException;
+
+trait CipherBuilderTrait
+{
+ /**
+ * Returns an identifier recognizable by `openssl_*` functions, such as
+ * `aes-256-cbc` or `aes-128-ctr`.
+ *
+ * @param string $cipherName Name of the cipher being used for encrypting
+ * or decrypting.
+ * @param int $keySize Size of the encryption key, in bits, that will be
+ * used.
+ *
+ * @return string
+ */
+ protected function getCipherOpenSslName($cipherName, $keySize)
+ {
+ return "aes-{$keySize}-{$cipherName}";
+ }
+
+ /**
+ * Constructs a CipherMethod for the given name, initialized with the other
+ * data passed for use in encrypting or decrypting.
+ *
+ * @param string $cipherName Name of the cipher to generate for encrypting.
+ * @param string $iv Base Initialization Vector for the cipher.
+ * @param int $keySize Size of the encryption key, in bits, that will be
+ * used.
+ *
+ * @return CipherMethod
+ *
+ * @internal
+ */
+ protected function buildCipherMethod($cipherName, $iv, $keySize)
+ {
+ switch ($cipherName) {
+ case 'cbc':
+ return new Cbc(
+ $iv,
+ $keySize
+ );
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Performs a reverse lookup to get the openssl_* cipher name from the
+ * AESName passed in from the MetadataEnvelope.
+ *
+ * @param $aesName
+ *
+ * @return string
+ *
+ * @internal
+ */
+ protected function getCipherFromAesName($aesName)
+ {
+ switch ($aesName) {
+ case 'AES/GCM/NoPadding':
+ return 'gcm';
+ case 'AES/CBC/PKCS5Padding':
+ return 'cbc';
+ default:
+ throw new CryptoException('Unrecognized or unsupported'
+ . ' AESName for reverse lookup.');
+ }
+ }
+} \ No newline at end of file
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/Cipher/CipherMethod.php b/vendor/aws/aws-sdk-php/src/Crypto/Cipher/CipherMethod.php
new file mode 100644
index 0000000..a99aaa7
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/Cipher/CipherMethod.php
@@ -0,0 +1,59 @@
+<?php
+namespace Aws\Crypto\Cipher;
+
+interface CipherMethod
+{
+ /**
+ * Returns an identifier recognizable by `openssl_*` functions, such as
+ * `aes-256-cbc` or `aes-128-ctr`.
+ *
+ * @return string
+ */
+ public function getOpenSslName();
+
+ /**
+ * Returns an AES recognizable name, such as 'AES/GCM/NoPadding'.
+ *
+ * @return string
+ */
+ public function getAesName();
+
+ /**
+ * Returns the IV that should be used to initialize the next block in
+ * encrypt or decrypt.
+ *
+ * @return string
+ */
+ public function getCurrentIv();
+
+ /**
+ * Indicates whether the cipher method used with this IV requires padding
+ * the final block to make sure the plaintext is evenly divisible by the
+ * block size.
+ *
+ * @return boolean
+ */
+ public function requiresPadding();
+
+ /**
+ * Adjust the return of this::getCurrentIv to reflect a seek performed on
+ * the encryption stream using this IV object.
+ *
+ * @param int $offset
+ * @param int $whence
+ *
+ * @throws LogicException Thrown if the requested seek is not supported by
+ * this IV implementation. For example, a CBC IV
+ * only supports a full rewind ($offset === 0 &&
+ * $whence === SEEK_SET)
+ */
+ public function seek($offset, $whence = SEEK_SET);
+
+ /**
+ * Take account of the last cipher text block to adjust the return of
+ * this::getCurrentIv
+ *
+ * @param string $cipherTextBlock
+ */
+ public function update($cipherTextBlock);
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/DecryptionTrait.php b/vendor/aws/aws-sdk-php/src/Crypto/DecryptionTrait.php
new file mode 100644
index 0000000..7aa1a9a
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/DecryptionTrait.php
@@ -0,0 +1,181 @@
+<?php
+namespace Aws\Crypto;
+
+use GuzzleHttp\Psr7;
+use GuzzleHttp\Psr7\LimitStream;
+use Psr\Http\Message\StreamInterface;
+
+trait DecryptionTrait
+{
+ /**
+ * Dependency to reverse lookup the openssl_* cipher name from the AESName
+ * in the MetadataEnvelope.
+ *
+ * @param $aesName
+ *
+ * @return string
+ *
+ * @internal
+ */
+ abstract protected function getCipherFromAesName($aesName);
+
+ /**
+ * Dependency to generate a CipherMethod from a set of inputs for loading
+ * in to an AesDecryptingStream.
+ *
+ * @param string $cipherName Name of the cipher to generate for decrypting.
+ * @param string $iv Base Initialization Vector for the cipher.
+ * @param int $keySize Size of the encryption key, in bits, that will be
+ * used.
+ *
+ * @return Cipher\CipherMethod
+ *
+ * @internal
+ */
+ abstract protected function buildCipherMethod($cipherName, $iv, $keySize);
+
+ /**
+ * Builds an AesStreamInterface using cipher options loaded from the
+ * MetadataEnvelope and MaterialsProvider. Can decrypt data from both the
+ * legacy and V2 encryption client workflows.
+ *
+ * @param string $cipherText Plain-text data to be encrypted using the
+ * materials, algorithm, and data provided.
+ * @param MaterialsProviderInterface $provider A provider to supply and encrypt
+ * materials used in encryption.
+ * @param MetadataEnvelope $envelope A storage envelope for encryption
+ * metadata to be read from.
+ * @param array $cipherOptions Additional verification options.
+ *
+ * @return AesStreamInterface
+ *
+ * @throws \InvalidArgumentException Thrown when a value in $cipherOptions
+ * is not valid.
+ *
+ * @internal
+ */
+ public function decrypt(
+ $cipherText,
+ MaterialsProviderInterface $provider,
+ MetadataEnvelope $envelope,
+ array $cipherOptions = []
+ ) {
+ $cipherOptions['Iv'] = base64_decode(
+ $envelope[MetadataEnvelope::IV_HEADER]
+ );
+
+ $cipherOptions['TagLength'] =
+ $envelope[MetadataEnvelope::CRYPTO_TAG_LENGTH_HEADER] / 8;
+
+ $cek = $provider->decryptCek(
+ base64_decode(
+ $envelope[MetadataEnvelope::CONTENT_KEY_V2_HEADER]
+ ),
+ json_decode(
+ $envelope[MetadataEnvelope::MATERIALS_DESCRIPTION_HEADER],
+ true
+ )
+ );
+ $cipherOptions['KeySize'] = strlen($cek) * 8;
+ $cipherOptions['Cipher'] = $this->getCipherFromAesName(
+ $envelope[MetadataEnvelope::CONTENT_CRYPTO_SCHEME_HEADER]
+ );
+
+ $decryptionStream = $this->getDecryptingStream(
+ $cipherText,
+ $cek,
+ $cipherOptions
+ );
+ unset($cek);
+
+ return $decryptionStream;
+ }
+
+ private function getTagFromCiphertextStream(
+ StreamInterface $cipherText,
+ $tagLength
+ ) {
+ $cipherTextSize = $cipherText->getSize();
+ if ($cipherTextSize == null || $cipherTextSize <= 0) {
+ throw new \RuntimeException('Cannot decrypt a stream of unknown'
+ . ' size.');
+ }
+ return (string) new LimitStream(
+ $cipherText,
+ $tagLength,
+ $cipherTextSize - $tagLength
+ );
+ }
+
+ private function getStrippedCiphertextStream(
+ StreamInterface $cipherText,
+ $tagLength
+ ) {
+ $cipherTextSize = $cipherText->getSize();
+ if ($cipherTextSize == null || $cipherTextSize <= 0) {
+ throw new \RuntimeException('Cannot decrypt a stream of unknown'
+ . ' size.');
+ }
+ return new LimitStream(
+ $cipherText,
+ $cipherTextSize - $tagLength,
+ 0
+ );
+ }
+
+ /**
+ * Generates a stream that wraps the cipher text with the proper cipher and
+ * uses the content encryption key (CEK) to decrypt the data when read.
+ *
+ * @param string $cipherText Plain-text data to be encrypted using the
+ * materials, algorithm, and data provided.
+ * @param string $cek A content encryption key for use by the stream for
+ * encrypting the plaintext data.
+ * @param array $cipherOptions Options for use in determining the cipher to
+ * be used for encrypting data.
+ *
+ * @return AesStreamInterface
+ *
+ * @internal
+ */
+ protected function getDecryptingStream(
+ $cipherText,
+ $cek,
+ $cipherOptions
+ ) {
+ $cipherTextStream = Psr7\Utils::streamFor($cipherText);
+ switch ($cipherOptions['Cipher']) {
+ case 'gcm':
+ $cipherOptions['Tag'] = $this->getTagFromCiphertextStream(
+ $cipherTextStream,
+ $cipherOptions['TagLength']
+ );
+
+ return new AesGcmDecryptingStream(
+ $this->getStrippedCiphertextStream(
+ $cipherTextStream,
+ $cipherOptions['TagLength']
+ ),
+ $cek,
+ $cipherOptions['Iv'],
+ $cipherOptions['Tag'],
+ $cipherOptions['Aad'] = isset($cipherOptions['Aad'])
+ ? $cipherOptions['Aad']
+ : null,
+ $cipherOptions['TagLength'] ?: null,
+ $cipherOptions['KeySize']
+ );
+ default:
+ $cipherMethod = $this->buildCipherMethod(
+ $cipherOptions['Cipher'],
+ $cipherOptions['Iv'],
+ $cipherOptions['KeySize']
+ );
+ return new AesDecryptingStream(
+ $cipherTextStream,
+ $cek,
+ $cipherMethod
+ );
+ }
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/DecryptionTraitV2.php b/vendor/aws/aws-sdk-php/src/Crypto/DecryptionTraitV2.php
new file mode 100644
index 0000000..800319d
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/DecryptionTraitV2.php
@@ -0,0 +1,249 @@
+<?php
+namespace Aws\Crypto;
+
+use Aws\Exception\CryptoException;
+use GuzzleHttp\Psr7;
+use GuzzleHttp\Psr7\LimitStream;
+use Psr\Http\Message\StreamInterface;
+
+trait DecryptionTraitV2
+{
+ /**
+ * Dependency to reverse lookup the openssl_* cipher name from the AESName
+ * in the MetadataEnvelope.
+ *
+ * @param $aesName
+ *
+ * @return string
+ *
+ * @internal
+ */
+ abstract protected function getCipherFromAesName($aesName);
+
+ /**
+ * Dependency to generate a CipherMethod from a set of inputs for loading
+ * in to an AesDecryptingStream.
+ *
+ * @param string $cipherName Name of the cipher to generate for decrypting.
+ * @param string $iv Base Initialization Vector for the cipher.
+ * @param int $keySize Size of the encryption key, in bits, that will be
+ * used.
+ *
+ * @return Cipher\CipherMethod
+ *
+ * @internal
+ */
+ abstract protected function buildCipherMethod($cipherName, $iv, $keySize);
+
+ /**
+ * Builds an AesStreamInterface using cipher options loaded from the
+ * MetadataEnvelope and MaterialsProvider. Can decrypt data from both the
+ * legacy and V2 encryption client workflows.
+ *
+ * @param string $cipherText Plain-text data to be encrypted using the
+ * materials, algorithm, and data provided.
+ * @param MaterialsProviderInterfaceV2 $provider A provider to supply and encrypt
+ * materials used in encryption.
+ * @param MetadataEnvelope $envelope A storage envelope for encryption
+ * metadata to be read from.
+ * @param array $options Options used for decryption.
+ *
+ * @return AesStreamInterface
+ *
+ * @throws \InvalidArgumentException Thrown when a value in $cipherOptions
+ * is not valid.
+ *
+ * @internal
+ */
+ public function decrypt(
+ $cipherText,
+ MaterialsProviderInterfaceV2 $provider,
+ MetadataEnvelope $envelope,
+ array $options = []
+ ) {
+ $options['@CipherOptions'] = !empty($options['@CipherOptions'])
+ ? $options['@CipherOptions']
+ : [];
+ $options['@CipherOptions']['Iv'] = base64_decode(
+ $envelope[MetadataEnvelope::IV_HEADER]
+ );
+
+ $options['@CipherOptions']['TagLength'] =
+ $envelope[MetadataEnvelope::CRYPTO_TAG_LENGTH_HEADER] / 8;
+
+ $cek = $provider->decryptCek(
+ base64_decode(
+ $envelope[MetadataEnvelope::CONTENT_KEY_V2_HEADER]
+ ),
+ json_decode(
+ $envelope[MetadataEnvelope::MATERIALS_DESCRIPTION_HEADER],
+ true
+ ),
+ $options
+ );
+ $options['@CipherOptions']['KeySize'] = strlen($cek) * 8;
+ $options['@CipherOptions']['Cipher'] = $this->getCipherFromAesName(
+ $envelope[MetadataEnvelope::CONTENT_CRYPTO_SCHEME_HEADER]
+ );
+
+ $this->validateOptionsAndEnvelope($options, $envelope);
+
+ $decryptionStream = $this->getDecryptingStream(
+ $cipherText,
+ $cek,
+ $options['@CipherOptions']
+ );
+ unset($cek);
+
+ return $decryptionStream;
+ }
+
+ private function getTagFromCiphertextStream(
+ StreamInterface $cipherText,
+ $tagLength
+ ) {
+ $cipherTextSize = $cipherText->getSize();
+ if ($cipherTextSize == null || $cipherTextSize <= 0) {
+ throw new \RuntimeException('Cannot decrypt a stream of unknown'
+ . ' size.');
+ }
+ return (string) new LimitStream(
+ $cipherText,
+ $tagLength,
+ $cipherTextSize - $tagLength
+ );
+ }
+
+ private function getStrippedCiphertextStream(
+ StreamInterface $cipherText,
+ $tagLength
+ ) {
+ $cipherTextSize = $cipherText->getSize();
+ if ($cipherTextSize == null || $cipherTextSize <= 0) {
+ throw new \RuntimeException('Cannot decrypt a stream of unknown'
+ . ' size.');
+ }
+ return new LimitStream(
+ $cipherText,
+ $cipherTextSize - $tagLength,
+ 0
+ );
+ }
+
+ private function validateOptionsAndEnvelope($options, $envelope)
+ {
+ $allowedCiphers = AbstractCryptoClientV2::$supportedCiphers;
+ $allowedKeywraps = AbstractCryptoClientV2::$supportedKeyWraps;
+ if ($options['@SecurityProfile'] == 'V2_AND_LEGACY') {
+ $allowedCiphers = array_unique(array_merge(
+ $allowedCiphers,
+ AbstractCryptoClient::$supportedCiphers
+ ));
+ $allowedKeywraps = array_unique(array_merge(
+ $allowedKeywraps,
+ AbstractCryptoClient::$supportedKeyWraps
+ ));
+ }
+
+ $v1SchemaException = new CryptoException("The requested object is encrypted"
+ . " with V1 encryption schemas that have been disabled by"
+ . " client configuration @SecurityProfile=V2. Retry with"
+ . " V2_AND_LEGACY enabled or reencrypt the object.");
+
+ if (!in_array($options['@CipherOptions']['Cipher'], $allowedCiphers)) {
+ if (in_array($options['@CipherOptions']['Cipher'], AbstractCryptoClient::$supportedCiphers)) {
+ throw $v1SchemaException;
+ }
+ throw new CryptoException("The requested object is encrypted with"
+ . " the cipher '{$options['@CipherOptions']['Cipher']}', which is not"
+ . " supported for decryption with the selected security profile."
+ . " This profile allows decryption with: "
+ . implode(", ", $allowedCiphers));
+ }
+ if (!in_array(
+ $envelope[MetadataEnvelope::KEY_WRAP_ALGORITHM_HEADER],
+ $allowedKeywraps
+ )) {
+ if (in_array(
+ $envelope[MetadataEnvelope::KEY_WRAP_ALGORITHM_HEADER],
+ AbstractCryptoClient::$supportedKeyWraps)
+ ) {
+ throw $v1SchemaException;
+ }
+ throw new CryptoException("The requested object is encrypted with"
+ . " the keywrap schema '{$envelope[MetadataEnvelope::KEY_WRAP_ALGORITHM_HEADER]}',"
+ . " which is not supported for decryption with the current security"
+ . " profile.");
+ }
+
+ $matdesc = json_decode(
+ $envelope[MetadataEnvelope::MATERIALS_DESCRIPTION_HEADER],
+ true
+ );
+ if (isset($matdesc['aws:x-amz-cek-alg'])
+ && $envelope[MetadataEnvelope::CONTENT_CRYPTO_SCHEME_HEADER] !==
+ $matdesc['aws:x-amz-cek-alg']
+ ) {
+ throw new CryptoException("There is a mismatch in specified content"
+ . " encryption algrithm between the materials description value"
+ . " and the metadata envelope value: {$matdesc['aws:x-amz-cek-alg']}"
+ . " vs. {$envelope[MetadataEnvelope::CONTENT_CRYPTO_SCHEME_HEADER]}.");
+ }
+ }
+
+ /**
+ * Generates a stream that wraps the cipher text with the proper cipher and
+ * uses the content encryption key (CEK) to decrypt the data when read.
+ *
+ * @param string $cipherText Plain-text data to be encrypted using the
+ * materials, algorithm, and data provided.
+ * @param string $cek A content encryption key for use by the stream for
+ * encrypting the plaintext data.
+ * @param array $cipherOptions Options for use in determining the cipher to
+ * be used for encrypting data.
+ *
+ * @return AesStreamInterface
+ *
+ * @internal
+ */
+ protected function getDecryptingStream(
+ $cipherText,
+ $cek,
+ $cipherOptions
+ ) {
+ $cipherTextStream = Psr7\Utils::streamFor($cipherText);
+ switch ($cipherOptions['Cipher']) {
+ case 'gcm':
+ $cipherOptions['Tag'] = $this->getTagFromCiphertextStream(
+ $cipherTextStream,
+ $cipherOptions['TagLength']
+ );
+
+ return new AesGcmDecryptingStream(
+ $this->getStrippedCiphertextStream(
+ $cipherTextStream,
+ $cipherOptions['TagLength']
+ ),
+ $cek,
+ $cipherOptions['Iv'],
+ $cipherOptions['Tag'],
+ $cipherOptions['Aad'] = isset($cipherOptions['Aad'])
+ ? $cipherOptions['Aad']
+ : null,
+ $cipherOptions['TagLength'] ?: null,
+ $cipherOptions['KeySize']
+ );
+ default:
+ $cipherMethod = $this->buildCipherMethod(
+ $cipherOptions['Cipher'],
+ $cipherOptions['Iv'],
+ $cipherOptions['KeySize']
+ );
+ return new AesDecryptingStream(
+ $cipherTextStream,
+ $cek,
+ $cipherMethod
+ );
+ }
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/EncryptionTrait.php b/vendor/aws/aws-sdk-php/src/Crypto/EncryptionTrait.php
new file mode 100644
index 0000000..f6d1b7d
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/EncryptionTrait.php
@@ -0,0 +1,192 @@
+<?php
+namespace Aws\Crypto;
+
+use GuzzleHttp\Psr7;
+use GuzzleHttp\Psr7\AppendStream;
+use GuzzleHttp\Psr7\Stream;
+
+trait EncryptionTrait
+{
+ private static $allowedOptions = [
+ 'Cipher' => true,
+ 'KeySize' => true,
+ 'Aad' => true,
+ ];
+
+ /**
+ * Dependency to generate a CipherMethod from a set of inputs for loading
+ * in to an AesEncryptingStream.
+ *
+ * @param string $cipherName Name of the cipher to generate for encrypting.
+ * @param string $iv Base Initialization Vector for the cipher.
+ * @param int $keySize Size of the encryption key, in bits, that will be
+ * used.
+ *
+ * @return Cipher\CipherMethod
+ *
+ * @internal
+ */
+ abstract protected function buildCipherMethod($cipherName, $iv, $keySize);
+
+ /**
+ * Builds an AesStreamInterface and populates encryption metadata into the
+ * supplied envelope.
+ *
+ * @param Stream $plaintext Plain-text data to be encrypted using the
+ * materials, algorithm, and data provided.
+ * @param array $cipherOptions Options for use in determining the cipher to
+ * be used for encrypting data.
+ * @param MaterialsProvider $provider A provider to supply and encrypt
+ * materials used in encryption.
+ * @param MetadataEnvelope $envelope A storage envelope for encryption
+ * metadata to be added to.
+ *
+ * @return AesStreamInterface
+ *
+ * @throws \InvalidArgumentException Thrown when a value in $cipherOptions
+ * is not valid.
+ *
+ * @internal
+ */
+ public function encrypt(
+ Stream $plaintext,
+ array $cipherOptions,
+ MaterialsProvider $provider,
+ MetadataEnvelope $envelope
+ ) {
+ $materialsDescription = $provider->getMaterialsDescription();
+
+ $cipherOptions = array_intersect_key(
+ $cipherOptions,
+ self::$allowedOptions
+ );
+
+ if (empty($cipherOptions['Cipher'])) {
+ throw new \InvalidArgumentException('An encryption cipher must be'
+ . ' specified in the "cipher_options".');
+ }
+
+ if (!self::isSupportedCipher($cipherOptions['Cipher'])) {
+ throw new \InvalidArgumentException('The cipher requested is not'
+ . ' supported by the SDK.');
+ }
+
+ if (empty($cipherOptions['KeySize'])) {
+ $cipherOptions['KeySize'] = 256;
+ }
+ if (!is_int($cipherOptions['KeySize'])) {
+ throw new \InvalidArgumentException('The cipher "KeySize" must be'
+ . ' an integer.');
+ }
+
+ if (!MaterialsProvider::isSupportedKeySize(
+ $cipherOptions['KeySize']
+ )) {
+ throw new \InvalidArgumentException('The cipher "KeySize" requested'
+ . ' is not supported by AES (128, 192, or 256).');
+ }
+
+ $cipherOptions['Iv'] = $provider->generateIv(
+ $this->getCipherOpenSslName(
+ $cipherOptions['Cipher'],
+ $cipherOptions['KeySize']
+ )
+ );
+
+ $cek = $provider->generateCek($cipherOptions['KeySize']);
+
+ list($encryptingStream, $aesName) = $this->getEncryptingStream(
+ $plaintext,
+ $cek,
+ $cipherOptions
+ );
+
+ // Populate envelope data
+ $envelope[MetadataEnvelope::CONTENT_KEY_V2_HEADER] =
+ $provider->encryptCek(
+ $cek,
+ $materialsDescription
+ );
+ unset($cek);
+
+ $envelope[MetadataEnvelope::IV_HEADER] =
+ base64_encode($cipherOptions['Iv']);
+ $envelope[MetadataEnvelope::KEY_WRAP_ALGORITHM_HEADER] =
+ $provider->getWrapAlgorithmName();
+ $envelope[MetadataEnvelope::CONTENT_CRYPTO_SCHEME_HEADER] = $aesName;
+ $envelope[MetadataEnvelope::UNENCRYPTED_CONTENT_LENGTH_HEADER] =
+ strlen($plaintext);
+ $envelope[MetadataEnvelope::MATERIALS_DESCRIPTION_HEADER] =
+ json_encode($materialsDescription);
+ if (!empty($cipherOptions['Tag'])) {
+ $envelope[MetadataEnvelope::CRYPTO_TAG_LENGTH_HEADER] =
+ strlen($cipherOptions['Tag']) * 8;
+ }
+
+ return $encryptingStream;
+ }
+
+ /**
+ * Generates a stream that wraps the plaintext with the proper cipher and
+ * uses the content encryption key (CEK) to encrypt the data when read.
+ *
+ * @param Stream $plaintext Plain-text data to be encrypted using the
+ * materials, algorithm, and data provided.
+ * @param string $cek A content encryption key for use by the stream for
+ * encrypting the plaintext data.
+ * @param array $cipherOptions Options for use in determining the cipher to
+ * be used for encrypting data.
+ *
+ * @return [AesStreamInterface, string]
+ *
+ * @internal
+ */
+ protected function getEncryptingStream(
+ Stream $plaintext,
+ $cek,
+ &$cipherOptions
+ ) {
+ switch ($cipherOptions['Cipher']) {
+ case 'gcm':
+ $cipherOptions['TagLength'] = 16;
+
+ $cipherTextStream = new AesGcmEncryptingStream(
+ $plaintext,
+ $cek,
+ $cipherOptions['Iv'],
+ $cipherOptions['Aad'] = isset($cipherOptions['Aad'])
+ ? $cipherOptions['Aad']
+ : null,
+ $cipherOptions['TagLength'],
+ $cipherOptions['KeySize']
+ );
+
+ if (!empty($cipherOptions['Aad'])) {
+ trigger_error("'Aad' has been supplied for content encryption"
+ . " with " . $cipherTextStream->getAesName() . ". The"
+ . " PHP SDK encryption client can decrypt an object"
+ . " encrypted in this way, but other AWS SDKs may not be"
+ . " able to.", E_USER_WARNING);
+ }
+
+ $appendStream = new AppendStream([
+ $cipherTextStream->createStream()
+ ]);
+ $cipherOptions['Tag'] = $cipherTextStream->getTag();
+ $appendStream->addStream(Psr7\Utils::streamFor($cipherOptions['Tag']));
+ return [$appendStream, $cipherTextStream->getAesName()];
+ default:
+ $cipherMethod = $this->buildCipherMethod(
+ $cipherOptions['Cipher'],
+ $cipherOptions['Iv'],
+ $cipherOptions['KeySize']
+ );
+ $cipherTextStream = new AesEncryptingStream(
+ $plaintext,
+ $cek,
+ $cipherMethod
+ );
+ return [$cipherTextStream, $cipherTextStream->getAesName()];
+ }
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/EncryptionTraitV2.php b/vendor/aws/aws-sdk-php/src/Crypto/EncryptionTraitV2.php
new file mode 100644
index 0000000..8db0717
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/EncryptionTraitV2.php
@@ -0,0 +1,196 @@
+<?php
+namespace Aws\Crypto;
+
+use GuzzleHttp\Psr7;
+use GuzzleHttp\Psr7\AppendStream;
+use GuzzleHttp\Psr7\Stream;
+use Psr\Http\Message\StreamInterface;
+
+trait EncryptionTraitV2
+{
+ private static $allowedOptions = [
+ 'Cipher' => true,
+ 'KeySize' => true,
+ 'Aad' => true,
+ ];
+
+ private static $encryptClasses = [
+ 'gcm' => AesGcmEncryptingStream::class
+ ];
+
+ /**
+ * Dependency to generate a CipherMethod from a set of inputs for loading
+ * in to an AesEncryptingStream.
+ *
+ * @param string $cipherName Name of the cipher to generate for encrypting.
+ * @param string $iv Base Initialization Vector for the cipher.
+ * @param int $keySize Size of the encryption key, in bits, that will be
+ * used.
+ *
+ * @return Cipher\CipherMethod
+ *
+ * @internal
+ */
+ abstract protected function buildCipherMethod($cipherName, $iv, $keySize);
+
+ /**
+ * Builds an AesStreamInterface and populates encryption metadata into the
+ * supplied envelope.
+ *
+ * @param Stream $plaintext Plain-text data to be encrypted using the
+ * materials, algorithm, and data provided.
+ * @param array $options Options for use in encryption, including cipher
+ * options, and encryption context.
+ * @param MaterialsProviderV2 $provider A provider to supply and encrypt
+ * materials used in encryption.
+ * @param MetadataEnvelope $envelope A storage envelope for encryption
+ * metadata to be added to.
+ *
+ * @return StreamInterface
+ *
+ * @throws \InvalidArgumentException Thrown when a value in $options['@CipherOptions']
+ * is not valid.
+ *s
+ * @internal
+ */
+ public function encrypt(
+ Stream $plaintext,
+ array $options,
+ MaterialsProviderV2 $provider,
+ MetadataEnvelope $envelope
+ ) {
+ $options = array_change_key_case($options);
+ $cipherOptions = array_intersect_key(
+ $options['@cipheroptions'],
+ self::$allowedOptions
+ );
+
+ if (empty($cipherOptions['Cipher'])) {
+ throw new \InvalidArgumentException('An encryption cipher must be'
+ . ' specified in @CipherOptions["Cipher"].');
+ }
+
+ $cipherOptions['Cipher'] = strtolower($cipherOptions['Cipher']);
+
+ if (!self::isSupportedCipher($cipherOptions['Cipher'])) {
+ throw new \InvalidArgumentException('The cipher requested is not'
+ . ' supported by the SDK.');
+ }
+
+ if (empty($cipherOptions['KeySize'])) {
+ $cipherOptions['KeySize'] = 256;
+ }
+ if (!is_int($cipherOptions['KeySize'])) {
+ throw new \InvalidArgumentException('The cipher "KeySize" must be'
+ . ' an integer.');
+ }
+
+ if (!MaterialsProviderV2::isSupportedKeySize(
+ $cipherOptions['KeySize']
+ )) {
+ throw new \InvalidArgumentException('The cipher "KeySize" requested'
+ . ' is not supported by AES (128 or 256).');
+ }
+
+ $cipherOptions['Iv'] = $provider->generateIv(
+ $this->getCipherOpenSslName(
+ $cipherOptions['Cipher'],
+ $cipherOptions['KeySize']
+ )
+ );
+
+ $encryptClass = self::$encryptClasses[$cipherOptions['Cipher']];
+ $aesName = $encryptClass::getStaticAesName();
+ $materialsDescription = ['aws:x-amz-cek-alg' => $aesName];
+
+ $keys = $provider->generateCek(
+ $cipherOptions['KeySize'],
+ $materialsDescription,
+ $options
+ );
+
+ // Some providers modify materials description based on options
+ if (isset($keys['UpdatedContext'])) {
+ $materialsDescription = $keys['UpdatedContext'];
+ }
+
+ $encryptingStream = $this->getEncryptingStream(
+ $plaintext,
+ $keys['Plaintext'],
+ $cipherOptions
+ );
+
+ // Populate envelope data
+ $envelope[MetadataEnvelope::CONTENT_KEY_V2_HEADER] = $keys['Ciphertext'];
+ unset($keys);
+
+ $envelope[MetadataEnvelope::IV_HEADER] =
+ base64_encode($cipherOptions['Iv']);
+ $envelope[MetadataEnvelope::KEY_WRAP_ALGORITHM_HEADER] =
+ $provider->getWrapAlgorithmName();
+ $envelope[MetadataEnvelope::CONTENT_CRYPTO_SCHEME_HEADER] = $aesName;
+ $envelope[MetadataEnvelope::UNENCRYPTED_CONTENT_LENGTH_HEADER] =
+ strlen($plaintext);
+ $envelope[MetadataEnvelope::MATERIALS_DESCRIPTION_HEADER] =
+ json_encode($materialsDescription);
+ if (!empty($cipherOptions['Tag'])) {
+ $envelope[MetadataEnvelope::CRYPTO_TAG_LENGTH_HEADER] =
+ strlen($cipherOptions['Tag']) * 8;
+ }
+
+ return $encryptingStream;
+ }
+
+ /**
+ * Generates a stream that wraps the plaintext with the proper cipher and
+ * uses the content encryption key (CEK) to encrypt the data when read.
+ *
+ * @param Stream $plaintext Plain-text data to be encrypted using the
+ * materials, algorithm, and data provided.
+ * @param string $cek A content encryption key for use by the stream for
+ * encrypting the plaintext data.
+ * @param array $cipherOptions Options for use in determining the cipher to
+ * be used for encrypting data.
+ *
+ * @return [AesStreamInterface, string]
+ *
+ * @internal
+ */
+ protected function getEncryptingStream(
+ Stream $plaintext,
+ $cek,
+ &$cipherOptions
+ ) {
+ switch ($cipherOptions['Cipher']) {
+ // Only 'gcm' is supported for encryption currently
+ case 'gcm':
+ $cipherOptions['TagLength'] = 16;
+ $encryptClass = self::$encryptClasses['gcm'];
+ $cipherTextStream = new $encryptClass(
+ $plaintext,
+ $cek,
+ $cipherOptions['Iv'],
+ $cipherOptions['Aad'] = isset($cipherOptions['Aad'])
+ ? $cipherOptions['Aad']
+ : '',
+ $cipherOptions['TagLength'],
+ $cipherOptions['KeySize']
+ );
+
+ if (!empty($cipherOptions['Aad'])) {
+ trigger_error("'Aad' has been supplied for content encryption"
+ . " with " . $cipherTextStream->getAesName() . ". The"
+ . " PHP SDK encryption client can decrypt an object"
+ . " encrypted in this way, but other AWS SDKs may not be"
+ . " able to.", E_USER_WARNING);
+ }
+
+ $appendStream = new AppendStream([
+ $cipherTextStream->createStream()
+ ]);
+ $cipherOptions['Tag'] = $cipherTextStream->getTag();
+ $appendStream->addStream(Psr7\Utils::streamFor($cipherOptions['Tag']));
+ return $appendStream;
+ }
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/KmsMaterialsProvider.php b/vendor/aws/aws-sdk-php/src/Crypto/KmsMaterialsProvider.php
new file mode 100644
index 0000000..fc75138
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/KmsMaterialsProvider.php
@@ -0,0 +1,121 @@
+<?php
+namespace Aws\Crypto;
+
+use Aws\Kms\KmsClient;
+
+/**
+ * Uses KMS to supply materials for encrypting and decrypting data.
+ *
+ * Legacy implementation that supports legacy S3EncryptionClient and
+ * S3EncryptionMultipartUploader, which use an older encryption workflow. Use
+ * KmsMaterialsProviderV2 with S3EncryptionClientV2 or
+ * S3EncryptionMultipartUploaderV2 if possible.
+ *
+ * @deprecated
+ */
+class KmsMaterialsProvider extends MaterialsProvider implements MaterialsProviderInterface
+{
+ const WRAP_ALGORITHM_NAME = 'kms';
+
+ private $kmsClient;
+ private $kmsKeyId;
+
+ /**
+ * @param KmsClient $kmsClient A KMS Client for use encrypting and
+ * decrypting keys.
+ * @param string $kmsKeyId The private KMS key id to be used for encrypting
+ * and decrypting keys.
+ */
+ public function __construct(
+ KmsClient $kmsClient,
+ $kmsKeyId = null
+ ) {
+ $this->kmsClient = $kmsClient;
+ $this->kmsKeyId = $kmsKeyId;
+ }
+
+ public function fromDecryptionEnvelope(MetadataEnvelope $envelope)
+ {
+ if (empty($envelope[MetadataEnvelope::MATERIALS_DESCRIPTION_HEADER])) {
+ throw new \RuntimeException('Not able to detect the materials description.');
+ }
+
+ $materialsDescription = json_decode(
+ $envelope[MetadataEnvelope::MATERIALS_DESCRIPTION_HEADER],
+ true
+ );
+
+ if (empty($materialsDescription['kms_cmk_id'])
+ && empty($materialsDescription['aws:x-amz-cek-alg'])) {
+ throw new \RuntimeException('Not able to detect kms_cmk_id (legacy'
+ . ' implementation) or aws:x-amz-cek-alg (current implementation)'
+ . ' from kms materials description.');
+ }
+
+ return new self(
+ $this->kmsClient,
+ isset($materialsDescription['kms_cmk_id'])
+ ? $materialsDescription['kms_cmk_id']
+ : null
+ );
+ }
+
+ /**
+ * The KMS key id for use in matching this Provider to its keys,
+ * consistently with other SDKs as 'kms_cmk_id'.
+ *
+ * @return array
+ */
+ public function getMaterialsDescription()
+ {
+ return ['kms_cmk_id' => $this->kmsKeyId];
+ }
+
+ public function getWrapAlgorithmName()
+ {
+ return self::WRAP_ALGORITHM_NAME;
+ }
+
+ /**
+ * Takes a content encryption key (CEK) and description to return an encrypted
+ * key by using KMS' Encrypt API.
+ *
+ * @param string $unencryptedCek Key for use in encrypting other data
+ * that itself needs to be encrypted by the
+ * Provider.
+ * @param string $materialDescription Material Description for use in
+ * encrypting the $cek.
+ *
+ * @return string
+ */
+ public function encryptCek($unencryptedCek, $materialDescription)
+ {
+ $encryptedDataKey = $this->kmsClient->encrypt([
+ 'Plaintext' => $unencryptedCek,
+ 'KeyId' => $this->kmsKeyId,
+ 'EncryptionContext' => $materialDescription
+ ]);
+ return base64_encode($encryptedDataKey['CiphertextBlob']);
+ }
+
+ /**
+ * Takes an encrypted content encryption key (CEK) and material description
+ * for use decrypting the key by using KMS' Decrypt API.
+ *
+ * @param string $encryptedCek Encrypted key to be decrypted by the Provider
+ * for use decrypting other data.
+ * @param string $materialDescription Material Description for use in
+ * encrypting the $cek.
+ *
+ * @return string
+ */
+ public function decryptCek($encryptedCek, $materialDescription)
+ {
+ $result = $this->kmsClient->decrypt([
+ 'CiphertextBlob' => $encryptedCek,
+ 'EncryptionContext' => $materialDescription
+ ]);
+
+ return $result['Plaintext'];
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/KmsMaterialsProviderV2.php b/vendor/aws/aws-sdk-php/src/Crypto/KmsMaterialsProviderV2.php
new file mode 100644
index 0000000..e7da8b9
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/KmsMaterialsProviderV2.php
@@ -0,0 +1,100 @@
+<?php
+namespace Aws\Crypto;
+
+use Aws\Exception\CryptoException;
+use Aws\Kms\KmsClient;
+
+/**
+ * Uses KMS to supply materials for encrypting and decrypting data. This
+ * V2 implementation should be used with the V2 encryption clients (i.e.
+ * S3EncryptionClientV2).
+ */
+class KmsMaterialsProviderV2 extends MaterialsProviderV2 implements MaterialsProviderInterfaceV2
+{
+ const WRAP_ALGORITHM_NAME = 'kms+context';
+
+ private $kmsClient;
+ private $kmsKeyId;
+
+ /**
+ * @param KmsClient $kmsClient A KMS Client for use encrypting and
+ * decrypting keys.
+ * @param string $kmsKeyId The private KMS key id to be used for encrypting
+ * and decrypting keys.
+ */
+ public function __construct(
+ KmsClient $kmsClient,
+ $kmsKeyId = null
+ ) {
+ $this->kmsClient = $kmsClient;
+ $this->kmsKeyId = $kmsKeyId;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getWrapAlgorithmName()
+ {
+ return self::WRAP_ALGORITHM_NAME;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function decryptCek($encryptedCek, $materialDescription, $options)
+ {
+ $params = [
+ 'CiphertextBlob' => $encryptedCek,
+ 'EncryptionContext' => $materialDescription
+ ];
+ if (empty($options['@KmsAllowDecryptWithAnyCmk'])) {
+ if (empty($this->kmsKeyId)) {
+ throw new CryptoException('KMS CMK ID was not specified and the'
+ . ' operation is not opted-in to attempting to use any valid'
+ . ' CMK it discovers. Please specify a CMK ID, or explicitly'
+ . ' enable attempts to use any valid KMS CMK with the'
+ . ' @KmsAllowDecryptWithAnyCmk option.');
+ }
+ $params['KeyId'] = $this->kmsKeyId;
+ }
+
+ $result = $this->kmsClient->decrypt($params);
+ return $result['Plaintext'];
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function generateCek($keySize, $context, $options)
+ {
+ if (empty($this->kmsKeyId)) {
+ throw new CryptoException('A KMS key id is required for encryption'
+ . ' with KMS keywrap. Use a KmsMaterialsProviderV2 that has been'
+ . ' instantiated with a KMS key id.');
+ }
+ $options = array_change_key_case($options);
+ if (!isset($options['@kmsencryptioncontext'])
+ || !is_array($options['@kmsencryptioncontext'])
+ ) {
+ throw new CryptoException("'@KmsEncryptionContext' is a"
+ . " required argument when using KmsMaterialsProviderV2, and"
+ . " must be an associative array (or empty array).");
+ }
+ if (isset($options['@kmsencryptioncontext']['aws:x-amz-cek-alg'])) {
+ throw new CryptoException("Conflict in reserved @KmsEncryptionContext"
+ . " key aws:x-amz-cek-alg. This value is reserved for the S3"
+ . " Encryption Client and cannot be set by the user.");
+ }
+ $context = array_merge($options['@kmsencryptioncontext'], $context);
+ $result = $this->kmsClient->generateDataKey([
+ 'KeyId' => $this->kmsKeyId,
+ 'KeySpec' => "AES_{$keySize}",
+ 'EncryptionContext' => $context
+ ]);
+ return [
+ 'Plaintext' => $result['Plaintext'],
+ 'Ciphertext' => base64_encode($result['CiphertextBlob']),
+ 'UpdatedContext' => $context
+ ];
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/MaterialsProvider.php b/vendor/aws/aws-sdk-php/src/Crypto/MaterialsProvider.php
new file mode 100644
index 0000000..1c6941c
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/MaterialsProvider.php
@@ -0,0 +1,105 @@
+<?php
+namespace Aws\Crypto;
+
+abstract class MaterialsProvider implements MaterialsProviderInterface
+{
+ private static $supportedKeySizes = [
+ 128 => true,
+ 192 => true,
+ 256 => true,
+ ];
+
+ /**
+ * Returns if the requested size is supported by AES.
+ *
+ * @param int $keySize Size of the requested key in bits.
+ *
+ * @return bool
+ */
+ public static function isSupportedKeySize($keySize)
+ {
+ return isset(self::$supportedKeySizes[$keySize]);
+ }
+
+ /**
+ * Performs further initialization of the MaterialsProvider based on the
+ * data inside the MetadataEnvelope.
+ *
+ * @param MetadataEnvelope $envelope A storage envelope for encryption
+ * metadata to be read from.
+ *
+ * @return MaterialsProvider
+ *
+ * @throws \RuntimeException Thrown when there is an empty or improperly
+ * formed materials description in the envelope.
+ *
+ * @internal
+ */
+ abstract public function fromDecryptionEnvelope(MetadataEnvelope $envelope);
+
+ /**
+ * Returns the material description for this Provider so it can be verified
+ * by encryption mechanisms.
+ *
+ * @return string
+ */
+ abstract public function getMaterialsDescription();
+
+ /**
+ * Returns the wrap algorithm name for this Provider.
+ *
+ * @return string
+ */
+ abstract public function getWrapAlgorithmName();
+
+ /**
+ * Takes a content encryption key (CEK) and description to return an
+ * encrypted key according to the Provider's specifications.
+ *
+ * @param string $unencryptedCek Key for use in encrypting other data
+ * that itself needs to be encrypted by the
+ * Provider.
+ * @param string $materialDescription Material Description for use in
+ * encrypting the $cek.
+ *
+ * @return string
+ */
+ abstract public function encryptCek($unencryptedCek, $materialDescription);
+
+ /**
+ * Takes an encrypted content encryption key (CEK) and material description
+ * for use decrypting the key according to the Provider's specifications.
+ *
+ * @param string $encryptedCek Encrypted key to be decrypted by the Provider
+ * for use decrypting other data.
+ * @param string $materialDescription Material Description for use in
+ * encrypting the $cek.
+ *
+ * @return string
+ */
+ abstract public function decryptCek($encryptedCek, $materialDescription);
+
+ /**
+ * @param string $keySize Length of a cipher key in bits for generating a
+ * random content encryption key (CEK).
+ *
+ * @return string
+ */
+ public function generateCek($keySize)
+ {
+ return openssl_random_pseudo_bytes($keySize / 8);
+ }
+
+ /**
+ * @param string $openSslName Cipher OpenSSL name to use for generating
+ * an initialization vector.
+ *
+ * @return string
+ */
+ public function generateIv($openSslName)
+ {
+ return openssl_random_pseudo_bytes(
+ openssl_cipher_iv_length($openSslName)
+ );
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/MaterialsProviderInterface.php b/vendor/aws/aws-sdk-php/src/Crypto/MaterialsProviderInterface.php
new file mode 100644
index 0000000..a22016d
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/MaterialsProviderInterface.php
@@ -0,0 +1,61 @@
+<?php
+namespace Aws\Crypto;
+
+interface MaterialsProviderInterface
+{
+ /**
+ * Returns if the requested size is supported by AES.
+ *
+ * @param int $keySize Size of the requested key in bits.
+ *
+ * @return bool
+ */
+ public static function isSupportedKeySize($keySize);
+
+ /**
+ * Performs further initialization of the MaterialsProvider based on the
+ * data inside the MetadataEnvelope.
+ *
+ * @param MetadataEnvelope $envelope A storage envelope for encryption
+ * metadata to be read from.
+ *
+ * @internal
+ */
+ public function fromDecryptionEnvelope(MetadataEnvelope $envelope);
+
+ /**
+ * Returns the wrap algorithm name for this Provider.
+ *
+ * @return string
+ */
+ public function getWrapAlgorithmName();
+
+ /**
+ * Takes an encrypted content encryption key (CEK) and material description
+ * for use decrypting the key according to the Provider's specifications.
+ *
+ * @param string $encryptedCek Encrypted key to be decrypted by the Provider
+ * for use decrypting other data.
+ * @param string $materialDescription Material Description for use in
+ * encrypting the $cek.
+ *
+ * @return string
+ */
+ public function decryptCek($encryptedCek, $materialDescription);
+
+ /**
+ * @param string $keySize Length of a cipher key in bits for generating a
+ * random content encryption key (CEK).
+ *
+ * @return string
+ */
+ public function generateCek($keySize);
+
+ /**
+ * @param string $openSslName Cipher OpenSSL name to use for generating
+ * an initialization vector.
+ *
+ * @return string
+ */
+ public function generateIv($openSslName);
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/MaterialsProviderInterfaceV2.php b/vendor/aws/aws-sdk-php/src/Crypto/MaterialsProviderInterfaceV2.php
new file mode 100644
index 0000000..265af1a
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/MaterialsProviderInterfaceV2.php
@@ -0,0 +1,53 @@
+<?php
+namespace Aws\Crypto;
+
+interface MaterialsProviderInterfaceV2
+{
+ /**
+ * Returns if the requested size is supported by AES.
+ *
+ * @param int $keySize Size of the requested key in bits.
+ *
+ * @return bool
+ */
+ public static function isSupportedKeySize($keySize);
+
+ /**
+ * Returns the wrap algorithm name for this Provider.
+ *
+ * @return string
+ */
+ public function getWrapAlgorithmName();
+
+ /**
+ * Takes an encrypted content encryption key (CEK) and material description
+ * for use decrypting the key according to the Provider's specifications.
+ *
+ * @param string $encryptedCek Encrypted key to be decrypted by the Provider
+ * for use decrypting other data.
+ * @param string $materialDescription Material Description for use in
+ * decrypting the CEK.
+ * @param array $options Options for use in decrypting the CEK.
+ *
+ * @return string
+ */
+ public function decryptCek($encryptedCek, $materialDescription, $options);
+
+ /**
+ * @param string $keySize Length of a cipher key in bits for generating a
+ * random content encryption key (CEK).
+ * @param array $context Context map needed for key encryption
+ * @param array $options Additional options to be used in CEK generation
+ *
+ * @return array
+ */
+ public function generateCek($keySize, $context, $options);
+
+ /**
+ * @param string $openSslName Cipher OpenSSL name to use for generating
+ * an initialization vector.
+ *
+ * @return string
+ */
+ public function generateIv($openSslName);
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/MaterialsProviderV2.php b/vendor/aws/aws-sdk-php/src/Crypto/MaterialsProviderV2.php
new file mode 100644
index 0000000..685cbf5
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/MaterialsProviderV2.php
@@ -0,0 +1,66 @@
+<?php
+namespace Aws\Crypto;
+
+abstract class MaterialsProviderV2 implements MaterialsProviderInterfaceV2
+{
+ private static $supportedKeySizes = [
+ 128 => true,
+ 256 => true,
+ ];
+
+ /**
+ * Returns if the requested size is supported by AES.
+ *
+ * @param int $keySize Size of the requested key in bits.
+ *
+ * @return bool
+ */
+ public static function isSupportedKeySize($keySize)
+ {
+ return isset(self::$supportedKeySizes[$keySize]);
+ }
+
+ /**
+ * Returns the wrap algorithm name for this Provider.
+ *
+ * @return string
+ */
+ abstract public function getWrapAlgorithmName();
+
+ /**
+ * Takes an encrypted content encryption key (CEK) and material description
+ * for use decrypting the key according to the Provider's specifications.
+ *
+ * @param string $encryptedCek Encrypted key to be decrypted by the Provider
+ * for use decrypting other data.
+ * @param string $materialDescription Material Description for use in
+ * decrypting the CEK.
+ * @param string $options Options for use in decrypting the CEK.
+ *
+ * @return string
+ */
+ abstract public function decryptCek($encryptedCek, $materialDescription, $options);
+
+ /**
+ * @param string $keySize Length of a cipher key in bits for generating a
+ * random content encryption key (CEK).
+ * @param array $context Context map needed for key encryption
+ * @param array $options Additional options to be used in CEK generation
+ *
+ * @return array
+ */
+ abstract public function generateCek($keySize, $context, $options);
+
+ /**
+ * @param string $openSslName Cipher OpenSSL name to use for generating
+ * an initialization vector.
+ *
+ * @return string
+ */
+ public function generateIv($openSslName)
+ {
+ return openssl_random_pseudo_bytes(
+ openssl_cipher_iv_length($openSslName)
+ );
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/MetadataEnvelope.php b/vendor/aws/aws-sdk-php/src/Crypto/MetadataEnvelope.php
new file mode 100644
index 0000000..5a7c692
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/MetadataEnvelope.php
@@ -0,0 +1,61 @@
+<?php
+namespace Aws\Crypto;
+
+use Aws\HasDataTrait;
+use \ArrayAccess;
+use \IteratorAggregate;
+use \InvalidArgumentException;
+use \JsonSerializable;
+
+/**
+ * Stores encryption metadata for reading and writing.
+ *
+ * @internal
+ */
+class MetadataEnvelope implements ArrayAccess, IteratorAggregate, JsonSerializable
+{
+ use HasDataTrait;
+
+ const CONTENT_KEY_V2_HEADER = 'x-amz-key-v2';
+ const IV_HEADER = 'x-amz-iv';
+ const MATERIALS_DESCRIPTION_HEADER = 'x-amz-matdesc';
+ const KEY_WRAP_ALGORITHM_HEADER = 'x-amz-wrap-alg';
+ const CONTENT_CRYPTO_SCHEME_HEADER = 'x-amz-cek-alg';
+ const CRYPTO_TAG_LENGTH_HEADER = 'x-amz-tag-len';
+ const UNENCRYPTED_CONTENT_LENGTH_HEADER = 'x-amz-unencrypted-content-length';
+
+ private static $constants = [];
+
+ public static function getConstantValues()
+ {
+ if (empty(self::$constants)) {
+ $reflection = new \ReflectionClass(static::class);
+ foreach (array_values($reflection->getConstants()) as $constant) {
+ self::$constants[$constant] = true;
+ }
+ }
+
+ return array_keys(self::$constants);
+ }
+
+ /**
+ * @return void
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetSet($name, $value)
+ {
+ $constants = self::getConstantValues();
+ if (is_null($name) || !in_array($name, $constants)) {
+ throw new InvalidArgumentException('MetadataEnvelope fields must'
+ . ' must match a predefined offset; use the header constants.');
+ }
+
+ $this->data[$name] = $value;
+ }
+
+ #[\ReturnTypeWillChange]
+ public function jsonSerialize()
+ {
+ return $this->data;
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/MetadataStrategyInterface.php b/vendor/aws/aws-sdk-php/src/Crypto/MetadataStrategyInterface.php
new file mode 100644
index 0000000..5270c7e
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/MetadataStrategyInterface.php
@@ -0,0 +1,30 @@
+<?php
+namespace Aws\Crypto;
+
+interface MetadataStrategyInterface
+{
+ /**
+ * Places the information in the MetadataEnvelope to the strategy specific
+ * location. Populates the PutObject arguments with any information
+ * necessary for loading.
+ *
+ * @param MetadataEnvelope $envelope Encryption data to save according to
+ * the strategy.
+ * @param array $args Starting arguments for PutObject.
+ *
+ * @return array Updated arguments for PutObject.
+ */
+ public function save(MetadataEnvelope $envelope, array $args);
+
+ /**
+ * Generates a MetadataEnvelope according to the specific strategy using the
+ * passed arguments.
+ *
+ * @param array $args Arguments from Command and Result that contains
+ * S3 Object information, relevant headers, and command
+ * configuration.
+ *
+ * @return MetadataEnvelope
+ */
+ public function load(array $args);
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/AesGcm.php b/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/AesGcm.php
new file mode 100644
index 0000000..baf8ae2
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/AesGcm.php
@@ -0,0 +1,228 @@
+<?php
+namespace Aws\Crypto\Polyfill;
+
+use Aws\Exception\CryptoPolyfillException;
+use InvalidArgumentException;
+use RangeException;
+
+/**
+ * Class AesGcm
+ *
+ * This provides a polyfill for AES-GCM encryption/decryption, with caveats:
+ *
+ * 1. Only 96-bit nonces are supported.
+ * 2. Only 128-bit authentication tags are supported. (i.e. non-truncated)
+ *
+ * Supports AES key sizes of 128-bit, 192-bit, and 256-bit.
+ *
+ * @package Aws\Crypto\Polyfill
+ */
+class AesGcm
+{
+ use NeedsTrait;
+
+ /** @var Key $aesKey */
+ private $aesKey;
+
+ /** @var int $keySize */
+ private $keySize;
+
+ /** @var int $blockSize */
+ protected $blockSize = 8192;
+
+ /**
+ * AesGcm constructor.
+ *
+ * @param Key $aesKey
+ * @param int $keySize
+ * @param int $blockSize
+ *
+ * @throws CryptoPolyfillException
+ * @throws InvalidArgumentException
+ * @throws RangeException
+ */
+ public function __construct(Key $aesKey, $keySize = 256, $blockSize = 8192)
+ {
+ /* Preconditions: */
+ self::needs(
+ \in_array($keySize, [128, 192, 256], true),
+ "Key size must be 128, 192, or 256 bits; {$keySize} given",
+ InvalidArgumentException::class
+ );
+ self::needs(
+ \is_int($blockSize) && $blockSize > 0 && $blockSize <= PHP_INT_MAX,
+ 'Block size must be a positive integer.',
+ RangeException::class
+ );
+ self::needs(
+ $aesKey->length() << 3 === $keySize,
+ 'Incorrect key size; expected ' . $keySize . ' bits, got ' . ($aesKey->length() << 3) . ' bits.'
+ );
+ $this->aesKey = $aesKey;
+ $this->keySize = $keySize;
+ }
+
+ /**
+ * Encryption interface for AES-GCM
+ *
+ * @param string $plaintext Message to be encrypted
+ * @param string $nonce Number to be used ONCE
+ * @param Key $key AES Key
+ * @param string $aad Additional authenticated data
+ * @param string &$tag Reference to variable to hold tag
+ * @param int $keySize Key size (bits)
+ * @param int $blockSize Block size (bytes) -- How much memory to buffer
+ * @return string
+ * @throws InvalidArgumentException
+ */
+ public static function encrypt(
+ $plaintext,
+ $nonce,
+ Key $key,
+ $aad,
+ &$tag,
+ $keySize = 256,
+ $blockSize = 8192
+ ) {
+ self::needs(
+ self::strlen($nonce) === 12,
+ 'Nonce must be exactly 12 bytes',
+ InvalidArgumentException::class
+ );
+
+ $encryptor = new AesGcm($key, $keySize, $blockSize);
+ list($aadLength, $gmac) = $encryptor->gmacInit($nonce, $aad);
+
+ $ciphertext = \openssl_encrypt(
+ $plaintext,
+ "aes-{$encryptor->keySize}-ctr",
+ $key->get(),
+ OPENSSL_NO_PADDING | OPENSSL_RAW_DATA,
+ $nonce . "\x00\x00\x00\x02"
+ );
+
+ /* Calculate auth tag in a streaming fashion to minimize memory usage: */
+ $ciphertextLength = self::strlen($ciphertext);
+ for ($i = 0; $i < $ciphertextLength; $i += $encryptor->blockSize) {
+ $cBlock = new ByteArray(self::substr($ciphertext, $i, $encryptor->blockSize));
+ $gmac->update($cBlock);
+ }
+ $tag = $gmac->finish($aadLength, $ciphertextLength)->toString();
+ return $ciphertext;
+ }
+
+ /**
+ * Decryption interface for AES-GCM
+ *
+ * @param string $ciphertext Ciphertext to decrypt
+ * @param string $nonce Number to be used ONCE
+ * @param Key $key AES key
+ * @param string $aad Additional authenticated data
+ * @param string $tag Authentication tag
+ * @param int $keySize Key size (bits)
+ * @param int $blockSize Block size (bytes) -- How much memory to buffer
+ * @return string Plaintext
+ *
+ * @throws CryptoPolyfillException
+ * @throws InvalidArgumentException
+ */
+ public static function decrypt(
+ $ciphertext,
+ $nonce,
+ Key $key,
+ $aad,
+ &$tag,
+ $keySize = 256,
+ $blockSize = 8192
+ ) {
+ /* Precondition: */
+ self::needs(
+ self::strlen($nonce) === 12,
+ 'Nonce must be exactly 12 bytes',
+ InvalidArgumentException::class
+ );
+
+ $encryptor = new AesGcm($key, $keySize, $blockSize);
+ list($aadLength, $gmac) = $encryptor->gmacInit($nonce, $aad);
+
+ /* Calculate auth tag in a streaming fashion to minimize memory usage: */
+ $ciphertextLength = self::strlen($ciphertext);
+ for ($i = 0; $i < $ciphertextLength; $i += $encryptor->blockSize) {
+ $cBlock = new ByteArray(self::substr($ciphertext, $i, $encryptor->blockSize));
+ $gmac->update($cBlock);
+ }
+
+ /* Validate auth tag in constant-time: */
+ $calc = $gmac->finish($aadLength, $ciphertextLength);
+ $expected = new ByteArray($tag);
+ self::needs($calc->equals($expected), 'Invalid authentication tag');
+
+ /* Return plaintext if auth tag check succeeded: */
+ return \openssl_decrypt(
+ $ciphertext,
+ "aes-{$encryptor->keySize}-ctr",
+ $key->get(),
+ OPENSSL_NO_PADDING | OPENSSL_RAW_DATA,
+ $nonce . "\x00\x00\x00\x02"
+ );
+ }
+
+ /**
+ * Initialize a Gmac object with the nonce and this object's key.
+ *
+ * @param string $nonce Must be exactly 12 bytes long.
+ * @param string|null $aad
+ * @return array
+ */
+ protected function gmacInit($nonce, $aad = null)
+ {
+ $gmac = new Gmac(
+ $this->aesKey,
+ $nonce . "\x00\x00\x00\x01",
+ $this->keySize
+ );
+ $aadBlock = new ByteArray($aad);
+ $aadLength = $aadBlock->count();
+ $gmac->update($aadBlock);
+ $gmac->flush();
+ return [$aadLength, $gmac];
+ }
+
+ /**
+ * Calculate the length of a string.
+ *
+ * Uses the appropriate PHP function without being brittle to
+ * mbstring.func_overload.
+ *
+ * @param string $string
+ * @return int
+ */
+ protected static function strlen($string)
+ {
+ if (\is_callable('\\mb_strlen')) {
+ return (int) \mb_strlen($string, '8bit');
+ }
+ return (int) \strlen($string);
+ }
+
+ /**
+ * Return a substring of the provided string.
+ *
+ * Uses the appropriate PHP function without being brittle to
+ * mbstring.func_overload.
+ *
+ * @param string $string
+ * @param int $offset
+ * @param int|null $length
+ * @return string
+ */
+ protected static function substr($string, $offset = 0, $length = null)
+ {
+ if (\is_callable('\\mb_substr')) {
+ return \mb_substr($string, $offset, $length, '8bit');
+ } elseif (!\is_null($length)) {
+ return \substr($string, $offset, $length);
+ }
+ return \substr($string, $offset);
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/ByteArray.php b/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/ByteArray.php
new file mode 100644
index 0000000..c3472b0
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/ByteArray.php
@@ -0,0 +1,258 @@
+<?php
+namespace Aws\Crypto\Polyfill;
+
+/**
+ * Class ByteArray
+ * @package Aws\Crypto\Polyfill
+ */
+class ByteArray extends \SplFixedArray
+{
+ use NeedsTrait;
+
+ /**
+ * ByteArray constructor.
+ *
+ * @param int|string|int[] $size
+ * If you pass in an integer, it creates a ByteArray of that size.
+ * If you pass in a string or array, it converts it to an array of
+ * integers between 0 and 255.
+ * @throws \InvalidArgumentException
+ */
+ public function __construct($size = 0)
+ {
+ $arr = null;
+ // Integer? This behaves just like SplFixedArray.
+ if (\is_array($size)) {
+ // Array? We need to pass the count to parent::__construct() then populate
+ $arr = $size;
+ $size = \count($arr);
+ } elseif (\is_string($size)) {
+ // We need to avoid mbstring.func_overload
+ if (\is_callable('\\mb_str_split')) {
+ $tmp = \mb_str_split($size, 1, '8bit');
+ } else {
+ $tmp = \str_split($size, 1);
+ }
+ // Let's convert each character to an 8-bit integer and store in $arr
+ $arr = [];
+ if (!empty($tmp)) {
+ foreach ($tmp as $t) {
+ if (strlen($t) < 1) {
+ continue;
+ }
+ $arr []= \unpack('C', $t)[1] & 0xff;
+ }
+ }
+ $size = \count($arr);
+ } elseif ($size instanceof ByteArray) {
+ $arr = $size->toArray();
+ $size = $size->count();
+ } elseif (!\is_int($size)) {
+ throw new \InvalidArgumentException(
+ 'Argument must be an integer, string, or array of integers.'
+ );
+ }
+
+ parent::__construct($size);
+
+ if (!empty($arr)) {
+ // Populate this object with values from constructor argument
+ foreach ($arr as $i => $v) {
+ $this->offsetSet($i, $v);
+ }
+ } else {
+ // Initialize to zero.
+ for ($i = 0; $i < $size; ++$i) {
+ $this->offsetSet($i, 0);
+ }
+ }
+ }
+
+ /**
+ * Encode an integer into a byte array. 32-bit (unsigned), big endian byte order.
+ *
+ * @param int $num
+ * @return self
+ */
+ public static function enc32be($num)
+ {
+ return new ByteArray(\pack('N', $num));
+ }
+
+ /**
+ * @param ByteArray $other
+ * @return bool
+ */
+ public function equals(ByteArray $other)
+ {
+ if ($this->count() !== $other->count()) {
+ return false;
+ }
+ $d = 0;
+ for ($i = $this->count() - 1; $i >= 0; --$i) {
+ $d |= $this[$i] ^ $other[$i];
+ }
+ return $d === 0;
+ }
+
+ /**
+ * @param ByteArray $array
+ * @return ByteArray
+ */
+ public function exclusiveOr(ByteArray $array)
+ {
+ self::needs(
+ $this->count() === $array->count(),
+ 'Both ByteArrays must be equal size for exclusiveOr()'
+ );
+ $out = clone $this;
+ for ($i = 0; $i < $this->count(); ++$i) {
+ $out[$i] = $array[$i] ^ $out[$i];
+ }
+ return $out;
+ }
+
+ /**
+ * Returns a new ByteArray incremented by 1 (big endian byte order).
+ *
+ * @param int $increase
+ * @return self
+ */
+ public function getIncremented($increase = 1)
+ {
+ $clone = clone $this;
+ $index = $clone->count();
+ while ($index > 0) {
+ --$index;
+ $tmp = ($clone[$index] + $increase) & PHP_INT_MAX;
+ $clone[$index] = $tmp & 0xff;
+ $increase = $tmp >> 8;
+ }
+ return $clone;
+ }
+
+ /**
+ * Sets a value. See SplFixedArray for more.
+ *
+ * @param int $index
+ * @param int $newval
+ * @return void
+ */
+ public function offsetSet($index, $newval)
+ {
+ parent::offsetSet($index, $newval & 0xff);
+ }
+
+ /**
+ * Return a copy of this ByteArray, bitshifted to the right by 1.
+ * Used in Gmac.
+ *
+ * @return self
+ */
+ public function rshift()
+ {
+ $out = clone $this;
+ for ($j = $this->count() - 1; $j > 0; --$j) {
+ $out[$j] = (($out[$j - 1] & 1) << 7) | ($out[$j] >> 1);
+ }
+ $out[0] >>= 1;
+ return $out;
+ }
+
+ /**
+ * Constant-time conditional select. This is meant to read like a ternary operator.
+ *
+ * $z = ByteArray::select(1, $x, $y); // $z is equal to $x
+ * $z = ByteArray::select(0, $x, $y); // $z is equal to $y
+ *
+ * @param int $select
+ * @param ByteArray $left
+ * @param ByteArray $right
+ * @return ByteArray
+ */
+ public static function select($select, ByteArray $left, ByteArray $right)
+ {
+ self::needs(
+ $left->count() === $right->count(),
+ 'Both ByteArrays must be equal size for select()'
+ );
+ $rightLength = $right->count();
+ $out = clone $right;
+ $mask = (-($select & 1)) & 0xff;
+ for ($i = 0; $i < $rightLength; $i++) {
+ $out[$i] = $out[$i] ^ (($left[$i] ^ $right[$i]) & $mask);
+ }
+ return $out;
+ }
+
+ /**
+ * Overwrite values of this ByteArray based on a separate ByteArray, with
+ * a given starting offset and length.
+ *
+ * See JavaScript's Uint8Array.set() for more information.
+ *
+ * @param ByteArray $input
+ * @param int $offset
+ * @param int|null $length
+ * @return self
+ */
+ public function set(ByteArray $input, $offset = 0, $length = null)
+ {
+ self::needs(
+ is_int($offset) && $offset >= 0,
+ 'Offset must be a positive integer or zero'
+ );
+ if (is_null($length)) {
+ $length = $input->count();
+ }
+
+ $i = 0; $j = $offset;
+ while ($i < $length && $j < $this->count()) {
+ $this[$j] = $input[$i];
+ ++$i;
+ ++$j;
+ }
+ return $this;
+ }
+
+ /**
+ * Returns a slice of this ByteArray.
+ *
+ * @param int $start
+ * @param null $length
+ * @return self
+ */
+ public function slice($start = 0, $length = null)
+ {
+ return new ByteArray(\array_slice($this->toArray(), $start, $length));
+ }
+
+ /**
+ * Mutates the current state and sets all values to zero.
+ *
+ * @return void
+ */
+ public function zeroize()
+ {
+ for ($i = $this->count() - 1; $i >= 0; --$i) {
+ $this->offsetSet($i, 0);
+ }
+ }
+
+ /**
+ * Converts the ByteArray to a raw binary string.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ $count = $this->count();
+ if ($count === 0) {
+ return '';
+ }
+ $args = $this->toArray();
+ \array_unshift($args, \str_repeat('C', $count));
+ // constant-time, PHP <5.6 equivalent to pack('C*', ...$args);
+ return \call_user_func_array('\\pack', $args);
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/Gmac.php b/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/Gmac.php
new file mode 100644
index 0000000..535cfca
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/Gmac.php
@@ -0,0 +1,223 @@
+<?php
+namespace Aws\Crypto\Polyfill;
+
+/**
+ * Class Gmac
+ *
+ * @package Aws\Crypto\Polyfill
+ */
+class Gmac
+{
+ use NeedsTrait;
+
+ const BLOCK_SIZE = 16;
+
+ /** @var ByteArray $buf */
+ protected $buf;
+
+ /** @var int $bufLength */
+ protected $bufLength = 0;
+
+ /** @var ByteArray $h */
+ protected $h;
+
+ /** @var ByteArray $hf */
+ protected $hf;
+
+ /** @var Key $key */
+ protected $key;
+
+ /** @var ByteArray $x */
+ protected $x;
+
+ /**
+ * Gmac constructor.
+ *
+ * @param Key $aesKey
+ * @param string $nonce
+ * @param int $keySize
+ */
+ public function __construct(Key $aesKey, $nonce, $keySize = 256)
+ {
+ $this->buf = new ByteArray(16);
+ $this->h = new ByteArray(
+ \openssl_encrypt(
+ \str_repeat("\0", 16),
+ "aes-{$keySize}-ecb",
+ $aesKey->get(),
+ OPENSSL_RAW_DATA | OPENSSL_NO_PADDING
+ )
+ );
+ $this->key = $aesKey;
+ $this->x = new ByteArray(16);
+ $this->hf = new ByteArray(
+ \openssl_encrypt(
+ $nonce,
+ "aes-{$keySize}-ecb",
+ $aesKey->get(),
+ OPENSSL_RAW_DATA | OPENSSL_NO_PADDING
+ )
+ );
+ }
+
+ /**
+ * Update the object with some data.
+ *
+ * This method mutates this Gmac object.
+ *
+ * @param ByteArray $blocks
+ * @return self
+ */
+ public function update(ByteArray $blocks)
+ {
+ if (($blocks->count() + $this->bufLength) < self::BLOCK_SIZE) {
+ // Write to internal buffer until we reach enough to write.
+ $this->buf->set($blocks, $this->bufLength);
+ $this->bufLength += $blocks->count();
+ return $this;
+ }
+
+ // Process internal buffer first.
+ if ($this->bufLength > 0) {
+ // 0 <= state.buf_len < BLOCK_SIZE is an invariant
+ $tmp = new ByteArray(self::BLOCK_SIZE);
+ $tmp->set($this->buf->slice(0, $this->bufLength));
+ $remainingBlockLength = self::BLOCK_SIZE - $this->bufLength;
+ $tmp->set($blocks->slice(0, $remainingBlockLength), $this->bufLength);
+ $blocks = $blocks->slice($remainingBlockLength);
+ $this->bufLength = 0;
+ $this->x = $this->blockMultiply($this->x->exclusiveOr($tmp), $this->h);
+ }
+
+ // Process full blocks.
+ $numBlocks = $blocks->count() >> 4;
+ for ($i = 0; $i < $numBlocks; ++$i) {
+ $tmp = $blocks->slice($i << 4, self::BLOCK_SIZE);
+ $this->x = $this->blockMultiply($this->x->exclusiveOr($tmp), $this->h);
+ }
+ $last = $numBlocks << 4;
+
+ // Zero-fill buffer
+ for ($i = 0; $i < 16; ++$i) {
+ $this->buf[$i] = 0;
+ }
+ // Feed leftover into buffer.
+ if ($last < $blocks->count()) {
+ $tmp = $blocks->slice($last);
+ $this->buf->set($tmp);
+ $this->bufLength += ($blocks->count() - $last);
+ }
+ return $this;
+ }
+
+ /**
+ * Finish processing the authentication tag.
+ *
+ * This method mutates this Gmac object (effectively resetting it).
+ *
+ * @param int $aadLength
+ * @param int $ciphertextLength
+ * @return ByteArray
+ */
+ public function finish($aadLength, $ciphertextLength)
+ {
+ $lengthBlock = new ByteArray(16);
+ $state = $this->flush();
+
+ // AES-GCM expects bit lengths, not byte lengths.
+ $lengthBlock->set(ByteArray::enc32be($aadLength >> 29), 0);
+ $lengthBlock->set(ByteArray::enc32be($aadLength << 3), 4);
+ $lengthBlock->set(ByteArray::enc32be($ciphertextLength >> 29), 8);
+ $lengthBlock->set(ByteArray::enc32be($ciphertextLength << 3), 12);
+
+ $state->update($lengthBlock);
+ $output = $state->x->exclusiveOr($state->hf);
+
+ // Zeroize the internal values as a best-effort.
+ $state->buf->zeroize();
+ $state->x->zeroize();
+ $state->h->zeroize();
+ $state->hf->zeroize();
+ return $output;
+ }
+
+ /**
+ * Get a specific bit from the provided array, at the given index.
+ *
+ * [01234567], 8+[01234567], 16+[01234567], ...
+ *
+ * @param ByteArray $x
+ * @param int $i
+ * @return int
+ */
+ protected function bit(ByteArray $x, $i)
+ {
+ $byte = $i >> 3;
+ return ($x[$byte] >> ((7 - $i) & 7)) & 1;
+ }
+
+ /**
+ * Galois Field Multiplication
+ *
+ * This function is the critical path that must be constant-time in order to
+ * avoid timing side-channels against AES-GCM.
+ *
+ * The contents of each are always calculated, regardless of the branching
+ * condition, to prevent another kind of timing leak.
+ *
+ * @param ByteArray $x
+ * @param ByteArray $y
+ * @return ByteArray
+ */
+ protected function blockMultiply(ByteArray $x, ByteArray $y)
+ {
+ static $fieldPolynomial = null;
+ if (!$fieldPolynomial) {
+ $fieldPolynomial = new ByteArray([
+ 0xe1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ ]);
+ }
+ self::needs($x->count() === 16, 'Argument 1 must be a ByteArray of exactly 16 bytes');
+ self::needs($y->count() === 16, 'Argument 2 must be a ByteArray of exactly 16 bytes');
+
+ $v = clone $y;
+ $z = new ByteArray(16);
+
+ for ($i = 0; $i < 128; ++$i) {
+ // if ($b) $z = $z->exclusiveOr($v);
+ $b = $this->bit($x, $i);
+ $z = ByteArray::select(
+ $b,
+ $z->exclusiveOr($v),
+ $z
+ );
+
+ // if ($b) $v = $v->exclusiveOr($fieldPolynomial);
+ $b = $v[15] & 1;
+ $v = $v->rshift();
+ $v = ByteArray::select(
+ $b,
+ $v->exclusiveOr($fieldPolynomial),
+ $v
+ );
+ }
+ return $z;
+ }
+
+ /**
+ * Finish processing any leftover bytes in the internal buffer.
+ *
+ * @return self
+ */
+ public function flush()
+ {
+ if ($this->bufLength !== 0) {
+ $this->x = $this->blockMultiply(
+ $this->x->exclusiveOr($this->buf),
+ $this->h
+ );
+ $this->bufLength = 0;
+ }
+ return $this;
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/Key.php b/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/Key.php
new file mode 100644
index 0000000..49d0c69
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/Key.php
@@ -0,0 +1,77 @@
+<?php
+namespace Aws\Crypto\Polyfill;
+
+/**
+ * Class Key
+ *
+ * Wraps a string to keep it hidden from stack traces.
+ *
+ * @package Aws\Crypto\Polyfill
+ */
+class Key
+{
+ /**
+ * @var string $internalString
+ */
+ private $internalString;
+
+ /**
+ * Hide contents of
+ *
+ * @return array
+ */
+ public function __debugInfo()
+ {
+ return [];
+ }
+
+ /**
+ * Key constructor.
+ * @param string $str
+ */
+ public function __construct($str)
+ {
+ $this->internalString = $str;
+ }
+
+ /**
+ * Defense in depth:
+ *
+ * PHP 7.2 includes the Sodium cryptography library, which (among other things)
+ * exposes a function called sodium_memzero() that we can use to zero-fill strings
+ * to minimize the risk of sensitive cryptographic materials persisting in memory.
+ *
+ * If this function is not available, we XOR the string in-place with itself as a
+ * best-effort attempt.
+ */
+ public function __destruct()
+ {
+ if (extension_loaded('sodium') && function_exists('sodium_memzero')) {
+ try {
+ \sodium_memzero($this->internalString);
+ } catch (\SodiumException $ex) {
+ // This is a best effort, but does not provide the same guarantees as sodium_memzero():
+ $this->internalString ^= $this->internalString;
+ }
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function get()
+ {
+ return $this->internalString;
+ }
+
+ /**
+ * @return int
+ */
+ public function length()
+ {
+ if (\is_callable('\\mb_strlen')) {
+ return (int) \mb_strlen($this->internalString, '8bit');
+ }
+ return (int) \strlen($this->internalString);
+ }
+}
diff --git a/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/NeedsTrait.php b/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/NeedsTrait.php
new file mode 100644
index 0000000..5ba4d64
--- /dev/null
+++ b/vendor/aws/aws-sdk-php/src/Crypto/Polyfill/NeedsTrait.php
@@ -0,0 +1,38 @@
+<?php
+namespace Aws\Crypto\Polyfill;
+
+use Aws\Exception\CryptoPolyfillException;
+
+/**
+ * Trait NeedsTrait
+ * @package Aws\Crypto\Polyfill
+ */
+trait NeedsTrait
+{
+ /**
+ * Preconditions, postconditions, and loop invariants are very
+ * useful for safe programing. They also document the specifications.
+ * This function is to help simplify the semantic burden of parsing
+ * these constructions.
+ *
+ * Instead of constructions like
+ * if (!(GOOD CONDITION)) {
+ * throw new \Exception('condition not true');
+ * }
+ *
+ * you can write:
+ * needs(GOOD CONDITION, 'condition not true');
+ * @param $condition
+ * @param $errorMessage
+ * @param null $exceptionClass
+ */
+ public static function needs($condition, $errorMessage, $exceptionClass = null)
+ {
+ if (!$condition) {
+ if (!$exceptionClass) {
+ $exceptionClass = CryptoPolyfillException::class;
+ }
+ throw new $exceptionClass($errorMessage);
+ }
+ }
+}