def decrypt(self, ciphertext: bytes, associated_data: bytes) -> bytes: ct_len = len(ciphertext) # Recover DEK length if ct_len < DEK_LEN_BYTES: raise tink_error.TinkError dek_len = struct.unpack('>I', ciphertext[0:DEK_LEN_BYTES])[0] # Basic check if DEK length can be valid. if dek_len > (ct_len - DEK_LEN_BYTES) or dek_len < 0: raise tink_error.TinkError # Decrypt DEK with remote AEAD encrypted_dek_bytes = ciphertext[DEK_LEN_BYTES:DEK_LEN_BYTES + dek_len] dek_bytes = self.remote_aead.decrypt(encrypted_dek_bytes, b'') # Get AEAD primitive based on DEK dek = tink_pb2.KeyData() dek.type_url = self.key_template.type_url dek.value = dek_bytes dek.key_material_type = tink_pb2.KeyData.KeyMaterialType.SYMMETRIC dek_aead = core.Registry.primitive(dek, aead.Aead) # Extract ciphertext payload and decrypt ct_bytes = ciphertext[DEK_LEN_BYTES + dek_len:] return dek_aead.decrypt(ct_bytes, associated_data)
def test_public_key_data_success(self): self.reg.register_key_manager(DummyPrivateKeyManager('dummy_type_url')) key_data = tink_pb2.KeyData( type_url='dummy_type_url', key_material_type=tink_pb2.KeyData.ASYMMETRIC_PRIVATE) public_key_data = self.reg.public_key_data(key_data) self.assertEqual(public_key_data.type_url, 'public_dummy_type_url')
def test_primitive_fails_on_subclass(self): self.reg.register_key_manager( DummyKeyManager('dummy_type_url', helper.FakeAead)) with self.assertRaisesRegex(core.TinkError, 'uses primitive FakeAead, and not Aead'): self.reg.primitive(tink_pb2.KeyData(type_url='dummy_type_url'), aead.Aead)
def test_primitive_fails_on_wrong_primitive(self): self.reg.register_key_manager( DummyKeyManager('dummy_type_url', aead.Aead)) with self.assertRaisesRegex(core.TinkError, 'uses primitive Aead, and not Mac'): self.reg.primitive(tink_pb2.KeyData(type_url='dummy_type_url'), mac.Mac)
def test_public_key_data_fails_for_non_private_key_manager(self): self.reg.register_key_manager(DummyKeyManager('dummy_type_url')) key_data = tink_pb2.KeyData( type_url='dummy_type_url', key_material_type=tink_pb2.KeyData.ASYMMETRIC_PRIVATE) with self.assertRaisesRegex(core.TinkError, 'is not a PrivateKeyManager'): self.reg.public_key_data(key_data)
def test_public_key_data_fails_for_non_asymmetric_private_key(self): self.reg.register_key_manager(DummyPrivateKeyManager('dummy_type_url')) key_data = tink_pb2.KeyData( type_url='dummy_type_url', key_material_type=tink_pb2.KeyData.ASYMMETRIC_PUBLIC) with self.assertRaisesRegex(core.TinkError, 'contains a non-private key'): self.reg.public_key_data(key_data)
def test_new_key_data(self): key_template = self.new_hmac_key_template(common_pb2.SHA256, 24, 16) key_data = tink_pb2.KeyData() key_data.ParseFromString(self.key_manager.new_key_data(key_template)) self.assertEqual(key_data.type_url, self.key_manager.key_type()) key = hmac_pb2.HmacKey() key.ParseFromString(key_data.value) self.assertEqual(key.version, 0) self.assertEqual(key.params.hash, common_pb2.SHA256) self.assertEqual(key.params.tag_size, 24) self.assertLen(key.key_value, 16)
def test_new_key_data(self): key_template = self.new_aes_siv_key_template(64) key_data = tink_pb2.KeyData() key_data.ParseFromString(self.key_manager.new_key_data(key_template)) self.assertEqual(key_data.type_url, self.key_manager.key_type()) self.assertEqual(key_data.key_material_type, tink_pb2.KeyData.SYMMETRIC) key = aes_siv_pb2.AesSivKey() key.ParseFromString(key_data.value) self.assertEqual(key.version, 0) self.assertLen(key.key_value, 64)
def test_new_key_data(self): key_template = self.new_aes_eax_key_template(12, 16) serialized_key_data = self.key_manager.new_key_data(key_template) key_data = tink_pb2.KeyData() key_data.ParseFromString(serialized_key_data) self.assertEqual(key_data.type_url, self.key_manager.key_type()) self.assertEqual(key_data.key_material_type, tink_pb2.KeyData.SYMMETRIC) key = aes_eax_pb2.AesEaxKey() key.ParseFromString(key_data.value) self.assertEqual(key.version, 0) self.assertEqual(key.params.iv_size, 12) self.assertLen(key.key_value, 16)
def test_new_key_data(self): key_manager = self.hybrid_decrypt_key_manager() key_data = tink_pb2.KeyData() key_data.ParseFromString( key_manager.new_key_data( hybrid_key_templates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM. SerializeToString())) self.assertEqual(key_data.type_url, key_manager.key_type()) self.assertEqual(key_data.key_material_type, tink_pb2.KeyData.ASYMMETRIC_PRIVATE) key = ecies_aead_hkdf_pb2.EciesAeadHkdfPrivateKey() key.ParseFromString(key_data.value) self.assertLen(key.key_value, 32) self.assertEqual(key.public_key.params.kem_params.curve_type, common_pb2.NIST_P256)
def test_new_key_data_sign(self): key_template = self.new_ecdsa_key_template(common_pb2.SHA256, common_pb2.NIST_P256, ecdsa_pb2.DER) key_data = tink_pb2.KeyData() key_data.ParseFromString( self.key_manager_sign.new_key_data(key_template)) self.assertEqual(key_data.type_url, self.key_manager_sign.key_type()) key = ecdsa_pb2.EcdsaPrivateKey() key.ParseFromString(key_data.value) public_key = key.public_key self.assertEqual(key.version, 0) self.assertEqual(public_key.version, 0) self.assertEqual(public_key.params.hash_type, common_pb2.SHA256) self.assertEqual(public_key.params.curve, common_pb2.NIST_P256) self.assertEqual(public_key.params.encoding, ecdsa_pb2.DER) self.assertLen(key.key_value, 32)
def deserialize_key_data(serialized_proto): """Convert serialized KeyData proto to native Python proto.""" key_data = tink_pb2.KeyData() key_data.ParseFromString(serialized_proto) return key_data
def public_key_data(self, private_key_data): return tink_pb2.KeyData(type_url='public_' + private_key_data.type_url)
def new_key_data(self, key_template): return tink_pb2.KeyData(type_url=key_template.type_url)
def test_primitive_ok(self): self.reg.register_key_manager( DummyKeyManager('dummy_type_url', aead.Aead)) primitive = self.reg.primitive( tink_pb2.KeyData(type_url='dummy_type_url'), aead.Aead) self.assertIsInstance(primitive, helper.FakeAead)