diff --git a/static-data/official-plugins/wot/wot/crypto/encryption.py b/static-data/official-plugins/wot/wot/crypto/encryption.py index c9cd046b..e21a622f 100644 --- a/static-data/official-plugins/wot/wot/crypto/encryption.py +++ b/static-data/official-plugins/wot/wot/crypto/encryption.py @@ -2,13 +2,17 @@ from typing import TYPE_CHECKING, Union from ..identity import Identity +import result +import nacl.exceptions import nacl.public import nacl.utils +@result.as_result(nacl.exceptions.CryptoError, AttributeError) def encrypt_to_identity_anonymously( identity: 'Identity', message: Union[bytes, str]) -> nacl.utils.EncryptedMessage: + their_public_key = identity.key.to_curve25519_public_key() box = nacl.public.SealedBox(their_public_key) @@ -20,14 +24,17 @@ def encrypt_to_identity_anonymously( return box.encrypt(message) +@result.as_result(nacl.exceptions.CryptoError, AttributeError) def decrypt_from_identity_anonymously( our_identity: 'Identity', message: bytes) -> bytes: + our_private_key = our_identity.private_key.to_curve25519_private_key() box = nacl.public.SealedBox(our_private_key) return box.decrypt(message) +@result.as_result(nacl.exceptions.CryptoError, AttributeError) def encrypt_to_identity( our_identity: 'Identity', identity: 'Identity', @@ -43,7 +50,7 @@ def encrypt_to_identity( return box.encrypt(message) - +@result.as_result(nacl.exceptions.CryptoError, AttributeError) def decrypt_from_identity( our_identity: 'Identity', identity: 'Identity', diff --git a/static-data/official-plugins/wot/wot/crypto/signatures.py b/static-data/official-plugins/wot/wot/crypto/signatures.py index e69de29b..6139cc40 100644 --- a/static-data/official-plugins/wot/wot/crypto/signatures.py +++ b/static-data/official-plugins/wot/wot/crypto/signatures.py @@ -0,0 +1,20 @@ +from typing import TYPE_CHECKING + +import result +import nacl.signing +import nacl.exceptions + +if TYPE_CHECKING: + from identity import Identity + + +def create_signature_by_identity( + identity: 'Identity', message: bytes) -> result.Result[nacl.signing.SignedMessage]: + return result.as_result(nacl.exceptions.CryptoError)(identity.private_key.sign)(message) + + +def verify_signature_by_identity( + identity: 'Identity', + message: bytes, signature: bytes) -> result.Result[str]: + return result.as_result(nacl.exceptions.CryptoError)(nacl.signing.verify)( + identity.key, message, signature) diff --git a/static-data/official-plugins/wot/wot/identity/__init__.py b/static-data/official-plugins/wot/wot/identity/__init__.py index f4344184..b6fbff91 100644 --- a/static-data/official-plugins/wot/wot/identity/__init__.py +++ b/static-data/official-plugins/wot/wot/identity/__init__.py @@ -29,6 +29,7 @@ class Identity: self.trusted: Set[Identity] = IdentitySet() self.name = IdentityName(name) self.created_date = created_date + self.private_key: Union[None, SigningKey] self.private_key = self.key = None diff --git a/tests/default-plugin-tests/wot/test_decrypt_from_identity.py b/tests/default-plugin-tests/wot/test_decrypt_from_identity.py new file mode 100644 index 00000000..a9ee2c3c --- /dev/null +++ b/tests/default-plugin-tests/wot/test_decrypt_from_identity.py @@ -0,0 +1,52 @@ +import dbm +import os, uuid + +import time + +TEST_DIR = 'testdata/%s-%s' % (str(uuid.uuid4())[:6], os.path.basename(__file__)) + '/' +print("Test directory:", TEST_DIR) +os.environ["ONIONR_HOME"] = TEST_DIR +os.makedirs(TEST_DIR) + +from nacl import signing + +import unittest +import sys +sys.path.append('static-data/official-plugins/wot/') +sys.path.append("src/") + +import nacl.public +import nacl.exceptions +import nacl.signing +import result + +import wot +from wot.identity import Identity + +from wot import crypto + + + +class TestDecryptFromIdentity(unittest.TestCase): + + def test_decrypt_from_identity(self): + iden_priv_key = signing.SigningKey.generate() + iden_public = iden_priv_key.verify_key + identity = Identity(iden_priv_key, "us") + + their_priv_key = signing.SigningKey.generate() + their_public = their_priv_key.verify_key + their_identity = Identity(their_priv_key, "them") + + test_message = b"test message" + + encrypted = nacl.public.Box(their_priv_key.to_curve25519_private_key(), iden_public.to_curve25519_public_key()).encrypt(test_message) + self.assertIsInstance(encrypted, bytes) + + decrypted = crypto.encryption.decrypt_from_identity(identity, their_identity, encrypted) + self.assertIsInstance(decrypted, result.Ok) + self.assertEqual(decrypted.value, test_message) + + + +unittest.main() diff --git a/tests/default-plugin-tests/wot/test_encrypt_to_identity.py b/tests/default-plugin-tests/wot/test_encrypt_to_identity.py index 74678651..22f6e613 100644 --- a/tests/default-plugin-tests/wot/test_encrypt_to_identity.py +++ b/tests/default-plugin-tests/wot/test_encrypt_to_identity.py @@ -19,6 +19,7 @@ from blockdb import block_db_path import nacl.public import nacl.exceptions import nacl.signing +import result import wot from wot.identity import Identity @@ -42,7 +43,9 @@ class TestEncryptToIdentity(unittest.TestCase): test_message = b"test message" encrypted = crypto.encryption.encrypt_to_identity(identity, their_identity, test_message) - decrypted = nacl.public.Box(their_priv_key.to_curve25519_private_key(), iden_public.to_curve25519_public_key()).decrypt(encrypted) + self.assertIsInstance(encrypted, result.Ok) + + decrypted = nacl.public.Box(their_priv_key.to_curve25519_private_key(), iden_public.to_curve25519_public_key()).decrypt(encrypted.value) self.assertEqual(decrypted, test_message) def test_encrypt_to_identity_str(self): @@ -57,7 +60,8 @@ class TestEncryptToIdentity(unittest.TestCase): test_message = "test message" encrypted = crypto.encryption.encrypt_to_identity(identity, their_identity, test_message) - decrypted = nacl.public.Box(their_priv_key.to_curve25519_private_key(), iden_public.to_curve25519_public_key()).decrypt(encrypted) + self.assertIsInstance(encrypted, result.Ok) + decrypted = nacl.public.Box(their_priv_key.to_curve25519_private_key(), iden_public.to_curve25519_public_key()).decrypt(encrypted.value) self.assertEqual(decrypted, test_message.encode('utf-8')) def test_encrypt_to_identity_bytes_invalid(self): @@ -72,7 +76,8 @@ class TestEncryptToIdentity(unittest.TestCase): test_message = b"test message" encrypted = crypto.encryption.encrypt_to_identity(identity, their_identity, test_message) - encrypted = encrypted[:-1] + b'\x00' + self.assertIsInstance(encrypted, result.Ok) + encrypted = encrypted.value[:-1] + b'\x00' try: decrypted = nacl.public.Box(their_priv_key.to_curve25519_private_key(), iden_public.to_curve25519_public_key()).decrypt(encrypted) except nacl.exceptions.CryptoError: