| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 | 
							- <?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']
 
-                         : '',
 
-                     $cipherOptions['TagLength'] ?: null,
 
-                     $cipherOptions['KeySize']
 
-                 );
 
-             default:
 
-                 $cipherMethod = $this->buildCipherMethod(
 
-                     $cipherOptions['Cipher'],
 
-                     $cipherOptions['Iv'],
 
-                     $cipherOptions['KeySize']
 
-                 );
 
-                 return new AesDecryptingStream(
 
-                     $cipherTextStream,
 
-                     $cek,
 
-                     $cipherMethod
 
-                 );
 
-         }
 
-     }
 
- }
 
 
  |