def test_from_constuctor(self): line_utf_8 = "hello world" byte_line = line_utf_8.encode() vb = VirgilBuffer(byte_line) self.assertEqual(vb.to_string(), line_utf_8) self.assertEqual(type(vb.get_bytearray()), bytearray) self.assertEqual(bytes(vb.get_bytearray()), byte_line)
def test_verify(self): card_model = self.__get_card_model(Card.Scope.APPLICATION) data_string = "hello world" data = VirgilBuffer.from_string(data_string) vc = VirgilCard(self.__context, card_model) signature = self.__crypto.sign(data.get_bytearray(), self.__key_pair.private_key) self.assertTrue(vc.verify(data, VirgilBuffer(signature)))
def test_decrypt(self): key_pair = self.__crypto.generate_keys() private_key = key_pair.private_key context = VirgilContext() vk = VirgilKey(context, private_key) data_string = "hello world" data = VirgilBuffer.from_string(data_string) encrypted_data = VirgilBuffer( self.__crypto.encrypt(data.get_bytearray(), key_pair.public_key)) self.assertEqual(data.get_bytearray(), vk.decrypt(encrypted_data).get_bytearray())
def test_decrypt_then_verify(self): alice_keys = self.__crypto.generate_keys() test_keys = self.__crypto.generate_keys() data_string = "hello world" data = VirgilBuffer.from_string(data_string) context = VirgilContext() vk = VirgilKey(context, test_keys.private_key) cipher_data = self.__crypto.sign_then_encrypt(data.get_bytearray(), alice_keys.private_key, test_keys.public_key) self.assertEqual( data.get_bytearray(), vk.decrypt_then_verify(VirgilBuffer(cipher_data), alice_keys).get_bytearray())
def test_from_string_hex(self): line_utf_8 = "hello world" line_hex = "68656c6c6f20776f726c64" vb = VirgilBuffer.from_string(line_hex, "hex") self.assertEqual(vb.to_string("hex"), line_hex) self.assertEqual(type(vb.get_bytearray()), bytearray) self.assertEqual(vb.to_string(), line_utf_8)
def __build_card_model(self, identity, identity_type, scope, owner_key, custom_fields=None): card_config = { 'identity': identity, 'identity_type': identity_type, 'public_key': tuple(owner_key.export_public_key().get_bytearray()), 'data': custom_fields, } card = Card(**card_config) if scope == Card.Scope.APPLICATION: card_request = CreateCardRequest(**card_config) elif scope == Card.Scope.GLOBAL: card_request = CreateGlobalCardRequest(**card_config) else: raise ValueError("Unknown scope value") card.snapshot = card_request.snapshot snapshot_fingerprint = self.__crypto.calculate_fingerprint( card.snapshot) card.scope = scope card.id = snapshot_fingerprint.to_hex self_signature = owner_key.sign( VirgilBuffer(snapshot_fingerprint.value)) card.signatures = {card.id: self_signature.to_string("base64")} return card
def test_from_string_base64(self): line_utf_8 = "hello world" line_base64 = "aGVsbG8gd29ybGQ=" vb = VirgilBuffer.from_string(line_base64, "base64") self.assertEqual(vb.to_string("base64"), line_base64) self.assertEqual(type(vb.get_bytearray()), bytearray) self.assertEqual(vb.to_string(), line_utf_8)
def encrypt(self, data): # type: (Union[VirgilBuffer, str, bytearray, bytes]) -> VirgilBuffer """Encrypts the specified data for current VirgilCard recipient. Args: buffer: The data to be encrypted. Returns: Encrypted data Raises: ValueError if VirgilBuffer empty """ if isinstance(data, str): buffer = VirgilBuffer.from_string(data) elif isinstance(data, bytearray): buffer = VirgilBuffer(data) elif isinstance(data, bytes): buffer = VirgilBuffer(data) elif isinstance(data, VirgilBuffer): buffer = data else: raise TypeError("Unsupported type of data") if not buffer: raise ValueError("VirgilBuffer empty") cipher_data = self.__context.crypto.encrypt(buffer.get_bytearray(), self.public_key) return VirgilBuffer(cipher_data)
def export(self): # type: () -> str """Exports a current VirgilCard instance into base64 encoded string. Returns: A base64 string that represents a VirgilCard. """ card_json = Utils.json_dumps({ "id": self.__card.id, "content_snapshot": VirgilBuffer(self.__card.snapshot).to_string("base64"), "meta": { "card_version": self.__card.version, "signs": self.__card.signatures } }) return VirgilBuffer.from_string(card_json).to_string("base64")
def test_import_key_with_passwd(self): key_pair = self.__context.crypto.generate_keys() km = KeyManager(self.__context) exported_key = self.__context.crypto.export_private_key( key_pair.private_key, "SomeCoolPass") self.assertEqual( km.import_key(VirgilBuffer(exported_key), "SomeCoolPass")._VirgilKey__private_key, key_pair.private_key)
def test_sign(self): private_key = self.__crypto.generate_keys().private_key context = VirgilContext() vk = VirgilKey(context, private_key) data_string = "hello world" data = VirgilBuffer.from_string(data_string) self.assertEqual( vk.sign(data).get_bytearray(), bytearray( self.__crypto.sign(bytearray(data_string, "utf-8"), private_key)))
def test_encrypt(self): card_model = self.__get_card_model(Card.Scope.APPLICATION) data_string = "hello world" data = VirgilBuffer.from_string(data_string) vc = VirgilCard(self.__context, card_model) cipher_data = vc.encrypt(data) self.assertEqual( bytearray( self.__crypto.decrypt(cipher_data.get_bytearray(), self.__key_pair.private_key)), data.get_bytearray())
def verify(self, data, signature): # type: (Union[VirgilBuffer, str, bytearray, bytes], VirgilBuffer) -> bool """Verifies the specified buffer and signature with current VirgilCard recipient. Args: buffer: The data to be verified. signature: The signature used to verify the data integrity. Returns: Boolean verification result Raises: ValueError is buffer or signature empty """ if not data: raise ValueError("Data empty") if not signature: raise ValueError("Signatures empty") if isinstance(data, str): buffer = VirgilBuffer.from_string(data) elif isinstance(data, bytearray): buffer = VirgilBuffer(data) elif isinstance(data, bytes): buffer = VirgilBuffer(data) elif isinstance(data, VirgilBuffer): buffer = data else: raise TypeError("Unsupported type of data") is_valid = self.__context.crypto.verify(buffer.get_bytearray(), signature.get_bytearray(), self.public_key) return is_valid
def import_card(self, exported_card): # type: (str) -> VirgilCard """Imports a VirgilCard from specified buffer. Args: exported_card: A Card in string representation. Returns: An instance of VirgilCard. """ buffer = VirgilBuffer.from_string(exported_card, "base64") imported_card_model = Utils.json_loads(buffer.get_bytearray()) card = Card.from_response(imported_card_model) return VirgilCard(self.context, card)
def __build_card_model(self, identity, identity_type, custom_fields, scope, owner_key, validation_token=None): # type: (str, str, dict, Card.Scope, VirgilKey) -> Card """Constructs the card model Args: identity: The user's identity. identity_type: Type of the identity. custom_fields: The custom fields (optional). scope: Card scope owner_key: The owner's VirgilKey. Returns: Card model for VirgilCard creation. Raises: ValueError when scope incorrect. """ card_config = { 'identity': identity, 'identity_type': identity_type, 'public_key': owner_key.export_public_key().get_bytearray(), 'data': custom_fields, } card_model = Card(**card_config) if scope == Card.Scope.APPLICATION: card_request = CreateCardRequest(**card_config) elif scope == Card.Scope.GLOBAL: card_config.update({"validation_token": validation_token}) card_request = CreateGlobalCardRequest(**card_config) else: raise ValueError("Unknown scope value") card_model.snapshot = card_request.snapshot snapshot_fingerprint = self.context.crypto.calculate_fingerprint( card_model.snapshot) card_model.scope = scope card_model.id = snapshot_fingerprint.to_hex self_signature = owner_key.sign( VirgilBuffer(snapshot_fingerprint.value)) card_model.signatures = { card_model.id: self_signature.to_string("base64") } return card_model
def revoke_global(self, card, key, identity): # type: (VirgilCard, VirgilKey, Union[IdentityUser, IdentityApplication, IdentityEmail]) -> None """Revokes a global VirgilCard from Virgil Security services. Args: card: The Card to be revoked. key: The Key associated with the revoking Card. identity: The identity token. """ revoke_global_card_request = RevokeGlobalCardRequest( card.id, identity.validation_token, RevokeGlobalCardRequest.Reasons.Unspecified) snapshot_fingerprint = self.context.crypto.calculate_fingerprint( revoke_global_card_request.snapshot) revoke_global_card_request.signatures = { card.id: key.sign(VirgilBuffer( snapshot_fingerprint.value)).to_string("base64") } self.context.client.revoke_global_card_from_request( revoke_global_card_request)
def revoke(self, card): # type: (VirgilCard) -> None """Revokes a VirgilCard from Virgil Services. Args: card: The card to be revoked. """ revoke_card_request = RevokeCardRequest( card.id, RevokeCardRequest.Reasons.Unspecified) app_key = self.context.credentials.get_app_key(self.context.crypto) snapshot_fingerprint = self.context.crypto.calculate_fingerprint( revoke_card_request.snapshot) signature = VirgilBuffer( self.context.crypto.sign(snapshot_fingerprint.value, app_key)).to_string("base64") revoke_card_request.signatures = { self.context.credentials.app_id: signature } self.context.client.revoke_card_from_request(revoke_card_request)
def test_sign_then_encrypt(self): alice_keys = self.__crypto.generate_keys() bob_keys = self.__crypto.generate_keys() test_keys = self.__crypto.generate_keys() context = VirgilContext() data_string = "hello world" data = VirgilBuffer.from_string(data_string) recipients = [alice_keys, bob_keys] vk = VirgilKey(context, test_keys.private_key) cipher_data = vk.sign_then_encrypt(data, recipients) self.assertEqual( data.get_bytearray(), bytearray( self.__crypto.decrypt_then_verify(cipher_data.get_bytearray(), alice_keys.private_key, test_keys.public_key))) self.assertEqual( data.get_bytearray(), bytearray( self.__crypto.decrypt_then_verify(cipher_data.get_bytearray(), bob_keys.private_key, test_keys.public_key)))
def encrypt_for(self, cards, data): # type: (List[VirgilCard], Union[VirgilBuffer, str, bytearray, bytes]) -> VirgilBuffer """Encrypt to multiply cards""" if cards: public_keys = list(map(lambda x: x.public_key, cards)) else: raise ValueError("Card list for encryption empty") if isinstance(data, str): buffer = VirgilBuffer.from_string(data) elif isinstance(data, bytearray): buffer = VirgilBuffer(data) elif isinstance(data, bytes): buffer = VirgilBuffer(data) elif isinstance(data, VirgilBuffer): buffer = data else: raise TypeError("Unsupported type of data") cipher_data = self.__context.crypto.encrypt(buffer.get_bytearray(), *public_keys) return VirgilBuffer(cipher_data)
def test_from_empty_bytes(self): with self.assertRaises(Exception) as context: vb = VirgilBuffer(bytes()) vb.get_bytearray() self.assertEqual("Buffer empty", str(context.exception))
def test_from_string_utf8(self): line_utf_8 = "hello world" vb = VirgilBuffer.from_string(line_utf_8, "utf-8") self.assertEqual(vb.to_string("utf-8"), line_utf_8) self.assertEqual(type(vb.get_bytearray()), bytearray) self.assertEqual(vb.to_string(), line_utf_8)
def test_import_key(self): km = KeyManager(self.__context) key_pair = self.__context.crypto.generate_keys() imported_key = km.import_key(VirgilBuffer(key_pair.private_key.value)) self.assertEqual(imported_key._VirgilKey__private_key, key_pair.private_key)