diff --git a/common/protob/messages-solana.proto b/common/protob/messages-solana.proto index 03da7d4d3..d62c52a99 100644 --- a/common/protob/messages-solana.proto +++ b/common/protob/messages-solana.proto @@ -53,28 +53,9 @@ message SolanaSignTx { } /** - * Response: Contains the hash of the signed transaction and the signature + * Response: Contains the transaction signature * @end */ message SolanaTxSignature { required bytes signature = 1; // tx signature } - -/** - * Request: Ask device to sign a Solana off-chain message - * @start - * @next SolanaOffChainMessageSignature - * @next Failure - */ -message SolanaSignOffChainMessage { - repeated uint32 address_n = 1; // BIP-32 path to derive the key to sign with - required bytes serialized_message = 2; // serialized off-chain message to be signed -} - -/** - * Response: Contains a off-chain message signature - * @end - */ -message SolanaOffChainMessageSignature { - required bytes signature = 1; // off-chain message signature -} diff --git a/common/protob/messages.proto b/common/protob/messages.proto index b6697b106..04a31d195 100644 --- a/common/protob/messages.proto +++ b/common/protob/messages.proto @@ -367,6 +367,4 @@ enum MessageType { MessageType_SolanaAddress = 903 [(wire_out) = true]; MessageType_SolanaSignTx = 904 [(wire_in) = true]; MessageType_SolanaTxSignature = 905 [(wire_out) = true]; - MessageType_SolanaSignOffChainMessage = 906 [(wire_in) = true]; - MessageType_SolanaOffChainMessageSignature = 907 [(wire_out) = true]; } diff --git a/core/src/all_modules.py b/core/src/all_modules.py index 1352e34e2..c57c56ec0 100644 --- a/core/src/all_modules.py +++ b/core/src/all_modules.py @@ -393,8 +393,6 @@ apps.solana.parsing.parse_instructions import apps.solana.parsing.parse_instructions apps.solana.parsing.utils import apps.solana.parsing.utils -apps.solana.sign_off_chain_message -import apps.solana.sign_off_chain_message apps.solana.sign_tx import apps.solana.sign_tx apps.solana.types diff --git a/core/src/apps/solana/sign_off_chain_message.py b/core/src/apps/solana/sign_off_chain_message.py deleted file mode 100644 index 0b605b550..000000000 --- a/core/src/apps/solana/sign_off_chain_message.py +++ /dev/null @@ -1,142 +0,0 @@ -from typing import TYPE_CHECKING - -from apps.common.keychain import with_slip44_keychain - -from . import CURVE, PATTERNS, SLIP44_ID - -if TYPE_CHECKING: - from trezor.messages import ( - SolanaSignOffChainMessage, - SolanaOffChainMessageSignature, - ) - from apps.common.keychain import Keychain - - -FORMAT_ASCII = 0 -FORMAT_UTF8 = 1 - -MAX_MESSAGE_LENGTH = 1212 - - -@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE) -async def sign_off_chain_message( - msg: SolanaSignOffChainMessage, - keychain: Keychain, -) -> SolanaOffChainMessageSignature: - from trezor.crypto import base58 - from trezor.crypto.curve import ed25519 - from trezor.messages import SolanaOffChainMessageSignature - from trezor.ui.layouts import confirm_signverify - from apps.common import seed - - address_n = msg.address_n - serialized_message = msg.serialized_message - - message, format = _parse_off_chain_message(serialized_message) - - node = keychain.derive(address_n) - - address = base58.encode(seed.remove_ed25519_prefix(node.public_key())) - - await confirm_signverify( - "SOL", message.decode("ascii" if format == 0 else "utf-8"), address, False - ) - - signature = ed25519.sign(node.private_key(), serialized_message) - - return SolanaOffChainMessageSignature(signature=signature) - - -def _parse_off_chain_message(serialized_message: bytes) -> tuple[bytes, int]: - from trezor.utils import BufferReader - - SIGNING_DOMAIN_SPECIFIER = b"\xffsolana offchain" - - serialized_message_b = BufferReader(serialized_message) - - signing_domain_specifier = serialized_message_b.read(16) - if signing_domain_specifier != SIGNING_DOMAIN_SPECIFIER: - raise ValueError("Invalid message") - - version = serialized_message_b.get() - if version != 0: - raise ValueError("Invalid message") - - format = serialized_message_b.get() - if format > FORMAT_UTF8: - raise ValueError("Invalid message") - - length = int.from_bytes(serialized_message_b.read(2), "little") - if serialized_message_b.remaining_count() != length: - raise ValueError("Invalid message") - - message = serialized_message_b.read(length) - - if format == FORMAT_ASCII and not _is_ascii(message): - raise ValueError("Invalid message") - elif format == FORMAT_UTF8 and not _is_utf8(message): - raise ValueError("Invalid message") - - return message, format - - -def _is_utf8(data: bytes) -> bool: - """Adapted from: https://www.cl.cam.ac.uk/~mgk25/ucs/utf8_check.c""" - length = len(data) - i = 0 - while i < length: - if data[i] < 0x80: - # 0xxxxxxx - i += 1 - elif (data[i] & 0xE0) == 0xC0: - # 110XXXXx 10xxxxxx - if ( - i + 1 >= length - or (data[i + 1] & 0xC0) != 0x80 - or (data[i] & 0xFE) == 0xC0 - ): # overlong? - return False - else: - i += 2 - elif (data[i] & 0xF0) == 0xE0: - # 1110XXXX 10Xxxxxx 10xxxxxx - if ( - i + 2 >= length - or (data[i + 1] & 0xC0) != 0x80 - or (data[i + 2] & 0xC0) != 0x80 - or (data[i] == 0xE0 and (data[i + 1] & 0xE0) == 0x80) - or (data[i] == 0xED and (data[i + 1] & 0xE0) == 0xA0) - or ( - data[i] == 0xEF - and data[i + 1] == 0xBF - and (data[i + 2] & 0xFE) == 0xBE - ) - ): # U+FFFE or U+FFFF? - return False - else: - i += 3 - elif (data[i] & 0xF8) == 0xF0: - # 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx - if ( - i + 3 >= length - or (data[i + 1] & 0xC0) != 0x80 - or (data[i + 2] & 0xC0) != 0x80 - or (data[i + 3] & 0xC0) != 0x80 - or (data[i] == 0xF0 and (data[i + 1] & 0xF0) == 0x80) - or (data[i] == 0xF4 and data[i + 1] > 0x8F) - or data[i] > 0xF4 - ): - return False - else: - i += 4 - else: - return False - - return True - -def _is_ascii(data: bytes) -> bool: - for byte in data: - if byte < 0x20 or byte > 0x7e: - return False; - - return True diff --git a/core/src/apps/workflow_handlers.py b/core/src/apps/workflow_handlers.py index 0e5db5b06..dee4fab80 100644 --- a/core/src/apps/workflow_handlers.py +++ b/core/src/apps/workflow_handlers.py @@ -193,8 +193,6 @@ def _find_message_handler_module(msg_type: int) -> str: return "apps.solana.get_address" if msg_type == MessageType.SolanaSignTx: return "apps.solana.sign_tx" - if msg_type == MessageType.SolanaSignOffChainMessage: - return "apps.solana.sign_off_chain_message" raise ValueError diff --git a/core/src/trezor/enums/MessageType.py b/core/src/trezor/enums/MessageType.py index f1f891fad..e3d5c3fd4 100644 --- a/core/src/trezor/enums/MessageType.py +++ b/core/src/trezor/enums/MessageType.py @@ -239,5 +239,3 @@ if not utils.BITCOIN_ONLY: SolanaAddress = 903 SolanaSignTx = 904 SolanaTxSignature = 905 - SolanaSignOffChainMessage = 906 - SolanaOffChainMessageSignature = 907 diff --git a/core/src/trezor/enums/__init__.py b/core/src/trezor/enums/__init__.py index b7cb6cd2d..94c8bfb27 100644 --- a/core/src/trezor/enums/__init__.py +++ b/core/src/trezor/enums/__init__.py @@ -257,8 +257,6 @@ if TYPE_CHECKING: SolanaAddress = 903 SolanaSignTx = 904 SolanaTxSignature = 905 - SolanaSignOffChainMessage = 906 - SolanaOffChainMessageSignature = 907 class FailureType(IntEnum): UnexpectedMessage = 1 diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index c9f689f81..d4e93927d 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -5192,36 +5192,6 @@ if TYPE_CHECKING: def is_type_of(cls, msg: Any) -> TypeGuard["SolanaTxSignature"]: return isinstance(msg, cls) - class SolanaSignOffChainMessage(protobuf.MessageType): - address_n: "list[int]" - serialized_message: "bytes" - - def __init__( - self, - *, - serialized_message: "bytes", - address_n: "list[int] | None" = None, - ) -> None: - pass - - @classmethod - def is_type_of(cls, msg: Any) -> TypeGuard["SolanaSignOffChainMessage"]: - return isinstance(msg, cls) - - class SolanaOffChainMessageSignature(protobuf.MessageType): - signature: "bytes" - - def __init__( - self, - *, - signature: "bytes", - ) -> None: - pass - - @classmethod - def is_type_of(cls, msg: Any) -> TypeGuard["SolanaOffChainMessageSignature"]: - return isinstance(msg, cls) - class StellarAsset(protobuf.MessageType): type: "StellarAssetType" code: "str | None" diff --git a/python/src/trezorlib/cli/solana.py b/python/src/trezorlib/cli/solana.py index 2a4b17a81..d5ef7e6bb 100644 --- a/python/src/trezorlib/cli/solana.py +++ b/python/src/trezorlib/cli/solana.py @@ -57,18 +57,3 @@ def sign_tx( address_n = tools.parse_path(address) client.init_device() return solana.sign_tx(client, address_n, bytes.fromhex(serialized_tx)) - - -@cli.command() -@click.option("-n", "--address", required=True, help=PATH_HELP) -@click.option("-m", "--serialized-message", required=True) -@with_client -def sign_off_chain_message( - client: "TrezorClient", - address: str, - serialized_message: str, -) -> messages.SolanaOffChainMessageSignature: - """Sign Solana off-chain message.""" - address_n = tools.parse_path(address) - client.init_device() - return solana.sign_off_chain_message(client, address_n, bytes.fromhex(serialized_message)) diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index 1ceb659e4..aaa776779 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -265,8 +265,6 @@ class MessageType(IntEnum): SolanaAddress = 903 SolanaSignTx = 904 SolanaTxSignature = 905 - SolanaSignOffChainMessage = 906 - SolanaOffChainMessageSignature = 907 class FailureType(IntEnum): @@ -6621,37 +6619,6 @@ class SolanaTxSignature(protobuf.MessageType): self.signature = signature -class SolanaSignOffChainMessage(protobuf.MessageType): - MESSAGE_WIRE_TYPE = 906 - FIELDS = { - 1: protobuf.Field("address_n", "uint32", repeated=True, required=False, default=None), - 2: protobuf.Field("serialized_message", "bytes", repeated=False, required=True), - } - - def __init__( - self, - *, - serialized_message: "bytes", - address_n: Optional[Sequence["int"]] = None, - ) -> None: - self.address_n: Sequence["int"] = address_n if address_n is not None else [] - self.serialized_message = serialized_message - - -class SolanaOffChainMessageSignature(protobuf.MessageType): - MESSAGE_WIRE_TYPE = 907 - FIELDS = { - 1: protobuf.Field("signature", "bytes", repeated=False, required=True), - } - - def __init__( - self, - *, - signature: "bytes", - ) -> None: - self.signature = signature - - class StellarAsset(protobuf.MessageType): MESSAGE_WIRE_TYPE = None FIELDS = { diff --git a/python/src/trezorlib/solana.py b/python/src/trezorlib/solana.py index 3873e85af..88e6ed196 100644 --- a/python/src/trezorlib/solana.py +++ b/python/src/trezorlib/solana.py @@ -42,17 +42,3 @@ def sign_tx( serialized_tx=serialized_tx, ) ) - - -@expect(messages.SolanaOffChainMessageSignature) -def sign_off_chain_message( - client: "TrezorClient", - address_n: List[int], - serialized_message: bytes, -) -> "MessageType": - return client.call( - messages.SolanaSignOffChainMessage( - address_n=address_n, - serialized_message=serialized_message, - ) - )