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
KmsMaterialsProviderV2.php
101 lines
| 1 | <?php |
| 2 | namespace Aws\Crypto; |
| 3 | |
| 4 | use Aws\Exception\CryptoException; |
| 5 | use Aws\Kms\KmsClient; |
| 6 | |
| 7 | /** |
| 8 | * Uses KMS to supply materials for encrypting and decrypting data. This |
| 9 | * V2 implementation should be used with the V2 encryption clients (i.e. |
| 10 | * S3EncryptionClientV2). |
| 11 | */ |
| 12 | class KmsMaterialsProviderV2 extends MaterialsProviderV2 implements MaterialsProviderInterfaceV2 |
| 13 | { |
| 14 | const WRAP_ALGORITHM_NAME = 'kms+context'; |
| 15 | |
| 16 | private $kmsClient; |
| 17 | private $kmsKeyId; |
| 18 | |
| 19 | /** |
| 20 | * @param KmsClient $kmsClient A KMS Client for use encrypting and |
| 21 | * decrypting keys. |
| 22 | * @param string $kmsKeyId The private KMS key id to be used for encrypting |
| 23 | * and decrypting keys. |
| 24 | */ |
| 25 | public function __construct( |
| 26 | KmsClient $kmsClient, |
| 27 | $kmsKeyId = null |
| 28 | ) { |
| 29 | $this->kmsClient = $kmsClient; |
| 30 | $this->kmsKeyId = $kmsKeyId; |
| 31 | } |
| 32 | |
| 33 | /** |
| 34 | * @inheritDoc |
| 35 | */ |
| 36 | public function getWrapAlgorithmName() |
| 37 | { |
| 38 | return self::WRAP_ALGORITHM_NAME; |
| 39 | } |
| 40 | |
| 41 | /** |
| 42 | * @inheritDoc |
| 43 | */ |
| 44 | public function decryptCek($encryptedCek, $materialDescription, $options) |
| 45 | { |
| 46 | $params = [ |
| 47 | 'CiphertextBlob' => $encryptedCek, |
| 48 | 'EncryptionContext' => $materialDescription |
| 49 | ]; |
| 50 | if (empty($options['@KmsAllowDecryptWithAnyCmk'])) { |
| 51 | if (empty($this->kmsKeyId)) { |
| 52 | throw new CryptoException('KMS CMK ID was not specified and the' |
| 53 | . ' operation is not opted-in to attempting to use any valid' |
| 54 | . ' CMK it discovers. Please specify a CMK ID, or explicitly' |
| 55 | . ' enable attempts to use any valid KMS CMK with the' |
| 56 | . ' @KmsAllowDecryptWithAnyCmk option.'); |
| 57 | } |
| 58 | $params['KeyId'] = $this->kmsKeyId; |
| 59 | } |
| 60 | |
| 61 | $result = $this->kmsClient->decrypt($params); |
| 62 | return $result['Plaintext']; |
| 63 | } |
| 64 | |
| 65 | /** |
| 66 | * @inheritDoc |
| 67 | */ |
| 68 | public function generateCek($keySize, $context, $options) |
| 69 | { |
| 70 | if (empty($this->kmsKeyId)) { |
| 71 | throw new CryptoException('A KMS key id is required for encryption' |
| 72 | . ' with KMS keywrap. Use a KmsMaterialsProviderV2 that has been' |
| 73 | . ' instantiated with a KMS key id.'); |
| 74 | } |
| 75 | $options = array_change_key_case($options); |
| 76 | if (!isset($options['@kmsencryptioncontext']) |
| 77 | || !is_array($options['@kmsencryptioncontext']) |
| 78 | ) { |
| 79 | throw new CryptoException("'@KmsEncryptionContext' is a" |
| 80 | . " required argument when using KmsMaterialsProviderV2, and" |
| 81 | . " must be an associative array (or empty array)."); |
| 82 | } |
| 83 | if (isset($options['@kmsencryptioncontext']['aws:x-amz-cek-alg'])) { |
| 84 | throw new CryptoException("Conflict in reserved @KmsEncryptionContext" |
| 85 | . " key aws:x-amz-cek-alg. This value is reserved for the S3" |
| 86 | . " Encryption Client and cannot be set by the user."); |
| 87 | } |
| 88 | $context = array_merge($options['@kmsencryptioncontext'], $context); |
| 89 | $result = $this->kmsClient->generateDataKey([ |
| 90 | 'KeyId' => $this->kmsKeyId, |
| 91 | 'KeySpec' => "AES_{$keySize}", |
| 92 | 'EncryptionContext' => $context |
| 93 | ]); |
| 94 | return [ |
| 95 | 'Plaintext' => $result['Plaintext'], |
| 96 | 'Ciphertext' => base64_encode($result['CiphertextBlob']), |
| 97 | 'UpdatedContext' => $context |
| 98 | ]; |
| 99 | } |
| 100 | } |
| 101 |