Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions src/aleph/chains/avalanche.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import logging

from aleph.schemas.pending_messages import BasePendingMessage

LOGGER = logging.getLogger("chains.avalanche")
CHAIN_NAME = "AVAX"
MESSAGE_TEMPLATE = b"\x1AAvalanche Signed Message:\n%b"
Expand Down Expand Up @@ -49,16 +51,16 @@ async def get_chain_info(address):
return chain_id, hrp


async def verify_signature(message):
async def verify_signature(message: BasePendingMessage):
"""Verifies a signature of a message, return True if verified, false if not"""
try:
chain_id, hrp = await get_chain_info(message["sender"])
chain_id, hrp = await get_chain_info(message.sender)
except Exception:
LOGGER.exception("Avalanche sender address deserialization error")
return False

try:
signature = base58.b58decode(message["signature"])
signature = base58.b58decode(message.signature)
signature, status = await validate_checksum(signature)
if not status:
LOGGER.exception("Avalanche signature checksum error")
Expand All @@ -76,10 +78,10 @@ async def verify_signature(message):
address = await address_from_public_key(public_key.format())
address = await address_to_string(chain_id, hrp, address)

result = address == message["sender"]
result = address == message.sender

except Exception as e:
LOGGER.exception("Error processing signature for %s" % message["sender"])
LOGGER.exception("Error processing signature for %s" % message.sender)
result = False

return result
Expand Down
6 changes: 4 additions & 2 deletions src/aleph/chains/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@
from aleph.permissions import check_sender_authorization
from aleph.storage import get_json, pin_hash, add_json, get_message_content
from .tx_context import TxContext
from ..schemas.pending_messages import BasePendingMessage

LOGGER = logging.getLogger("chains.common")


async def get_verification_buffer(message: Dict) -> bytes:
async def get_verification_buffer(message: BasePendingMessage) -> bytes:
"""Returns a serialized string to verify the message integrity
(this is was it signed)
"""
return "{chain}\n{sender}\n{type}\n{item_hash}".format(**message).encode("utf-8")
buffer = f"{message.chain}\n{message.sender}\n{message.type}\n{message.item_hash}"
return buffer.encode("utf-8")


async def mark_confirmed_data(chain_name, tx_hash, height):
Expand Down
18 changes: 10 additions & 8 deletions src/aleph/chains/cosmos.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,26 @@
import hashlib
import json
import logging
from typing import Dict

import ecdsa
from cosmospy import pubkey_to_address

from aleph.chains.common import get_verification_buffer
from aleph.register_chain import register_verifier
from aleph.schemas.pending_messages import BasePendingMessage

LOGGER = logging.getLogger("chains.cosmos")
CHAIN_NAME = "CSDK"


async def get_signable_message(message):
async def get_signable_message(message: BasePendingMessage) -> Dict:
signable = (await get_verification_buffer(message)).decode("utf-8")
content_message = {
"type": "signutil/MsgSignText",
"value": {
"message": signable,
"signer": message["sender"],
"signer": message.sender,
},
}

Expand All @@ -38,7 +40,7 @@ async def get_signable_message(message):
}


async def get_verification_string(message):
async def get_verification_string(message: BasePendingMessage) -> str:
value = await get_signable_message(message)
return json.dumps(value, separators=(",", ":"), sort_keys=True)

Expand All @@ -48,11 +50,11 @@ async def get_hrp(address):
return hrp


async def verify_signature(message):
async def verify_signature(message: BasePendingMessage) -> bool:
"""Verifies a signature of a message, return True if verified, false if not"""

try:
signature = json.loads(message["signature"])
signature = json.loads(message.signature)
except Exception:
LOGGER.exception("Cosmos signature deserialization error")
return False
Expand All @@ -68,7 +70,7 @@ async def verify_signature(message):

try:
pub_key = base64.b64decode(signature.get("pub_key").get("value"))
hrp = await get_hrp(message["sender"])
hrp = await get_hrp(message.sender)
except Exception:
LOGGER.exception("Cosmos key verification error")
result = False
Expand All @@ -81,10 +83,10 @@ async def verify_signature(message):

try:
address = pubkey_to_address(pub_key, hrp=hrp)
if address != message["sender"]:
if address != message.sender:
LOGGER.warning(
"Signature for bad address %s instead of %s"
% (address, message["sender"])
% (address, message.sender)
)
return False

Expand Down
11 changes: 6 additions & 5 deletions src/aleph/chains/ethereum.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@
)
from aleph.utils import run_in_executor
from .tx_context import TxContext
from ..schemas.pending_messages import BasePendingMessage

LOGGER = logging.getLogger("chains.ethereum")
CHAIN_NAME = "ETH"


async def verify_signature(message):
async def verify_signature(message: BasePendingMessage) -> bool:
"""Verifies a signature of a message, return True if verified, false if not"""

# w3 = await loop.run_in_executor(None, get_web3, config)
Expand All @@ -52,7 +53,7 @@ async def verify_signature(message):
address = await run_in_executor(
None,
functools.partial(
Account.recover_message, message_hash, signature=message["signature"]
Account.recover_message, message_hash, signature=message.signature
),
)
# address = Account.recover_message(message_hash, signature=message['signature'])
Expand All @@ -63,16 +64,16 @@ async def verify_signature(message):
# signature=message['signature']))
# address = w3.eth.account.recoverHash(message_hash,
# signature=message['signature'])
if address == message["sender"]:
if address == message.sender:
verified = True
else:
LOGGER.warning(
"Received bad signature from %s for %s" % (address, message["sender"])
"Received bad signature from %s for %s" % (address, message.sender)
)
return False

except Exception as e:
LOGGER.exception("Error processing signature for %s" % message["sender"])
LOGGER.exception("Error processing signature for %s" % message.sender)
verified = False

return verified
Expand Down
11 changes: 6 additions & 5 deletions src/aleph/chains/nuls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,27 @@
# NulsSignature, public_key_to_hash, address_from_hash, hash_from_address,
# CHEAP_UNIT_FEE)
# from nulsexplorer.protocol.transaction import Transaction
from aleph.schemas.pending_messages import BasePendingMessage
from aleph.utils import run_in_executor

LOGGER = logging.getLogger("chains.nuls")
CHAIN_NAME = "NULS"


async def verify_signature(message):
async def verify_signature(message: BasePendingMessage) -> bool:
"""Verifies a signature of a message, return True if verified, false if not"""
sig_raw = bytes(bytearray.fromhex(message["signature"]))
sig_raw = bytes(bytearray.fromhex(message.signature))
sig = NulsSignature(sig_raw)

sender_hash = hash_from_address(message["sender"])
sender_hash = hash_from_address(message.sender)
(sender_chain_id,) = struct.unpack("h", sender_hash[:2])

hash = public_key_to_hash(sig.pub_key, sender_chain_id)

address = address_from_hash(hash)
if address != message["sender"]:
if address != message.sender:
LOGGER.warning(
"Received bad signature from %s for %s" % (address, message["sender"])
"Received bad signature from %s for %s" % (address, message.sender)
)
return False

Expand Down
11 changes: 6 additions & 5 deletions src/aleph/chains/nuls2.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
)
from aleph.utils import run_in_executor
from .tx_context import TxContext
from ..schemas.pending_messages import BasePendingMessage

LOGGER = logging.getLogger("chains.nuls2")
CHAIN_NAME = "NULS2"
Expand All @@ -44,11 +45,11 @@
DECIMALS = None # will get populated later... bad?


async def verify_signature(message):
async def verify_signature(message: BasePendingMessage) -> bool:
"""Verifies a signature of a message, return True if verified, false if not"""
sig_raw = base64.b64decode(message["signature"])
sig_raw = base64.b64decode(message.signature)

sender_hash = hash_from_address(message["sender"])
sender_hash = hash_from_address(message.sender)
(sender_chain_id,) = struct.unpack("h", sender_hash[:2])
verification = await get_verification_buffer(message)
try:
Expand All @@ -64,9 +65,9 @@ async def verify_signature(message):
LOGGER.exception("NULS Signature verification error")
return False

if address != message["sender"]:
if address != message.sender:
LOGGER.warning(
"Received bad signature from %s for %s" % (address, message["sender"])
"Received bad signature from %s for %s" % (address, message.sender)
)
return False
else:
Expand Down
8 changes: 5 additions & 3 deletions src/aleph/chains/solana.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@

import logging

from aleph.schemas.pending_messages import BasePendingMessage

LOGGER = logging.getLogger("chains.solana")
CHAIN_NAME = "SOL"


async def verify_signature(message):
async def verify_signature(message: BasePendingMessage) -> bool:
"""Verifies a signature of a message, return True if verified, false if not"""

try:
signature = json.loads(message["signature"])
signature = json.loads(message.signature)
sigdata = base58.b58decode(signature["signature"])
public_key = base58.b58decode(signature["publicKey"])
except Exception:
Expand All @@ -31,7 +33,7 @@ async def verify_signature(message):
LOGGER.exception("Solana signature version error")
return False

if message["sender"] != signature["publicKey"]:
if message.sender != signature["publicKey"]:
LOGGER.exception("Solana signature source error")
return False

Expand Down
7 changes: 4 additions & 3 deletions src/aleph/chains/substrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@

from aleph.chains.common import get_verification_buffer
from aleph.register_chain import register_verifier
from aleph.schemas.pending_messages import BasePendingMessage

LOGGER = logging.getLogger("chains.substrate")
CHAIN_NAME = "DOT"


async def verify_signature(message):
async def verify_signature(message: BasePendingMessage) -> bool:
"""Verifies a signature of a message, return True if verified, false if not"""

try:
signature = json.loads(message["signature"])
signature = json.loads(message.signature)
except Exception:
LOGGER.exception("Substrate signature deserialization error")
return False
Expand All @@ -27,7 +28,7 @@ async def verify_signature(message):
return False

try:
keypair = Keypair(ss58_address=message["sender"])
keypair = Keypair(ss58_address=message.sender)
verif = (await get_verification_buffer(message)).decode("utf-8")
result = keypair.verify(verif, signature["data"])
except Exception:
Expand Down
14 changes: 5 additions & 9 deletions src/aleph/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ async def incoming_check(ipfs_pubsub_message: Dict) -> Dict:


async def check_message(
message: Dict,
message_dict: Dict,
from_chain: bool = False,
from_network: bool = False,
trusted: bool = False,
Expand All @@ -67,24 +67,20 @@ async def check_message(
TODO: Implement it fully! Dangerous!
"""

_ = parse_message(message)
message = parse_message(message_dict)

if trusted:
# only in the case of a message programmatically built here
# from legacy native chain signing for example (signing offloaded)
return message
return message_dict
else:
message = {
k: v for k, v in message.items() if k in INCOMING_MESSAGE_AUTHORIZED_FIELDS
}
await asyncio.sleep(0)
chain = message.get("chain", None)
chain = message.chain
signer = VERIFIER_REGISTER.get(chain, None)
if signer is None:
raise InvalidMessageError("Unknown chain for validation %r" % chain)
try:
if await signer(message):
return message
return message_dict
else:
raise InvalidMessageError("The signature of the message is invalid")
except ValueError:
Expand Down
10 changes: 8 additions & 2 deletions src/aleph/register_chain.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
from typing import Awaitable, Callable, Dict

from aleph.schemas.pending_messages import BasePendingMessage

Verifier = Callable[[BasePendingMessage], Awaitable[bool]]

# We will register here processors for the chains by name
VERIFIER_REGISTER = dict()
VERIFIER_REGISTER: Dict[str, Verifier] = dict()
INCOMING_WORKERS = dict()
OUTGOING_WORKERS = dict()
BALANCE_GETTERS = dict()


def register_verifier(chain_name, handler):
def register_verifier(chain_name: str, handler: Verifier):
VERIFIER_REGISTER[chain_name] = handler


Expand Down
Loading