Beispiel #1
0
    def test_init(self):
        with self.assertRaises(AssertionError):
            S3EncryptionClient(key_provider='invalid_object')

        client = S3EncryptionClient(key_provider=self.kms_client)
        self.assertIs(client._key_provider, self.kms_client)
        self.assertRegexpMatches(str(client._client),
                                 "<botocore.client.S3 object at 0x.*?>")
Beispiel #2
0
    def test_get_object(self):
        from botocore.exceptions import ClientError
        s3_key = 'dummy'

        encryption_client = S3EncryptionClient(key_provider=self.kms_client)
        encryption_client._client = mock.MagicMock()
        encryption_client._client.get_object = mock.Mock(
            side_effect=ClientError({'Error': {
                'Code': 'Unknown Error'
            }}, 'S3'))

        with self.assertRaises(ConfigurationFileNotFoundError):
            encryption_client.get_object(bucket=self.s3_bucket, key=s3_key)

        encryption_client._client.get_object.assert_called_once_with(
            Bucket=self.s3_bucket, Key=s3_key)

        encryption_client = S3EncryptionClient(key_provider=self.kms_client)
        encryption_client._client = mock.MagicMock()
        encryption_client._client.get_object = mock.MagicMock(
            return_value={
                'Metadata': self.s3_metadata,
                'Body': StringIO(base64.b64decode(self.base64_encrypted_data))
            })
        encryption_client._key_provider = mock.MagicMock()
        encryption_client._key_provider.decrypt = \
            mock.MagicMock(
                return_value=base64.b64decode(
                    self.base64_plaintext_envelope_key
                )
            )

        result = encryption_client.get_object(bucket=self.s3_bucket,
                                              key=s3_key)

        encryption_client._key_provider.decrypt.assert_called_once_with(
            encrypted_content=base64.b64decode(
                self.s3_metadata['x-amz-key-v2']),
            encryption_context=json.loads(self.s3_metadata['x-amz-matdesc']))

        self.assertDictEqual(result, {
            'Body': self.plaintext_data,
            'Metadata': self.s3_metadata
        })
Beispiel #3
0
 def test_encrypt(self):
     client = S3EncryptionClient(key_provider=self.kms_client)
     for chunk_size in (16, 32):
         encrypted_content = client.encrypt(
             content=self.plaintext_data,
             key=base64.b64decode(self.base64_plaintext_envelope_key),
             iv=base64.b64decode(self.s3_metadata['x-amz-iv']),
             chunk_size=chunk_size)
         base64_encrypted_content = base64.b64encode(encrypted_content)
         self.assertEqual(base64_encrypted_content,
                          self.base64_encrypted_data)
Beispiel #4
0
    def __init__(self, kms_alias, region=None, display=None, stream=None):
        stream = stream or sys.stderr
        logger = display or module_logger
        self._logger = logger

        # If no display is provided, the module_logger is configured and used.
        if isinstance(self._logger, logging.Logger):
            self._configure_logger(stream=stream)

        self._encryption_backend = S3EncryptionClient(
            key_provider=KMSClient(alias=kms_alias, region=region)
        )
Beispiel #5
0
 def test_decrypt(self):
     client = S3EncryptionClient(key_provider=self.kms_client)
     for chunk_size in (16, 32, 48, 64):
         encrypted_content = StringIO(
             base64.b64decode(self.base64_encrypted_data))
         decrypted = client.decrypt(
             content=encrypted_content,
             key=base64.b64decode(self.base64_plaintext_envelope_key),
             iv=base64.b64decode(self.s3_metadata['x-amz-iv']),
             unencrypted_length=int(
                 self.s3_metadata['x-amz-unencrypted-content-length']),
             chunk_size=chunk_size)
         self.assertEqual(decrypted, self.plaintext_data)
Beispiel #6
0
    def test_prepare_encryption_metadata(self):
        unencrypted_length = 10
        metadata = dict(encrypted_envelope_key='test_envelope_key',
                        iv='test_iv',
                        encryption_context={'ctx': 'a'},
                        unencrypted_content_length=unencrypted_length)

        result = S3EncryptionClient._prepare_encryption_metadata(**metadata)
        self.assertDictEqual(
            result, {
                'x-amz-key-v2': to_base64(metadata['encrypted_envelope_key']),
                'x-amz-iv': to_base64(metadata['iv']),
                'x-amz-cek-alg': 'AES/CBC/PKCS5Padding',
                'x-amz-wrap-alg': 'kms',
                'x-amz-matdesc': '{"ctx":"a"}',
                'x-amz-unencrypted-content-length': str(unencrypted_length)
            })
Beispiel #7
0
    def test_put_object(self):
        s3_key = 'dummy'

        encryption_client = S3EncryptionClient(key_provider=self.kms_client)
        encryption_client._key_provider = mock.MagicMock()
        encryption_client._key_provider.generate_envelope_key = \
            mock.MagicMock(
                return_value={
                    'Plaintext': base64.b64decode(
                        self.base64_plaintext_envelope_key
                    ),
                    'CiphertextBlob': base64.b64decode(
                        self.s3_metadata['x-amz-key-v2']
                    ),
                    'EncryptionContext': json.loads(
                        self.s3_metadata['x-amz-matdesc']
                    )
                }
            )
        encryption_client._client = mock.MagicMock()
        encryption_client._client.put_object = mock.MagicMock(
            return_value={'tested-operation': 's3_put_object'})

        iv = base64.b64decode(self.s3_metadata['x-amz-iv'])
        crypto_random = StringIO(iv)

        mock_generate_envelope_key = \
            encryption_client._key_provider.generate_envelope_key

        mock_put_object = encryption_client._client.put_object

        with mock.patch.object(Random, 'new', return_value=crypto_random):
            result = encryption_client.put_object(bucket=self.s3_bucket,
                                                  key=s3_key,
                                                  body=self.plaintext_data)
            mock_generate_envelope_key.assert_called_once_with()
            self.assertDictEqual(result, {'tested-operation': 's3_put_object'})
            mock_put_object.assert_called_once_with(
                Body=base64.b64decode(self.base64_encrypted_data),
                Bucket=self.s3_bucket,
                Key=s3_key,
                Metadata=self.s3_metadata,
                ServerSideEncryption='AES256')
Beispiel #8
0
    def test_get_object_update_alias_from_metadata(self):
        s3_key = 'dummy'

        kms_client = KMSClient(alias=None)
        encryption_client = S3EncryptionClient(key_provider=kms_client)

        original_set_alias = kms_client.set_alias

        self.assertIsNone(encryption_client._key_provider.alias)

        encryption_client._client = mock.MagicMock()
        encryption_client._client.get_object = mock.MagicMock(
            return_value={
                'Metadata': self.s3_metadata,
                'Body': StringIO(base64.b64decode(self.base64_encrypted_data))
            })
        encryption_client._key_provider = mock.MagicMock()
        encryption_client._key_provider.decrypt = \
            mock.MagicMock(
                return_value=base64.b64decode(
                    self.base64_plaintext_envelope_key
                )
            )

        mock_get_key_alias = encryption_client._key_provider.get_key_alias = \
            mock.MagicMock(return_value='test')

        encryption_client._key_provider.alias = None
        mock_set_alias = encryption_client._key_provider.set_alias = \
            mock.MagicMock(side_effect=original_set_alias)

        encryption_client.get_object(bucket=self.s3_bucket, key=s3_key)

        mock_get_key_alias.assert_called_once_with(
            key_id=json.loads(self.s3_metadata['x-amz-matdesc'])['kms_cmk_id'])
        mock_set_alias.assert_called_once_with('test')
        self.assertEqual(kms_client._alias, 'alias/test')