PluginProbe ʕ •ᴥ•ʔ
Transferito: WP Migration / trunk
Transferito: WP Migration vtrunk
trunk 11.4.0 12.0.0 13.1.0 14.0.0 14.0.11 14.0.7 14.1.0 14.1.1 14.1.2 14.1.3 14.1.4
transferito / vendor / aws / aws-sdk-php / src / Crypto / DecryptionTrait.php
transferito / vendor / aws / aws-sdk-php / src / Crypto Last commit date
Cipher 11 months ago Polyfill 11 months ago AbstractCryptoClient.php 11 months ago AbstractCryptoClientV2.php 11 months ago AesDecryptingStream.php 11 months ago AesEncryptingStream.php 11 months ago AesGcmDecryptingStream.php 11 months ago AesGcmEncryptingStream.php 11 months ago AesStreamInterface.php 11 months ago AesStreamInterfaceV2.php 11 months ago DecryptionTrait.php 11 months ago DecryptionTraitV2.php 11 months ago EncryptionTrait.php 11 months ago EncryptionTraitV2.php 11 months ago KmsMaterialsProvider.php 11 months ago KmsMaterialsProviderV2.php 11 months ago MaterialsProvider.php 11 months ago MaterialsProviderInterface.php 11 months ago MaterialsProviderInterfaceV2.php 11 months ago MaterialsProviderV2.php 11 months ago MetadataEnvelope.php 11 months ago MetadataStrategyInterface.php 11 months ago
DecryptionTrait.php
182 lines
1 <?php
2 namespace Aws\Crypto;
3
4 use GuzzleHttp\Psr7;
5 use GuzzleHttp\Psr7\LimitStream;
6 use Psr\Http\Message\StreamInterface;
7
8 trait DecryptionTrait
9 {
10 /**
11 * Dependency to reverse lookup the openssl_* cipher name from the AESName
12 * in the MetadataEnvelope.
13 *
14 * @param $aesName
15 *
16 * @return string
17 *
18 * @internal
19 */
20 abstract protected function getCipherFromAesName($aesName);
21
22 /**
23 * Dependency to generate a CipherMethod from a set of inputs for loading
24 * in to an AesDecryptingStream.
25 *
26 * @param string $cipherName Name of the cipher to generate for decrypting.
27 * @param string $iv Base Initialization Vector for the cipher.
28 * @param int $keySize Size of the encryption key, in bits, that will be
29 * used.
30 *
31 * @return Cipher\CipherMethod
32 *
33 * @internal
34 */
35 abstract protected function buildCipherMethod($cipherName, $iv, $keySize);
36
37 /**
38 * Builds an AesStreamInterface using cipher options loaded from the
39 * MetadataEnvelope and MaterialsProvider. Can decrypt data from both the
40 * legacy and V2 encryption client workflows.
41 *
42 * @param string $cipherText Plain-text data to be encrypted using the
43 * materials, algorithm, and data provided.
44 * @param MaterialsProviderInterface $provider A provider to supply and encrypt
45 * materials used in encryption.
46 * @param MetadataEnvelope $envelope A storage envelope for encryption
47 * metadata to be read from.
48 * @param array $cipherOptions Additional verification options.
49 *
50 * @return AesStreamInterface
51 *
52 * @throws \InvalidArgumentException Thrown when a value in $cipherOptions
53 * is not valid.
54 *
55 * @internal
56 */
57 public function decrypt(
58 $cipherText,
59 MaterialsProviderInterface $provider,
60 MetadataEnvelope $envelope,
61 array $cipherOptions = []
62 ) {
63 $cipherOptions['Iv'] = base64_decode(
64 $envelope[MetadataEnvelope::IV_HEADER]
65 );
66
67 $cipherOptions['TagLength'] =
68 $envelope[MetadataEnvelope::CRYPTO_TAG_LENGTH_HEADER] / 8;
69
70 $cek = $provider->decryptCek(
71 base64_decode(
72 $envelope[MetadataEnvelope::CONTENT_KEY_V2_HEADER]
73 ),
74 json_decode(
75 $envelope[MetadataEnvelope::MATERIALS_DESCRIPTION_HEADER],
76 true
77 )
78 );
79 $cipherOptions['KeySize'] = strlen($cek) * 8;
80 $cipherOptions['Cipher'] = $this->getCipherFromAesName(
81 $envelope[MetadataEnvelope::CONTENT_CRYPTO_SCHEME_HEADER]
82 );
83
84 $decryptionStream = $this->getDecryptingStream(
85 $cipherText,
86 $cek,
87 $cipherOptions
88 );
89 unset($cek);
90
91 return $decryptionStream;
92 }
93
94 private function getTagFromCiphertextStream(
95 StreamInterface $cipherText,
96 $tagLength
97 ) {
98 $cipherTextSize = $cipherText->getSize();
99 if ($cipherTextSize == null || $cipherTextSize <= 0) {
100 throw new \RuntimeException('Cannot decrypt a stream of unknown'
101 . ' size.');
102 }
103 return (string) new LimitStream(
104 $cipherText,
105 $tagLength,
106 $cipherTextSize - $tagLength
107 );
108 }
109
110 private function getStrippedCiphertextStream(
111 StreamInterface $cipherText,
112 $tagLength
113 ) {
114 $cipherTextSize = $cipherText->getSize();
115 if ($cipherTextSize == null || $cipherTextSize <= 0) {
116 throw new \RuntimeException('Cannot decrypt a stream of unknown'
117 . ' size.');
118 }
119 return new LimitStream(
120 $cipherText,
121 $cipherTextSize - $tagLength,
122 0
123 );
124 }
125
126 /**
127 * Generates a stream that wraps the cipher text with the proper cipher and
128 * uses the content encryption key (CEK) to decrypt the data when read.
129 *
130 * @param string $cipherText Plain-text data to be encrypted using the
131 * materials, algorithm, and data provided.
132 * @param string $cek A content encryption key for use by the stream for
133 * encrypting the plaintext data.
134 * @param array $cipherOptions Options for use in determining the cipher to
135 * be used for encrypting data.
136 *
137 * @return AesStreamInterface
138 *
139 * @internal
140 */
141 protected function getDecryptingStream(
142 $cipherText,
143 $cek,
144 $cipherOptions
145 ) {
146 $cipherTextStream = Psr7\Utils::streamFor($cipherText);
147 switch ($cipherOptions['Cipher']) {
148 case 'gcm':
149 $cipherOptions['Tag'] = $this->getTagFromCiphertextStream(
150 $cipherTextStream,
151 $cipherOptions['TagLength']
152 );
153
154 return new AesGcmDecryptingStream(
155 $this->getStrippedCiphertextStream(
156 $cipherTextStream,
157 $cipherOptions['TagLength']
158 ),
159 $cek,
160 $cipherOptions['Iv'],
161 $cipherOptions['Tag'],
162 $cipherOptions['Aad'] = isset($cipherOptions['Aad'])
163 ? $cipherOptions['Aad']
164 : '',
165 $cipherOptions['TagLength'] ?: null,
166 $cipherOptions['KeySize']
167 );
168 default:
169 $cipherMethod = $this->buildCipherMethod(
170 $cipherOptions['Cipher'],
171 $cipherOptions['Iv'],
172 $cipherOptions['KeySize']
173 );
174 return new AesDecryptingStream(
175 $cipherTextStream,
176 $cek,
177 $cipherMethod
178 );
179 }
180 }
181 }
182