Refactors Cryptographer to remove logs and avoid multi return types

Cryptographer now uses exceptions to report errors and does not use the log anymore
This commit is contained in:
Sergi Delgado Segura
2020-04-09 17:57:40 +02:00
parent b4ea005f55
commit 08701f0fee
12 changed files with 98 additions and 181 deletions

View File

@@ -6,25 +6,24 @@ import requests
from sys import argv
from uuid import uuid4
from coincurve import PublicKey
from requests import Timeout, ConnectionError
from getopt import getopt, GetoptError
from requests import Timeout, ConnectionError
from requests.exceptions import MissingSchema, InvalidSchema, InvalidURL
from cli.exceptions import TowerResponseError
from cli import DEFAULT_CONF, DATA_DIR, CONF_FILE_NAME, LOG_PREFIX
from cli.exceptions import InvalidKey, InvalidParameter, TowerResponseError
from cli.help import show_usage, help_add_appointment, help_get_appointment, help_register, help_get_all_appointments
import common.cryptographer
from common import constants
from common.logger import Logger
from common.appointment import Appointment
from common.config_loader import ConfigLoader
from common.cryptographer import Cryptographer
from common.tools import setup_logging, setup_data_folder
from common.exceptions import InvalidKey, InvalidParameter, SignatureError
from common.tools import is_256b_hex_str, is_locator, compute_locator, is_compressed_pk
logger = Logger(actor="Client", log_name_prefix=LOG_PREFIX)
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=LOG_PREFIX)
def register(compressed_pk, teos_url):
@@ -107,10 +106,6 @@ def add_appointment(appointment_data, cli_sk, teos_pk, teos_url):
appointment = Appointment.from_dict(appointment_data)
signature = Cryptographer.sign(appointment.serialize(), cli_sk)
# FIXME: the cryptographer should return exception we can capture
if not signature:
raise ValueError("The provided appointment cannot be signed")
data = {"appointment": appointment.to_dict(), "signature": signature}
# Send appointment to the server.
@@ -124,7 +119,7 @@ def add_appointment(appointment_data, cli_sk, teos_pk, teos_url):
raise TowerResponseError("The response does not contain the signature of the appointment")
rpk = Cryptographer.recover_pk(appointment.serialize(), signature)
if not Cryptographer.verify_rpk(teos_pk, rpk):
if not teos_pk != Cryptographer.get_compressed_pk(rpk):
raise TowerResponseError("The returned appointment's signature is invalid")
logger.info("Appointment accepted and signed by the Eye of Satoshi")
@@ -467,7 +462,7 @@ def main(command, args, command_line_conf):
except (FileNotFoundError, IOError, ConnectionError, ValueError) as e:
logger.error(str(e))
except (InvalidKey, InvalidParameter, TowerResponseError) as e:
except (InvalidKey, InvalidParameter, TowerResponseError, SignatureError) as e:
logger.error(e.reason, **e.kwargs)
except Exception as e:
logger.error("Unknown error occurred", error=str(e))

View File

@@ -7,13 +7,14 @@ from cryptography.exceptions import InvalidTag
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
from common.tools import is_256b_hex_str
from common.exceptions import InvalidKey, InvalidParameter, SignatureError, EncryptionError
LN_MESSAGE_PREFIX = b"Lightning Signed Message:"
def sha256d(message):
"""
Computes the double sha256 of a given by message.
Computes the double sha256 of a given message.
Args:
message(:obj:`bytes`): the message to be used as input to the hash function.
@@ -87,10 +88,6 @@ def sigrec_decode(sigrec):
return rsig + rid
# FIXME: Common has not log file, so it needs to log in the same log as the caller. This is a temporary fix.
logger = None
class Cryptographer:
"""
The :class:`Cryptographer` is in charge of all the cryptography in the tower.
@@ -99,63 +96,49 @@ class Cryptographer:
@staticmethod
def check_data_key_format(data, secret):
"""
Checks that the data and secret that will be used to by ``encrypt`` / ``decrypt`` are properly
formatted.
Checks that the data and secret that will be used to by ``encrypt`` / ``decrypt`` are properly formatted.
Args:
data(:obj:`str`): the data to be encrypted.
secret(:obj:`str`): the secret used to derive the encryption key.
Returns:
:obj:`bool`: Whether or not the ``key`` and ``data`` are properly formatted.
Raises:
:obj:`ValueError`: if either the ``key`` or ``data`` is not properly formatted.
:obj:`InvalidParameter`: if either the ``key`` and/or ``data`` are not properly formatted.
"""
if len(data) % 2:
error = "Incorrect (Odd-length) value"
raise ValueError(error)
raise InvalidParameter("Incorrect (Odd-length) data", data=data)
if not is_256b_hex_str(secret):
error = "Secret must be a 32-byte hex value (64 hex chars)"
raise ValueError(error)
return True
raise InvalidParameter("Secret must be a 32-byte hex value (64 hex chars)", secret=secret)
@staticmethod
def encrypt(blob, secret):
def encrypt(message, secret):
"""
Encrypts a given :obj:`Blob <common.cli.blob.Blob>` data using ``CHACHA20POLY1305``.
Encrypts a given message data using ``CHACHA20POLY1305``.
``SHA256(secret)`` is used as ``key``, and ``0 (12-byte)`` as ``iv``.
Args:
blob (:obj:`Blob <common.cli.blob.Blob>`): a ``Blob`` object containing a raw penalty transaction.
message (:obj:`str`): a message to be encrypted. Should be the hex-encoded commitment_tx.
secret (:obj:`str`): a value to used to derive the encryption key. Should be the dispute txid.
Returns:
:obj:`str`: The encrypted data (hex encoded).
:obj:`str`: The encrypted data (hex-encoded).
Raises:
:obj:`ValueError`: if either the ``secret`` or ``blob`` is not properly formatted.
:obj:`InvalidParameter`: if either the ``key`` and/or ``data`` are not properly formatted.
"""
Cryptographer.check_data_key_format(blob.data, secret)
# Transaction to be encrypted
# FIXME: The blob data should contain more things that just the transaction. Leaving like this for now.
tx = unhexlify(blob.data)
Cryptographer.check_data_key_format(message, secret)
# sk is the H(txid) (32-byte) and nonce is set to 0 (12-byte)
sk = sha256(unhexlify(secret)).digest()
nonce = bytearray(12)
logger.debug("Encrypting blob", sk=hexlify(sk).decode(), nonce=hexlify(nonce).decode(), blob=blob.data)
# Encrypt the data
cipher = ChaCha20Poly1305(sk)
encrypted_blob = cipher.encrypt(nonce=nonce, data=tx, associated_data=None)
encrypted_blob = cipher.encrypt(nonce=nonce, data=unhexlify(message), associated_data=None)
encrypted_blob = hexlify(encrypted_blob).decode("utf8")
return encrypted_blob
@@ -164,20 +147,20 @@ class Cryptographer:
# ToDo: #20-test-tx-decrypting-edge-cases
def decrypt(encrypted_blob, secret):
"""
Decrypts a given :obj:`EncryptedBlob <common.encrypted_blob.EncryptedBlob>` using ``CHACHA20POLY1305``.
Decrypts a given encrypted_blob using ``CHACHA20POLY1305``.
``SHA256(secret)`` is used as ``key``, and ``0 (12-byte)`` as ``iv``.
Args:
encrypted_blob(:obj:`EncryptedBlob <common.encrypted_blob.EncryptedBlob>`): an ``EncryptedBlob``
potentially containing a penalty transaction.
secret (:obj:`str`): a value to used to derive the decryption key. Should be the dispute txid.
encrypted_blob(:obj:`str`): an encrypted blob of data potentially containing a penalty transaction.
secret (:obj:`str`): a value used to derive the decryption key. Should be the dispute txid.
Returns:
:obj:`str`: The decrypted data (hex encoded).
:obj:`str`: The decrypted data (hex-encoded).
Raises:
:obj:`ValueError`: if either the ``secret`` or ``encrypted_blob`` is not properly formatted.
:obj:`InvalidParameter`: if either the ``key`` and/or ``data`` are not properly formatted.
:obj:`EncryptionError`: if the data cannot be decrypted with the given key.
"""
Cryptographer.check_data_key_format(encrypted_blob, secret)
@@ -186,13 +169,6 @@ class Cryptographer:
sk = sha256(unhexlify(secret)).digest()
nonce = bytearray(12)
logger.info(
"Decrypting blob",
sk=hexlify(sk).decode(),
nonce=hexlify(nonce).decode(),
encrypted_blob=encrypted_blob.data,
)
# Decrypt
cipher = ChaCha20Poly1305(sk)
data = unhexlify(encrypted_blob)
@@ -202,8 +178,7 @@ class Cryptographer:
blob = hexlify(blob).decode("utf8")
except InvalidTag:
blob = None
logger.error("Can't decrypt blob with the provided key")
raise EncryptionError("Can't decrypt blob with the provided key", blob=encrypted_blob, key=secret)
return blob
@@ -216,12 +191,15 @@ class Cryptographer:
file_path (:obj:`str`): the path to the key file to be loaded.
Returns:
:obj:`bytes` or :obj:`None`: the key file data if the file can be found and read. ``None`` otherwise.
:obj:`bytes`: the key file data if the file can be found and read.
Raises:
:obj:`InvalidParameter`: if the file_path has wrong format or cannot be found.
:obj:`InvalidKey`: if the key cannot be loaded from the file. It covers temporary I/O errors.
"""
if not isinstance(file_path, str):
logger.error("Key file path was expected, {} received".format(type(file_path)))
return None
raise InvalidParameter("Key file path was expected, {} received".format(type(file_path)))
try:
with open(file_path, "rb") as key_file:
@@ -229,12 +207,10 @@ class Cryptographer:
return key
except FileNotFoundError:
logger.error("Key file not found at {}. Please check your settings".format(file_path))
return None
raise InvalidParameter("Key file not found at {}. Please check your settings".format(file_path))
except IOError as e:
logger.error("I/O error({}): {}".format(e.errno, e.strerror))
return None
raise InvalidKey("Key file cannot be loaded", exception=e)
@staticmethod
def load_private_key_der(sk_der):
@@ -245,50 +221,52 @@ class Cryptographer:
sk_der(:obj:`str`): a private key encoded in ``DER`` format.
Returns:
:obj:`PrivateKey` or :obj:`None`: A ``PrivateKey`` object. if the private key can be loaded. `None`
otherwise.
:obj:`PrivateKey`: A ``PrivateKey`` object if the private key can be loaded.
Raises:
:obj:`InvalidKey`: if a ``PrivateKey`` cannot be loaded from the given data.
"""
try:
sk = PrivateKey.from_der(sk_der)
return sk
except ValueError:
logger.error("The provided data cannot be deserialized (wrong size or format)")
raise InvalidKey("The provided key data cannot be deserialized (wrong size or format)")
except TypeError:
logger.error("The provided data cannot be deserialized (wrong type)")
return None
raise InvalidKey("The provided key data cannot be deserialized (wrong type)")
@staticmethod
def sign(message, sk):
"""
Signs a given data using a given secret key using ECDSA over secp256k1.
Signs a given message with a given secret key using ECDSA over secp256k1.
Args:
message(:obj:`bytes`): the data to be signed.
sk(:obj:`PrivateKey`): the ECDSA secret key used to signed the data.
sk(:obj:`PrivateKey`): the ECDSA secret key to be used to sign the data.
Returns:
:obj:`str` or :obj:`None`: The zbase32 signature of the given message is it can be signed. `None` otherwise.
:obj:`str`: The zbase32 signature of the given message is it can be signed.
Raises:
:obj:`InvalidParameter`: if the message and/or secret key have a wrong value.
:obj:`SignatureError`: if there is an error during the signing process.
"""
if not isinstance(message, bytes):
logger.error("The message must be bytes. {} received".format(type(message)))
return None
raise InvalidParameter("Wrong value passed as message. Received {}, expected (bytes)".format(type(message)))
if not isinstance(sk, PrivateKey):
logger.error("The value passed as sk is not a private key (PrivateKey)")
return None
raise InvalidParameter("Wrong value passed as sk. Received {}, expected (PrivateKey)".format(type(message)))
try:
rsig_rid = sk.sign_recoverable(LN_MESSAGE_PREFIX + message, hasher=sha256d)
sigrec = sigrec_encode(rsig_rid)
zb32_sig = pyzbase32.encode_bytes(sigrec).decode()
except ValueError:
logger.error("Couldn't sign the message")
return None
except ValueError as e:
raise SignatureError("Couldn't sign the message. " + str(e))
return zb32_sig
@@ -302,16 +280,20 @@ class Cryptographer:
zb32_sig(:obj:`str`): the zbase32 signature of the message.
Returns:
:obj:`PublicKey` or :obj:`None`: The recovered public key if it can be recovered. `None` otherwise.
:obj:`PublicKey`: The public key if it can be recovered.
Raises:
:obj:`InvalidParameter`: if the message and/or signature have a wrong value.
:obj:`SignatureError`: if a public key cannot be recovered from the given signature.
"""
if not isinstance(message, bytes):
logger.error("The message must be bytes. {} received".format(type(message)))
return None
raise InvalidParameter("Wrong value passed as message. Received {}, expected (bytes)".format(type(message)))
if not isinstance(zb32_sig, str):
logger.error("The zbase32_sig must be str. {} received".format(type(zb32_sig)))
return None
raise InvalidParameter(
"Wrong value passed as zbase32_sig. Received {}, expected (str)".format(type(zb32_sig))
)
sigrec = pyzbase32.decode_bytes(zb32_sig)
@@ -323,31 +305,13 @@ class Cryptographer:
except ValueError as e:
# Several errors fit here: Signature length != 65, wrong recover id and failed to parse signature.
# All of them return raise ValueError.
logger.error(str(e))
return None
raise SignatureError("Cannot recover a public key from the given signature. " + str(e))
except Exception as e:
if "failed to recover ECDSA public key" in str(e):
logger.error("Cannot recover public key from signature")
raise SignatureError("Cannot recover a public key from the given signature")
else:
logger.error("Unknown exception", error=str(e))
return None
@staticmethod
def verify_rpk(pk, rpk):
"""
Verifies that that a recovered public key matches a given one.
Args:
pk(:obj:`PublicKey`): a given public key (provided by the user).
rpk(:obj:`PublicKey`): a public key recovered via ``recover_pk``.
Returns:
:obj:`bool`: True if the public keys match, False otherwise.
"""
return pk.point() == rpk.point()
raise SignatureError("Unknown exception. " + str(e))
@staticmethod
def get_compressed_pk(pk):
@@ -358,18 +322,19 @@ class Cryptographer:
pk(:obj:`PublicKey`): a given public key.
Returns:
:obj:`str` or :obj:`None`: A compressed, hex-encoded, public key (33-byte long) if it can be compressed.
`None` oterwise.
:obj:`str`: A compressed, hex-encoded, public key (33-byte long) if it can be compressed.
Raises:
:obj:`InvalidParameter`: if the value passed as public key is not a PublicKey object.
:obj:`InvalidKey`: if the public key has not been properly created.
"""
if not isinstance(pk, PublicKey):
logger.error("The received data is not a PublicKey object")
return None
raise InvalidParameter("Wrong value passed as pk. Received {}, expected (PublicKey)".format(type(pk)))
try:
compressed_pk = pk.format(compressed=True)
return hexlify(compressed_pk).decode("utf-8")
except TypeError as e:
logger.error("PublicKey has invalid initializer", error=str(e))
return None
raise InvalidKey("PublicKey has invalid initializer", error=str(e))

View File

@@ -1,5 +1,6 @@
from common.tools import is_compressed_pk
from common.cryptographer import Cryptographer
from common.exceptions import InvalidParameter, InvalidKey, SignatureError
class NotEnoughSlots(ValueError):
@@ -71,7 +72,7 @@ class Gatekeeper:
:obj:`IdentificationFailure`: if the user cannot be identified.
"""
if isinstance(message, bytes) and isinstance(signature, str):
try:
rpk = Cryptographer.recover_pk(message, signature)
compressed_pk = Cryptographer.get_compressed_pk(rpk)
@@ -80,7 +81,7 @@ class Gatekeeper:
else:
raise IdentificationFailure("User not found.")
else:
except (InvalidParameter, InvalidKey, SignatureError):
raise IdentificationFailure("Wrong message or signature.")
def fill_slots(self, user_pk, n):

View File

@@ -1,6 +1,5 @@
import re
import common.cryptographer
from common.logger import Logger
from common.tools import is_locator
from common.constants import LOCATOR_LEN_HEX
@@ -9,7 +8,6 @@ from common.appointment import Appointment
from teos import errors, LOG_PREFIX
logger = Logger(actor="Inspector", log_name_prefix=LOG_PREFIX)
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=LOG_PREFIX)
# FIXME: The inspector logs the wrong messages sent form the users. A possible attack surface would be to send a really
# long field that, even if not accepted by TEOS, would be stored in the logs. This is a possible DoS surface

View File

@@ -3,7 +3,6 @@ from sys import argv, exit
from getopt import getopt, GetoptError
from signal import signal, SIGINT, SIGQUIT, SIGTERM
import common.cryptographer
from common.logger import Logger
from common.config_loader import ConfigLoader
from common.cryptographer import Cryptographer
@@ -25,7 +24,6 @@ from teos.tools import can_connect_to_bitcoind, in_correct_network
from teos import LOG_PREFIX, DATA_DIR, DEFAULT_CONF, CONF_FILE_NAME
logger = Logger(actor="Daemon", log_name_prefix=LOG_PREFIX)
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=LOG_PREFIX)
def handle_signals(signal_received, frame):

View File

@@ -1,17 +1,17 @@
from queue import Queue
from threading import Thread
import common.cryptographer
from common.logger import Logger
from common.tools import compute_locator
from common.appointment import Appointment
from common.exceptions import EncryptionError
from common.cryptographer import Cryptographer, hash_160
from common.exceptions import InvalidParameter, SignatureError
from teos import LOG_PREFIX
from teos.cleaner import Cleaner
logger = Logger(actor="Watcher", log_name_prefix=LOG_PREFIX)
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=LOG_PREFIX)
class Watcher:
@@ -57,7 +57,7 @@ class Watcher:
last_known_block (:obj:`str`): the last block known by the ``Watcher``.
Raises:
ValueError: if `teos_sk_file` is not found.
:obj:`InvalidKey <common.exceptions.InvalidKey>`: if teos sk cannot be loaded.
"""
@@ -147,7 +147,14 @@ class Watcher:
self.db_manager.create_append_locator_map(appointment.locator, uuid)
appointment_added = True
signature = Cryptographer.sign(appointment.serialize(), self.signing_key)
try:
signature = Cryptographer.sign(appointment.serialize(), self.signing_key)
except (InvalidParameter, SignatureError):
# This should never happen since data is sanitized, just in case to avoid a crash
logger.error("Data couldn't be signed", appointment=appointment.to_dict())
signature = None
logger.info("New appointment accepted", locator=appointment.locator)
@@ -297,7 +304,7 @@ class Watcher:
try:
penalty_rawtx = Cryptographer.decrypt(appointment.encrypted_blob, dispute_txid)
except ValueError:
except EncryptionError:
penalty_rawtx = None
penalty_tx = self.block_processor.decode_raw_transaction(penalty_rawtx)

View File

@@ -7,8 +7,6 @@ from binascii import hexlify
from coincurve import PrivateKey
from requests.exceptions import ConnectionError, Timeout
import common.cryptographer
from common.logger import Logger
from common.tools import compute_locator
from common.appointment import Appointment
from common.cryptographer import Cryptographer
@@ -18,8 +16,6 @@ from cli.exceptions import InvalidParameter, InvalidKey, TowerResponseError
from test.cli.unit.conftest import get_random_value_hex, get_config
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=teos_cli.LOG_PREFIX)
config = get_config()
# dummy keys for the tests

View File

@@ -1,17 +1,12 @@
import os
from binascii import unhexlify
from coincurve import PrivateKey, PublicKey
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization
from coincurve import PrivateKey, PublicKey
import common.cryptographer
from common.logger import Logger
from common.cryptographer import Cryptographer
from test.common.unit.conftest import get_random_value_hex
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix="")
data = "6097cdf52309b1b2124efeed36bd34f46dc1c25ad23ac86f28380f746254f777"
key = "b2e984a570f6f49bc38ace178e09147b0aa296cbb7c92eb01412f7e2d07b5659"
encrypted_data = "8f31028097a8bf12a92e088caab5cf3fcddf0d35ed2b72c24b12269373efcdea04f9d2a820adafe830c20ff132d89810"
@@ -185,7 +180,7 @@ def test_sign_ground_truth():
sig = Cryptographer.sign(message, sk)
rpk = Cryptographer.recover_pk(message, sig)
assert Cryptographer.verify_rpk(PublicKey(unhexlify(c_lightning_rpk)), rpk)
assert c_lightning_rpk == Cryptographer.get_compressed_pk(rpk)
def test_sign_wrong_sk():
@@ -221,7 +216,7 @@ def test_recover_pk_ground_truth():
rpk = Cryptographer.recover_pk(message, zsig)
assert Cryptographer.verify_rpk(PublicKey(unhexlify(org_pk)), rpk)
assert org_pk == Cryptographer.get_compressed_pk(rpk)
def test_recover_pk_wrong_inputs():
@@ -241,27 +236,6 @@ def test_recover_pk_wrong_inputs():
assert Cryptographer.recover_pk(message, bytes(104)) is None
def test_verify_pk():
sk, _ = generate_keypair()
message = b"Test message"
zbase32_sig = Cryptographer.sign(message, sk)
rpk = Cryptographer.recover_pk(message, zbase32_sig)
assert Cryptographer.verify_rpk(sk.public_key, rpk)
def test_verify_pk_wrong():
sk, _ = generate_keypair()
sk2, _ = generate_keypair()
message = b"Test message"
zbase32_sig = Cryptographer.sign(message, sk)
rpk = Cryptographer.recover_pk(message, zbase32_sig)
assert not Cryptographer.verify_rpk(sk2.public_key, rpk)
def test_get_compressed_pk():
sk, pk = generate_keypair()
compressed_pk = Cryptographer.get_compressed_pk(pk)

View File

@@ -8,8 +8,6 @@ from coincurve import PrivateKey
from cli.exceptions import TowerResponseError
from cli import teos_cli, DATA_DIR, DEFAULT_CONF, CONF_FILE_NAME
import common.cryptographer
from common.logger import Logger
from common.tools import compute_locator
from common.appointment import Appointment
from common.cryptographer import Cryptographer
@@ -25,7 +23,6 @@ from test.teos.e2e.conftest import (
)
cli_config = get_config(DATA_DIR, CONF_FILE_NAME, DEFAULT_CONF)
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix="")
teos_base_endpoint = "http://{}:{}".format(cli_config.get("API_CONNECT"), cli_config.get("API_PORT"))
teos_add_appointment_endpoint = "{}/add_appointment".format(teos_base_endpoint)
@@ -257,7 +254,7 @@ def test_appointment_wrong_decryption_key(bitcoin_cli):
# Check that the server has accepted the appointment
signature = response_json.get("signature")
rpk = Cryptographer.recover_pk(appointment.serialize(), signature)
assert Cryptographer.verify_rpk(teos_pk, rpk) is True
assert teos_pk == Cryptographer.get_compressed_pk(rpk)
assert response_json.get("locator") == appointment.locator
# Trigger the appointment

View File

@@ -10,25 +10,21 @@ from bitcoind_mock.bitcoind import BitcoindMock
from bitcoind_mock.conf import BTC_RPC_HOST, BTC_RPC_PORT
from bitcoind_mock.transaction import create_dummy_transaction
from teos import DEFAULT_CONF
from teos.carrier import Carrier
from teos.tools import bitcoin_cli
from teos.users_dbm import UsersDBM
from teos.gatekeeper import Gatekeeper
from teos import LOG_PREFIX, DEFAULT_CONF
from teos.responder import TransactionTracker
from teos.block_processor import BlockProcessor
from teos.appointments_dbm import AppointmentsDBM
import common.cryptographer
from common.logger import Logger
from common.tools import compute_locator
from common.appointment import Appointment
from common.constants import LOCATOR_LEN_HEX
from common.config_loader import ConfigLoader
from common.cryptographer import Cryptographer
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=LOG_PREFIX)
# Set params to connect to regtest for testing
DEFAULT_CONF["BTC_RPC_PORT"]["value"] = 18443
DEFAULT_CONF["BTC_NETWORK"]["value"] = "regtest"

View File

@@ -2,19 +2,14 @@ import pytest
from binascii import unhexlify
import teos.errors as errors
from teos import LOG_PREFIX
from teos.block_processor import BlockProcessor
from teos.inspector import Inspector, InspectionFailed
import common.cryptographer
from common.logger import Logger
from common.appointment import Appointment
from common.constants import LOCATOR_LEN_BYTES, LOCATOR_LEN_HEX
from test.teos.unit.conftest import get_random_value_hex, bitcoind_connect_params, get_config
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=LOG_PREFIX)
NO_HEX_STRINGS = [
"R" * LOCATOR_LEN_HEX,
get_random_value_hex(LOCATOR_LEN_BYTES - 1) + "PP",

View File

@@ -13,8 +13,6 @@ from teos.chain_monitor import ChainMonitor
from teos.appointments_dbm import AppointmentsDBM
from teos.block_processor import BlockProcessor
import common.cryptographer
from common.logger import Logger
from common.tools import compute_locator
from common.cryptographer import Cryptographer
@@ -28,9 +26,6 @@ from test.teos.unit.conftest import (
bitcoind_connect_params,
)
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=LOG_PREFIX)
APPOINTMENTS = 5
START_TIME_OFFSET = 1
END_TIME_OFFSET = 1
@@ -134,16 +129,16 @@ def test_add_appointment(watcher):
added_appointment, sig = watcher.add_appointment(appointment, user_pk)
assert added_appointment is True
assert Cryptographer.verify_rpk(
watcher.signing_key.public_key, Cryptographer.recover_pk(appointment.serialize(), sig)
assert Cryptographer.get_compressed_pk(watcher.signing_key.public_key) == Cryptographer.get_compressed_pk(
Cryptographer.recover_pk(appointment.serialize(), sig)
)
# Check that we can also add an already added appointment (same locator)
added_appointment, sig = watcher.add_appointment(appointment, user_pk)
assert added_appointment is True
assert Cryptographer.verify_rpk(
watcher.signing_key.public_key, Cryptographer.recover_pk(appointment.serialize(), sig)
assert Cryptographer.get_compressed_pk(watcher.signing_key.public_key) == Cryptographer.get_compressed_pk(
Cryptographer.recover_pk(appointment.serialize(), sig)
)
# If two appointments with the same locator from the same user are added, they are overwritten, but if they come
@@ -153,8 +148,8 @@ def test_add_appointment(watcher):
different_user_pk = get_random_value_hex(33)
added_appointment, sig = watcher.add_appointment(appointment, different_user_pk)
assert added_appointment is True
assert Cryptographer.verify_rpk(
watcher.signing_key.public_key, Cryptographer.recover_pk(appointment.serialize(), sig)
assert Cryptographer.get_compressed_pk(watcher.signing_key.public_key) == Cryptographer.get_compressed_pk(
Cryptographer.recover_pk(appointment.serialize(), sig)
)
assert len(watcher.locator_uuid_map[appointment.locator]) == 2
@@ -172,8 +167,8 @@ def test_add_too_many_appointments(watcher):
added_appointment, sig = watcher.add_appointment(appointment, user_pk)
assert added_appointment is True
assert Cryptographer.verify_rpk(
watcher.signing_key.public_key, Cryptographer.recover_pk(appointment.serialize(), sig)
assert Cryptographer.get_compressed_pk(watcher.signing_key.public_key) == Cryptographer.get_compressed_pk(
Cryptographer.recover_pk(appointment.serialize(), sig)
)
appointment, dispute_tx = generate_dummy_appointment(