Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
}