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 / EncryptionTrait.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
EncryptionTrait.php
193 lines
1 <?php
2 namespace Aws\Crypto;
3
4 use GuzzleHttp\Psr7;
5 use GuzzleHttp\Psr7\AppendStream;
6 use GuzzleHttp\Psr7\Stream;
7
8 trait EncryptionTrait
9 {
10 private static $allowedOptions = [
11 'Cipher' => true,
12 'KeySize' => true,
13 'Aad' => true,
14 ];
15
16 /**
17 * Dependency to generate a CipherMethod from a set of inputs for loading
18 * in to an AesEncryptingStream.
19 *
20 * @param string $cipherName Name of the cipher to generate for encrypting.
21 * @param string $iv Base Initialization Vector for the cipher.
22 * @param int $keySize Size of the encryption key, in bits, that will be
23 * used.
24 *
25 * @return Cipher\CipherMethod
26 *
27 * @internal
28 */
29 abstract protected function buildCipherMethod($cipherName, $iv, $keySize);
30
31 /**
32 * Builds an AesStreamInterface and populates encryption metadata into the
33 * supplied envelope.
34 *
35 * @param Stream $plaintext Plain-text data to be encrypted using the
36 * materials, algorithm, and data provided.
37 * @param array $cipherOptions Options for use in determining the cipher to
38 * be used for encrypting data.
39 * @param MaterialsProvider $provider A provider to supply and encrypt
40 * materials used in encryption.
41 * @param MetadataEnvelope $envelope A storage envelope for encryption
42 * metadata to be added to.
43 *
44 * @return AesStreamInterface
45 *
46 * @throws \InvalidArgumentException Thrown when a value in $cipherOptions
47 * is not valid.
48 *
49 * @internal
50 */
51 public function encrypt(
52 Stream $plaintext,
53 array $cipherOptions,
54 MaterialsProvider $provider,
55 MetadataEnvelope $envelope
56 ) {
57 $materialsDescription = $provider->getMaterialsDescription();
58
59 $cipherOptions = array_intersect_key(
60 $cipherOptions,
61 self::$allowedOptions
62 );
63
64 if (empty($cipherOptions['Cipher'])) {
65 throw new \InvalidArgumentException('An encryption cipher must be'
66 . ' specified in the "cipher_options".');
67 }
68
69 if (!self::isSupportedCipher($cipherOptions['Cipher'])) {
70 throw new \InvalidArgumentException('The cipher requested is not'
71 . ' supported by the SDK.');
72 }
73
74 if (empty($cipherOptions['KeySize'])) {
75 $cipherOptions['KeySize'] = 256;
76 }
77 if (!is_int($cipherOptions['KeySize'])) {
78 throw new \InvalidArgumentException('The cipher "KeySize" must be'
79 . ' an integer.');
80 }
81
82 if (!MaterialsProvider::isSupportedKeySize(
83 $cipherOptions['KeySize']
84 )) {
85 throw new \InvalidArgumentException('The cipher "KeySize" requested'
86 . ' is not supported by AES (128, 192, or 256).');
87 }
88
89 $cipherOptions['Iv'] = $provider->generateIv(
90 $this->getCipherOpenSslName(
91 $cipherOptions['Cipher'],
92 $cipherOptions['KeySize']
93 )
94 );
95
96 $cek = $provider->generateCek($cipherOptions['KeySize']);
97
98 list($encryptingStream, $aesName) = $this->getEncryptingStream(
99 $plaintext,
100 $cek,
101 $cipherOptions
102 );
103
104 // Populate envelope data
105 $envelope[MetadataEnvelope::CONTENT_KEY_V2_HEADER] =
106 $provider->encryptCek(
107 $cek,
108 $materialsDescription
109 );
110 unset($cek);
111
112 $envelope[MetadataEnvelope::IV_HEADER] =
113 base64_encode($cipherOptions['Iv']);
114 $envelope[MetadataEnvelope::KEY_WRAP_ALGORITHM_HEADER] =
115 $provider->getWrapAlgorithmName();
116 $envelope[MetadataEnvelope::CONTENT_CRYPTO_SCHEME_HEADER] = $aesName;
117 $envelope[MetadataEnvelope::UNENCRYPTED_CONTENT_LENGTH_HEADER] =
118 strlen($plaintext);
119 $envelope[MetadataEnvelope::MATERIALS_DESCRIPTION_HEADER] =
120 json_encode($materialsDescription);
121 if (!empty($cipherOptions['Tag'])) {
122 $envelope[MetadataEnvelope::CRYPTO_TAG_LENGTH_HEADER] =
123 strlen($cipherOptions['Tag']) * 8;
124 }
125
126 return $encryptingStream;
127 }
128
129 /**
130 * Generates a stream that wraps the plaintext with the proper cipher and
131 * uses the content encryption key (CEK) to encrypt the data when read.
132 *
133 * @param Stream $plaintext Plain-text data to be encrypted using the
134 * materials, algorithm, and data provided.
135 * @param string $cek A content encryption key for use by the stream for
136 * encrypting the plaintext data.
137 * @param array $cipherOptions Options for use in determining the cipher to
138 * be used for encrypting data.
139 *
140 * @return [AesStreamInterface, string]
141 *
142 * @internal
143 */
144 protected function getEncryptingStream(
145 Stream $plaintext,
146 $cek,
147 &$cipherOptions
148 ) {
149 switch ($cipherOptions['Cipher']) {
150 case 'gcm':
151 $cipherOptions['TagLength'] = 16;
152
153 $cipherTextStream = new AesGcmEncryptingStream(
154 $plaintext,
155 $cek,
156 $cipherOptions['Iv'],
157 $cipherOptions['Aad'] = isset($cipherOptions['Aad'])
158 ? $cipherOptions['Aad']
159 : '',
160 $cipherOptions['TagLength'],
161 $cipherOptions['KeySize']
162 );
163
164 if (!empty($cipherOptions['Aad'])) {
165 trigger_error("'Aad' has been supplied for content encryption"
166 . " with " . $cipherTextStream->getAesName() . ". The"
167 . " PHP SDK encryption client can decrypt an object"
168 . " encrypted in this way, but other AWS SDKs may not be"
169 . " able to.", E_USER_WARNING);
170 }
171
172 $appendStream = new AppendStream([
173 $cipherTextStream->createStream()
174 ]);
175 $cipherOptions['Tag'] = $cipherTextStream->getTag();
176 $appendStream->addStream(Psr7\Utils::streamFor($cipherOptions['Tag']));
177 return [$appendStream, $cipherTextStream->getAesName()];
178 default:
179 $cipherMethod = $this->buildCipherMethod(
180 $cipherOptions['Cipher'],
181 $cipherOptions['Iv'],
182 $cipherOptions['KeySize']
183 );
184 $cipherTextStream = new AesEncryptingStream(
185 $plaintext,
186 $cek,
187 $cipherMethod
188 );
189 return [$cipherTextStream, $cipherTextStream->getAesName()];
190 }
191 }
192 }
193