1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 07:28:10 +00:00

feat(core/misc): enable typing for misc app

This commit is contained in:
matejcik 2021-01-08 12:12:33 +01:00 committed by matejcik
parent ccd241fe55
commit bf562cfd4b
6 changed files with 78 additions and 42 deletions

View File

@ -13,8 +13,8 @@ option java_outer_classname = "TrezorMessageCrypto";
*/
message CipherKeyValue {
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
optional string key = 2; // key component of key:value
optional bytes value = 3; // value component of key:value
required string key = 2; // key component of key:value
required bytes value = 3; // value component of key:value
optional bool encrypt = 4; // are we encrypting (True) or decrypting (False)?
optional bool ask_on_encrypt = 5; // should we ask on encrypt operation?
optional bool ask_on_decrypt = 6; // should we ask on decrypt operation?
@ -26,7 +26,7 @@ message CipherKeyValue {
* @end
*/
message CipheredKeyValue {
optional bytes value = 1; // ciphered/deciphered value
required bytes value = 1; // ciphered/deciphered value
}
/**
@ -49,9 +49,9 @@ message IdentityType {
* @next Failure
*/
message SignIdentity {
optional IdentityType identity = 1; // identity
optional bytes challenge_hidden = 2; // non-visible challenge
optional string challenge_visual = 3; // challenge shown on display (e.g. date+time)
required IdentityType identity = 1; // identity
optional bytes challenge_hidden = 2 [default=""]; // non-visible challenge
optional string challenge_visual = 3 [default=""]; // challenge shown on display (e.g. date+time)
optional string ecdsa_curve_name = 4; // ECDSA curve name to use
}
@ -61,8 +61,8 @@ message SignIdentity {
*/
message SignedIdentity {
optional string address = 1; // identity address
optional bytes public_key = 2; // identity public key
optional bytes signature = 3; // signature of the identity data
required bytes public_key = 2; // identity public key
required bytes signature = 3; // signature of the identity data
}
/**
@ -72,8 +72,8 @@ message SignedIdentity {
* @next Failure
*/
message GetECDHSessionKey {
optional IdentityType identity = 1; // identity
optional bytes peer_public_key = 2; // peer's public key
required IdentityType identity = 1; // identity
required bytes peer_public_key = 2; // peer's public key
optional string ecdsa_curve_name = 3; // ECDSA curve name to use
}
@ -82,7 +82,7 @@ message GetECDHSessionKey {
* @end
*/
message ECDHSessionKey {
optional bytes session_key = 1; // ECDH session key
required bytes session_key = 1; // ECDH session key
}
/**

View File

@ -108,6 +108,7 @@ mypy:
src/main.py \
src/apps/bitcoin \
src/apps/cardano \
src/apps/misc \
src/apps/webauthn
## code generation:

View File

@ -7,8 +7,12 @@ from apps.common.confirm import require_confirm
from apps.common.keychain import get_keychain
from apps.common.paths import AlwaysMatchingSchema
if False:
from trezor.messages.CipherKeyValue import CipherKeyValue
from trezor.wire import Context
async def cipher_key_value(ctx, msg):
async def cipher_key_value(ctx: Context, msg: CipherKeyValue) -> CipheredKeyValue:
keychain = await get_keychain(ctx, "secp256k1", [AlwaysMatchingSchema])
if len(msg.value) % 16 > 0:
@ -30,10 +34,10 @@ async def cipher_key_value(ctx, msg):
return CipheredKeyValue(value=value)
def compute_cipher_key_value(msg, seckey: bytes) -> bytes:
data = msg.key
data += "E1" if msg.ask_on_encrypt else "E0"
data += "D1" if msg.ask_on_decrypt else "D0"
def compute_cipher_key_value(msg: CipherKeyValue, seckey: bytes) -> bytes:
data = msg.key.encode()
data += b"E1" if msg.ask_on_encrypt else b"E0"
data += b"D1" if msg.ask_on_decrypt else b"D0"
data = hmac(hmac.SHA512, seckey, data).digest()
key = data[:32]
if msg.iv and len(msg.iv) == 16:

View File

@ -13,8 +13,16 @@ from apps.common.paths import AlwaysMatchingSchema
from .sign_identity import serialize_identity, serialize_identity_without_proto
if False:
from trezor.messages.GetECDHSessionKey import GetECDHSessionKey
from trezor.messages.IdentityType import IdentityType
async def get_ecdh_session_key(ctx, msg):
from apps.common.paths import Bip32Path
async def get_ecdh_session_key(
ctx: wire.Context, msg: GetECDHSessionKey
) -> ECDHSessionKey:
if msg.ecdsa_curve_name is None:
msg.ecdsa_curve_name = "secp256k1"
@ -34,7 +42,9 @@ async def get_ecdh_session_key(ctx, msg):
return ECDHSessionKey(session_key=session_key)
async def require_confirm_ecdh_session_key(ctx, identity):
async def require_confirm_ecdh_session_key(
ctx: wire.Context, identity: IdentityType
) -> None:
lines = chunks(serialize_identity_without_proto(identity), 18)
proto = identity.proto.upper() if identity.proto else "identity"
text = Text("Decrypt %s" % proto)
@ -42,11 +52,10 @@ async def require_confirm_ecdh_session_key(ctx, identity):
await require_confirm(ctx, text)
def get_ecdh_path(identity: str, index: int):
identity_hash = sha256(pack("<I", index) + identity).digest()
def get_ecdh_path(identity: str, index: int) -> Bip32Path:
identity_hash = sha256(pack("<I", index) + identity.encode()).digest()
address_n = (17,) + unpack("<IIII", identity_hash[:16])
address_n = [HARDENED | x for x in address_n]
address_n = [HARDENED | x for x in (17,) + unpack("<IIII", identity_hash[:16])]
return address_n

View File

@ -5,8 +5,12 @@ from trezor.ui.text import Text
from apps.common.confirm import require_confirm
if False:
from trezor.wire import Context
from trezor.messages.GetEntropy import GetEntropy
async def get_entropy(ctx, msg):
async def get_entropy(ctx: Context, msg: GetEntropy) -> Entropy:
text = Text("Confirm entropy")
text.bold("Do you really want", "to send entropy?")
text.normal("Continue only if you", "know what you are doing!")

View File

@ -1,18 +1,27 @@
from ustruct import pack, unpack
from trezor import ui
from trezor import ui, wire
from trezor.crypto.hashlib import sha256
from trezor.messages.SignedIdentity import SignedIdentity
from trezor.ui.text import Text
from trezor.utils import chunks
from apps.common import HARDENED, coins
from apps.common import HARDENED, coininfo
from apps.common.confirm import require_confirm
from apps.common.keychain import get_keychain
from apps.common.paths import AlwaysMatchingSchema
if False:
from typing import List, Optional, Union
async def sign_identity(ctx, msg):
from trezor.messages.IdentityType import IdentityType
from trezor.messages.SignIdentity import SignIdentity
from trezor.ui.text import TextContent
from apps.common.paths import Bip32Path
async def sign_identity(ctx: wire.Context, msg: SignIdentity) -> SignedIdentity:
if msg.ecdsa_curve_name is None:
msg.ecdsa_curve_name = "secp256k1"
@ -24,9 +33,10 @@ async def sign_identity(ctx, msg):
address_n = get_identity_path(identity, msg.identity.index or 0)
node = keychain.derive(address_n)
coin = coins.by_name("Bitcoin")
coin = coininfo.by_name("Bitcoin")
if msg.ecdsa_curve_name == "secp256k1":
address = node.address(coin.address_type) # hardcoded bitcoin address type
# hardcoded bitcoin address type
address: Optional[str] = node.address(coin.address_type)
else:
address = None
pubkey = node.public_key()
@ -70,8 +80,10 @@ async def sign_identity(ctx, msg):
return SignedIdentity(address=address, public_key=pubkey, signature=signature)
async def require_confirm_sign_identity(ctx, identity, challenge_visual):
lines = []
async def require_confirm_sign_identity(
ctx: wire.Context, identity: IdentityType, challenge_visual: Optional[str]
) -> None:
lines: List[TextContent] = []
if challenge_visual:
lines.append(challenge_visual)
@ -84,7 +96,7 @@ async def require_confirm_sign_identity(ctx, identity, challenge_visual):
await require_confirm(ctx, text)
def serialize_identity(identity):
def serialize_identity(identity: IdentityType) -> str:
s = ""
if identity.proto:
s += identity.proto + "://"
@ -99,7 +111,7 @@ def serialize_identity(identity):
return s
def serialize_identity_without_proto(identity):
def serialize_identity_without_proto(identity: IdentityType) -> str:
proto = identity.proto
identity.proto = None # simplify serialized identity string
s = serialize_identity(identity)
@ -107,17 +119,20 @@ def serialize_identity_without_proto(identity):
return s
def get_identity_path(identity: str, index: int):
identity_hash = sha256(pack("<I", index) + identity).digest()
def get_identity_path(identity: str, index: int) -> Bip32Path:
identity_hash = sha256(pack("<I", index) + identity.encode()).digest()
address_n = (13,) + unpack("<IIII", identity_hash[:16])
address_n = [HARDENED | x for x in address_n]
address_n = [HARDENED | x for x in (13,) + unpack("<IIII", identity_hash[:16])]
return address_n
def sign_challenge(
seckey: bytes, challenge_hidden: bytes, challenge_visual: str, sigtype, curve: str
seckey: bytes,
challenge_hidden: bytes,
challenge_visual: str,
sigtype: Union[str, coininfo.CoinInfo],
curve: str,
) -> bytes:
from trezor.crypto.hashlib import sha256
@ -133,19 +148,22 @@ def sign_challenge(
data = challenge_hidden
elif sigtype == "signify":
if curve != "ed25519":
raise ValueError("Unsupported curve")
raise wire.DataError("Unsupported curve")
data = challenge_hidden
elif sigtype == "ssh":
if curve != "ed25519":
data = sha256(challenge_hidden).digest()
else:
data = challenge_hidden
else:
elif isinstance(sigtype, coininfo.CoinInfo):
# sigtype is coin
challenge = (
sha256(challenge_hidden).digest() + sha256(challenge_visual).digest()
sha256(challenge_hidden).digest()
+ sha256(challenge_visual.encode()).digest()
)
data = message_digest(sigtype, challenge)
else:
raise wire.DataError("Unsupported sigtype")
if curve == "secp256k1":
signature = secp256k1.sign(seckey, data)
@ -154,7 +172,7 @@ def sign_challenge(
elif curve == "ed25519":
signature = ed25519.sign(seckey, data)
else:
raise ValueError("Unknown curve")
raise wire.DataError("Unknown curve")
if curve == "ed25519":
signature = b"\x00" + signature