decryptCek(base64_decode($envelope[\UglyRobot\Infinite_Uploads\Aws\Crypto\MetadataEnvelope::CONTENT_KEY_V2_HEADER]), json_decode($envelope[\UglyRobot\Infinite_Uploads\Aws\Crypto\MetadataEnvelope::MATERIALS_DESCRIPTION_HEADER], true)); $cipherOptions['KeySize'] = strlen($cek) * 8; $cipherOptions['Cipher'] = $this->getCipherFromAesName($envelope[\UglyRobot\Infinite_Uploads\Aws\Crypto\MetadataEnvelope::CONTENT_CRYPTO_SCHEME_HEADER]); $decryptionStream = $this->getDecryptingStream($cipherText, $cek, $cipherOptions); unset($cek); return $decryptionStream; } private function getTagFromCiphertextStream(\UglyRobot\Infinite_Uploads\Psr\Http\Message\StreamInterface $cipherText, $tagLength) { $cipherTextSize = $cipherText->getSize(); if ($cipherTextSize == null || $cipherTextSize <= 0) { throw new \RuntimeException('Cannot decrypt a stream of unknown' . ' size.'); } return (string) new \UglyRobot\Infinite_Uploads\GuzzleHttp\Psr7\LimitStream($cipherText, $tagLength, $cipherTextSize - $tagLength); } private function getStrippedCiphertextStream(\UglyRobot\Infinite_Uploads\Psr\Http\Message\StreamInterface $cipherText, $tagLength) { $cipherTextSize = $cipherText->getSize(); if ($cipherTextSize == null || $cipherTextSize <= 0) { throw new \RuntimeException('Cannot decrypt a stream of unknown' . ' size.'); } return new \UglyRobot\Infinite_Uploads\GuzzleHttp\Psr7\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 = \UglyRobot\Infinite_Uploads\GuzzleHttp\Psr7\stream_for($cipherText); switch ($cipherOptions['Cipher']) { case 'gcm': $cipherOptions['Tag'] = $this->getTagFromCiphertextStream($cipherTextStream, $cipherOptions['TagLength']); return new \UglyRobot\Infinite_Uploads\Aws\Crypto\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 \UglyRobot\Infinite_Uploads\Aws\Crypto\AesDecryptingStream($cipherTextStream, $cek, $cipherMethod); } } }