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:
parent
ccd241fe55
commit
bf562cfd4b
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,6 +108,7 @@ mypy:
|
||||
src/main.py \
|
||||
src/apps/bitcoin \
|
||||
src/apps/cardano \
|
||||
src/apps/misc \
|
||||
src/apps/webauthn
|
||||
|
||||
## code generation:
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
@ -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!")
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user