Beispiel #1
0
    async def multipart_upload(self,
                               Bucket=None,
                               Key=None,
                               Body=None,
                               ACL=None,
                               config=None,
                               callback=None,
                               **kwargs):

        if config is None:
            config = boto3.s3.transfer.TransferConfig()

        context = {'raw_body': Body}
        handler = EncryptionHandler(self.key_provider, self.encryption_mode)
        # with concurrent.futures.ThreadPoolExecutor() as pool:
        #     context = await self.loop.run_in_executor(
        #         pool, handler.build_request_context, context)

        if S3Action.MULTIPART_UPLOAD not in handler.actions_for_cipher():
            raise ValueError(
                'Current cipher can not be used for full multipart upload')

        context = handler.build_request_context(context)
        if ACL is not None:
            kwargs['ACL'] = ACL

        kwargs.update({'Metadata': context['envelope']})
        f = io.BytesIO(context['body'].full_data)

        await self.client.upload_fileobj(f,
                                         Bucket=Bucket,
                                         Key=Key,
                                         ExtraArgs=kwargs.copy(),
                                         Callback=callback,
                                         Config=config)
Beispiel #2
0
 def put_object(self, Bucket=None, Key=None, Body=None, ACL=None):
     context = {'raw_body': Body, 'cipher': crypto.aes_cipher(mode='CBC')}
     handler = EncryptionHandler(self.key_provider)
     context = handler.build_request_context(context)
     kwargs = {
         'Bucket': Bucket,
         'Key': Key,
         'Body': context['body'],
         'Metadata': context['envelope']
     }
     if ACL is not None:
         kwargs['ACL'] = ACL
     self.client.put_object(**kwargs)
Beispiel #3
0
    def test_build_envelope(self):
        from s3_encryption.handler import EncryptionHandler
        from s3_encryption import crypto
        cipher = crypto.aes_cipher(mode='CBC')
        cipher.iv = crypto.aes_iv()
        cipher.key = crypto.aes_key()

        handler = EncryptionHandler(self.mock_provider)
        envelope = handler.build_envelope(cipher)

        assert_equal(envelope['x-amz-key'], self.encrypted_key)
        assert_equal(envelope['x-amz-iv'], self.encode64(self.iv))
        assert_equal(envelope['x-amz-matdesc'], self.matdesc)
Beispiel #4
0
    def test_build_request_context(self):
        from s3_encryption.handler import EncryptionHandler
        old_build_env = EncryptionHandler.build_envelope
        EncryptionHandler.build_envelope = lambda x, y: self.matdesc

        handler = EncryptionHandler(self.mock_provider)

        context = handler.build_request_context(self.base_request_context)

        EncryptionHandler.build_envelope = old_build_env

        assert_equal(context['body'], self.encrypted_body)
        assert_equal(context['envelope'], self.matdesc)
Beispiel #5
0
    def test_build_envelope(self):
        from s3_encryption.handler import EncryptionHandler
        from s3_encryption import crypto
        cipher = crypto.aes_cipher(mode='CBC')
        cipher.iv = crypto.aes_iv()
        cipher.key = crypto.aes_key()

        handler = EncryptionHandler(self.mock_provider)
        envelope = handler.build_envelope(cipher)

        assert_equal(envelope['x-amz-key'], self.encrypted_key)
        assert_equal(envelope['x-amz-iv'], self.encode64(self.iv))
        assert_equal(envelope['x-amz-matdesc'], self.matdesc)
Beispiel #6
0
    def test_build_request_context(self):
        from s3_encryption.handler import EncryptionHandler
        old_build_env = EncryptionHandler.build_envelope
        EncryptionHandler.build_envelope = lambda x, y: self.matdesc

        handler = EncryptionHandler(self.mock_provider)

        context = handler.build_request_context(self.base_request_context)

        EncryptionHandler.build_envelope = old_build_env

        assert_equal(context['body'], self.encrypted_body)
        assert_equal(context['envelope'], self.matdesc)
    def multipart_upload(self,
                         Bucket=None,
                         Key=None,
                         Body=None,
                         ACL=None,
                         part_size=None,
                         **kwargs):
        context = {'raw_body': Body, 'cipher': crypto.aes_cipher(mode='CBC')}
        handler = EncryptionHandler(self.key_provider)
        context = handler.build_request_context(context)
        if ACL is not None:
            kwargs['ACL'] = ACL
        bucket = self.resource.Object(Bucket, Key)
        kwargs.update({'Metadata': context['envelope']})
        multipart_upload = bucket.initiate_multipart_upload(**kwargs)

        result = None

        try:
            f = io.BytesIO(context['body'])
            parts = []
            current_part = 0
            chunk = f.read(part_size)
            part = multipart_upload.Part(current_part)
            response = part.upload(Body=chunk)
            parts.append({
                'PartNumber': current_part,
                'ETag': response['ETag']
            })

            chunk = f.read(part_size)
            while chunk:
                current_part += 1
                part = multipart_upload.Part(current_part)
                response = part.upload(Body=chunk)
                parts.append({
                    'PartNumber': current_part,
                    'ETag': response['ETag']
                })
                chunk = f.read(part_size)

            result = multipart_upload.complete(
                MultipartUpload={'Parts': parts.copy()})
        except Exception as e:
            response = multipart_upload.abort()
            raise e

        return result
Beispiel #8
0
 def put_object(self, Bucket=None, Key=None, Body=None, ACL=None):
     context = {
         'raw_body': Body,
         'cipher': crypto.aes_cipher(mode='CBC')
     }
     handler = EncryptionHandler(self.key_provider)
     context = handler.build_request_context(context)
     kwargs = {
        'Bucket': Bucket,
        'Key': Key,
        'Body': context['body'],
        'Metadata': context['envelope']
     }
     if ACL is not None:
         kwargs['ACL'] = ACL
     self.client.put_object(**kwargs)
Beispiel #9
0
    def get_handler(self):
        '''
        Generates an EncryptionHandler for the current key_provider
        and client encryption mode

        Be careful since a new data key will be generated for each handler.
        '''
        return EncryptionHandler(self.key_provider, self.encryption_mode)