def test_kms_with_error_parameter(self):
        if oss2.compat.is_py3:
            return

        def assertKmsFuncRaises(kms, error=OpenApiServerError):
            self.assertRaises(error, kms.get_key)
            self.assertRaises(error, kms._AliKMSProvider__encrypt_data, '123')
            self.assertRaises(error, kms._AliKMSProvider__decrypt_data, '123')
            self.assertRaises(error, kms._AliKMSProvider__generate_data_key)
            self.assertRaises(error, kms.decrypt_oss_meta_data, {'123': '456'}, '123')

        kms = AliKMSProvider(OSS_ID, OSS_SECRET, OSS_REGION, OSS_CMK)
        plain_key = kms.get_key()

        kms_with_passphrase = AliKMSProvider(OSS_ID, OSS_SECRET, OSS_REGION, OSS_CMK, passphrase='1234')
        plain_key1 = kms_with_passphrase.get_key()
        self.assertRaises(OpenApiServerError, kms_with_passphrase._AliKMSProvider__decrypt_data, plain_key)
        self.assertRaises(OpenApiServerError, kms._AliKMSProvider__decrypt_data, plain_key1)

        kms_with_error_regin = AliKMSProvider(OSS_ID, OSS_SECRET, "123", OSS_CMK)
        assertKmsFuncRaises(kms_with_error_regin, error=ClientError)

        kms_with_error_cmk = AliKMSProvider(OSS_ID, OSS_SECRET, OSS_REGION, '123')
        assertKmsFuncRaises(kms_with_error_cmk)

        kms_with_error_id = AliKMSProvider('123', OSS_SECRET, OSS_REGION, OSS_CMK)
        assertKmsFuncRaises(kms_with_error_id)

        kms_with_error_secret = AliKMSProvider(OSS_ID, '123', OSS_REGION, OSS_CMK)
        assertKmsFuncRaises(kms_with_error_secret)

        self.assertRaises(ClientError, AliKMSProvider, OSS_ID, OSS_SECRET, OSS_REGION, OSS_CMK, cipher=object)
    def test_ali_kms_provider_invalid_region(self):
        provider = AliKMSProvider(OSS_ID, OSS_SECRET, OSS_CMK_REGION, OSS_CMK)
        plain_key, encrypted_key = provider.get_key()
        encrypted_iv = provider.get_iv()

        region_list = [
            'cn-hangzhou', 'cn-shanghai', 'cn-qingdao', 'cn-beijing',
            'cn-zhangjiakou', 'cn-huhehaote', 'cn-shenzhen', 'cn-hongkong',
            'us-west-1', 'us-east-1', 'ap-southeast-1', 'ap-southeast-2',
            'ap-southeast-3', 'ap-southeast-5', 'ap-northeast-1', 'ap-south-1',
            'eu-central-1', 'eu-west-1', 'me-east-1'
        ]

        if OSS_REGION in region_list:
            region_list.remove(OSS_REGION)

        region_num = len(region_list)
        invalid_region = region_list[random.randint(0, region_num - 1)]

        provider_invalid = AliKMSProvider(OSS_ID, OSS_SECRET, invalid_region,
                                          OSS_CMK)
        self.assertRaises(OpenApiServerError,
                          provider_invalid.decrypt_encrypted_key,
                          encrypted_key)
        self.assertRaises(OpenApiServerError,
                          provider_invalid.decrypt_encrypted_key, encrypted_iv)
    def test_kms_with_error_parameter(self):
        if oss2.compat.is_py3:
            return

        def assertKmsFuncRaises(kms, error=OpenApiServerError):
            self.assertRaises(error, kms.get_key)
            self.assertRaises(error, kms._AliKMSProvider__encrypt_data, '123')
            self.assertRaises(error, kms._AliKMSProvider__decrypt_data, '123')
            self.assertRaises(error, kms._AliKMSProvider__generate_data_key)
            self.assertRaises(error, kms.decrypt_oss_meta_data, {'123': '456'},
                              '123')

        kms = AliKMSProvider(OSS_ID, OSS_SECRET, OSS_REGION, OSS_CMK)
        plain_key = kms.get_key()

        kms_with_passphrase = AliKMSProvider(OSS_ID,
                                             OSS_SECRET,
                                             OSS_REGION,
                                             OSS_CMK,
                                             passphrase='1234')
        plain_key1 = kms_with_passphrase.get_key()
        self.assertRaises(OpenApiServerError,
                          kms_with_passphrase._AliKMSProvider__decrypt_data,
                          plain_key)
        self.assertRaises(OpenApiServerError,
                          kms._AliKMSProvider__decrypt_data, plain_key1)

        kms_with_error_regin = AliKMSProvider(OSS_ID, OSS_SECRET, "123",
                                              OSS_CMK)
        assertKmsFuncRaises(kms_with_error_regin, error=ClientError)

        kms_with_error_cmk = AliKMSProvider(OSS_ID, OSS_SECRET, OSS_REGION,
                                            '123')
        assertKmsFuncRaises(kms_with_error_cmk)

        kms_with_error_id = AliKMSProvider('123', OSS_SECRET, OSS_REGION,
                                           OSS_CMK)
        assertKmsFuncRaises(kms_with_error_id)

        kms_with_error_secret = AliKMSProvider(OSS_ID, '123', OSS_REGION,
                                               OSS_CMK)
        assertKmsFuncRaises(kms_with_error_secret)

        self.assertRaises(ClientError,
                          AliKMSProvider,
                          OSS_ID,
                          OSS_SECRET,
                          OSS_REGION,
                          OSS_CMK,
                          cipher=object)
    def test_kms_adapter(self):
        if oss2.compat.is_py33:
            return

        content = b'1234'*10

        kms = AliKMSProvider(OSS_ID, OSS_SECRET, OSS_REGION, OSS_CMK)
        key = kms.get_key()
        start = kms.get_start()
        adapter = kms.make_encrypt_adapter(content, key, start)
        encrypt_content = adapter.read()
        self.assertNotEqual(content, encrypt_content)

        adapter1 = kms.make_decrypt_adapter(encrypt_content, key, start)
        self.assertEqual(content, adapter1.read())
    def test_kms_with_error_response(self):
        if oss2.compat.is_py33:
            return

        kms = AliKMSProvider(OSS_ID, OSS_SECRET, OSS_REGION, OSS_CMK)

        with patch.object(oss2.AliKMSProvider,
                          '_AliKMSProvider__do',
                          return_value={
                              'Plaintext': '123',
                              'CiphertextBlob': '123'
                          },
                          autospect=True):
            self.assertRaises(OpenApiFormatError, kms.get_key)

        with patch.object(client.AcsClient,
                          'do_action_with_exception',
                          return_value='12iof..3',
                          autospect=True):
            self.assertRaises(OpenApiFormatError, kms.get_key)
            self.assertRaises(OpenApiFormatError,
                              kms._AliKMSProvider__encrypt_data, '123')
            self.assertRaises(OpenApiFormatError,
                              kms._AliKMSProvider__decrypt_data, '123')
            self.assertRaises(OpenApiFormatError,
                              kms._AliKMSProvider__generate_data_key)
            self.assertRaises(OpenApiFormatError, kms.decrypt_oss_meta_data,
                              {'1231': '1234'}, '1231')
    def test_ali_kms_provider_basic(self):
        provider = AliKMSProvider(OSS_ID,
                                  OSS_SECRET,
                                  OSS_CMK_REGION,
                                  OSS_CMK,
                                  passphrase=random_string(8))
        self.assertEqual(provider.wrap_alg, "KMS/ALICLOUD")
        self.assertEqual(provider.cipher.alg, "AES/CTR/NoPadding")
        plain_key, encrypted_key = provider.get_key()
        plain_iv = provider.get_iv()

        with patch('oss2.AliKMSProvider.get_key',
                   return_value=[plain_key, encrypted_key]):
            with patch.object(oss2.utils,
                              'random_iv',
                              return_value=plain_iv,
                              autospect=True):
                content_crypto_material = provider.create_content_material()
                self.assertFalse(content_crypto_material.is_unencrypted())
                decrypted_key = provider.decrypt_encrypted_key(
                    content_crypto_material.encrypted_key)
                decrypted_iv = provider.decrypt_encrypted_iv(
                    content_crypto_material.encrypted_iv)
                self.assertEqual(plain_key, decrypted_key)
                self.assertEqual(plain_iv, decrypted_iv)
    def test_ali_kms_provider_diff_passphrase(self):
        provider = AliKMSProvider(OSS_ID,
                                  OSS_SECRET,
                                  OSS_CMK_REGION,
                                  OSS_CMK,
                                  passphrase=random_string(6))
        plain_key, encrypted_key = provider.get_key()
        encrypted_iv = provider.get_iv()

        provider_diff = AliKMSProvider(OSS_ID,
                                       OSS_SECRET,
                                       OSS_CMK_REGION,
                                       OSS_CMK,
                                       passphrase=random_string(8))
        self.assertRaises(OpenApiServerError,
                          provider_diff.decrypt_encrypted_key, encrypted_key)
        self.assertRaises(OpenApiServerError,
                          provider_diff.decrypt_encrypted_iv, encrypted_iv)
    def test_kms_basic(self):
        if oss2.compat.is_py33:
            return

        id, key, token = self.get_sts()

        kms = AliKMSProvider(id, key, OSS_REGION, OSS_CMK, token, passphrase='1234')

        plain_key = kms.get_key()
        iv = kms.get_start()
        header = kms.build_header()
        self.assertEqual(plain_key, kms.decrypt_oss_meta_data(header, 'x-oss-meta-oss-crypto-key'))
        self.assertEqual(iv, kms.decrypt_oss_meta_data(header, 'x-oss-meta-oss-crypto-start', lambda x: int(x)))
        self.assertEqual(None, kms.decrypt_oss_meta_data(header, '1231'))
    def test_ali_kms_with_error_response(self):
        if oss2.compat.is_py33:
            return

        kms = AliKMSProvider(OSS_ID, OSS_SECRET, OSS_CMK_REGION, OSS_CMK)

        # 模拟返回的数据格式不对,不是正确的json格式字符串
        plain_key = random_string(32)
        encrypted_key = random_string(32)
        return_value = "{'Plaintext': %s, 'CiphertextBlob': %s}" % (
            plain_key, encrypted_key)
        with patch.object(client.AcsClient,
                          'do_action_with_exception',
                          return_value=return_value,
                          autospect=True):
            self.assertRaises(OpenApiFormatError, kms.get_key)
    def test_kms_adapter(self):
        if oss2.compat.is_py33:
            return

        content = b'1234' * 10

        kms = AliKMSProvider(OSS_ID, OSS_SECRET, OSS_REGION, OSS_CMK)
        key = kms.get_key()
        start = kms.get_start()
        adapter = kms.make_encrypt_adapter(content, key, start)
        encrypt_content = adapter.read()
        self.assertNotEqual(content, encrypt_content)

        adapter1 = kms.make_decrypt_adapter(encrypt_content, key, start)
        self.assertEqual(content, adapter1.read())
    def test_kms_basic(self):
        if oss2.compat.is_py33:
            return

        id, key, token = self.get_sts()

        kms = AliKMSProvider(id,
                             key,
                             OSS_REGION,
                             OSS_CMK,
                             token,
                             passphrase='1234')

        plain_key = kms.get_key()
        iv = kms.get_start()
        header = kms.build_header()
        self.assertEqual(
            plain_key,
            kms.decrypt_oss_meta_data(header, 'x-oss-meta-oss-crypto-key'))
        self.assertEqual(
            iv,
            kms.decrypt_oss_meta_data(header, 'x-oss-meta-oss-crypto-start',
                                      lambda x: int(x)))
        self.assertEqual(None, kms.decrypt_oss_meta_data(header, '1231'))
    def test_ali_kms_provider_invalid_ak(self):
        provider = AliKMSProvider(OSS_ID, OSS_SECRET, OSS_CMK_REGION, OSS_CMK)
        plain_key, encrypted_key = provider.get_key()
        encrypted_iv = provider.get_iv()

        invalid_secret = random_string(len(OSS_SECRET))
        provider_invalid = AliKMSProvider(OSS_ID, invalid_secret,
                                          OSS_CMK_REGION, OSS_CMK)
        self.assertRaises(OpenApiServerError,
                          provider_invalid.decrypt_encrypted_key,
                          encrypted_key)
        self.assertRaises(OpenApiServerError,
                          provider_invalid.decrypt_encrypted_key, encrypted_iv)

        invald_id = random_string(len(OSS_ID))
        provider_invalid = AliKMSProvider(invald_id, OSS_SECRET,
                                          OSS_CMK_REGION, OSS_CMK)
        self.assertRaises(OpenApiServerError,
                          provider_invalid.decrypt_encrypted_key,
                          encrypted_key)
        self.assertRaises(OpenApiServerError,
                          provider_invalid.decrypt_encrypted_key, encrypted_iv)
    def test_ali_kms_provider_adapter(self):
        provider = AliKMSProvider(OSS_ID, OSS_SECRET, OSS_CMK_REGION, OSS_CMK)
        content = b'a' * random.randint(1, 100) * 1024
        content_crypto_material = provider.create_content_material()

        plain_key = provider.decrypt_encrypted_key(
            content_crypto_material.encrypted_key)
        plain_iv = provider.decrypt_encrypted_iv(
            content_crypto_material.encrypted_iv)
        cipher = content_crypto_material.cipher

        stream_encrypted = provider.make_encrypt_adapter(content, cipher)
        encrypted_content = stream_encrypted.read()
        # reset cipher
        cipher.initialize(plain_key, plain_iv)
        stream_decrypted = provider.make_decrypt_adapter(
            encrypted_content, cipher)
        self.assertEqual(content, stream_decrypted.read())

        # 使用不同的content crypto material
        content_crypto_material_diff = provider.create_content_material()
        plain_key = provider.decrypt_encrypted_key(
            content_crypto_material_diff.encrypted_key)
        plain_iv = provider.decrypt_encrypted_iv(
            content_crypto_material_diff.encrypted_iv)
        cipher = content_crypto_material_diff.cipher

        stream_encrypted_diff = provider.make_encrypt_adapter(content, cipher)
        encrypted_content_diff = stream_encrypted_diff.read()
        self.assertNotEqual(encrypted_content_diff, encrypted_content)
        # reset cipher
        cipher.initialize(plain_key, plain_iv)
        stream_decrypted_diff = provider.make_decrypt_adapter(
            encrypted_content_diff, cipher)
        self.assertEqual(content, stream_decrypted_diff.read())
# 下载全部文件
result = bucket.get_object(multi_key)

# 验证一下
content_got = b''
for chunk in result:
    content_got += chunk
assert content_got[0:102400] == part_a
assert content_got[102400:204800] == part_b
assert content_got[204800:307200] == part_c

# 创建Bucket对象,可以进行客户端数据加密(使用阿里云KMS)
bucket = oss2.CryptoBucket(oss2.Auth(access_key_id, access_key_secret),
                           endpoint,
                           bucket_name,
                           crypto_provider=AliKMSProvider(
                               access_key_id, access_key_secret, region, cmk))

# 上传文件
bucket.put_object(key, content, headers={'content-length': str(1024 * 1024)})
"""
文件下载
"""

# 下载文件
# 原文件
result = bucket.get_object(key)

# 验证一下
content_got = b''
for chunk in result:
    content_got += chunk