void fsm_msgSignTx(SignTx *msg) { if (msg->inputs_count < 1) { fsm_sendFailure(FailureType_Failure_Other, "Transaction must have at least one input"); layoutHome(); return; } if (msg->outputs_count < 1) { fsm_sendFailure(FailureType_Failure_Other, "Transaction must have at least one output"); layoutHome(); return; } if (!protectPin(true)) { layoutHome(); return; } const CoinType *coin = fsm_getCoin(msg->coin_name); if (!coin) return; const HDNode *node = fsm_getDerivedNode(0, 0); if (!node) return; signing_init(msg->inputs_count, msg->outputs_count, coin, node); }
void fsm_msgSignMessage(SignMessage *msg) { RESP_INIT(MessageSignature); layoutSignMessage(msg->message.bytes, msg->message.size); if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, "Sign message cancelled"); layoutHome(); return; } if (!protectPin(true)) { layoutHome(); return; } const CoinType *coin = fsm_getCoin(msg->coin_name); if (!coin) return; const HDNode *node = fsm_getDerivedNode(msg->address_n, msg->address_n_count); if (!node) return; layoutProgressSwipe("Signing", 0); if (cryptoMessageSign(msg->message.bytes, msg->message.size, node->private_key, resp->signature.bytes) == 0) { resp->has_address = true; uint8_t addr_raw[21]; ecdsa_get_address_raw(node->public_key, coin->address_type, addr_raw); base58_encode_check(addr_raw, 21, resp->address, sizeof(resp->address)); resp->has_signature = true; resp->signature.size = 65; msg_write(MessageType_MessageType_MessageSignature, resp); } else { fsm_sendFailure(FailureType_Failure_Other, "Error signing message"); } layoutHome(); }
void fsm_msgGetAddress(GetAddress *msg) { RESP_INIT(Address); if (!protectPin(true)) { layoutHome(); return; } const CoinType *coin = fsm_getCoin(msg->coin_name); if (!coin) return; const HDNode *node = fsm_getDerivedNode(msg->address_n, msg->address_n_count); if (!node) return; if (msg->has_multisig) { layoutProgressSwipe("Preparing", 0); if (cryptoMultisigPubkeyIndex(&(msg->multisig), node->public_key) < 0) { fsm_sendFailure(FailureType_Failure_Other, "Pubkey not found in multisig script"); layoutHome(); return; } uint8_t buf[32]; if (compile_script_multisig_hash(&(msg->multisig), buf) == 0) { fsm_sendFailure(FailureType_Failure_Other, "Invalid multisig script"); layoutHome(); return; } ripemd160(buf, 32, buf + 1); buf[0] = coin->address_type_p2sh; // multisig cointype base58_encode_check(buf, 21, resp->address, sizeof(resp->address)); } else { ecdsa_get_address(node->public_key, coin->address_type, resp->address, sizeof(resp->address)); } if (msg->has_show_display && msg->show_display) { char desc[16]; if (msg->has_multisig) { strlcpy(desc, "Msig __ of __:", sizeof(desc)); const uint32_t m = msg->multisig.m; const uint32_t n = msg->multisig.pubkeys_count; desc[5] = (m < 10) ? ' ': ('0' + (m / 10)); desc[6] = '0' + (m % 10); desc[11] = (n < 10) ? ' ': ('0' + (n / 10)); desc[12] = '0' + (n % 10); } else { strlcpy(desc, "Address:", sizeof(desc)); } layoutAddress(resp->address, desc); if (!protectButton(ButtonRequestType_ButtonRequest_Address, true)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, "Show address cancelled"); layoutHome(); return; } } msg_write(MessageType_MessageType_Address, resp); layoutHome(); }
void fsm_msgSignMessage(SignMessage *msg) { RESP_INIT(MessageSignature); if (!storage_is_initialized()) { fsm_sendFailure(FailureType_Failure_NotInitialized, "Device not initialized"); return; } if(!confirm(ButtonRequestType_ButtonRequest_SignMessage, "Sign Message", (char *)msg->message.bytes)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, "Sign message cancelled"); go_home(); return; } if(!pin_protect_cached()) { go_home(); return; } const CoinType *coin = fsm_getCoin(msg->coin_name); if(!coin) { return; } const HDNode *node = fsm_getDerivedNode(msg->address_n, msg->address_n_count); if(!node) { return; } if(cryptoMessageSign(coin, msg->message.bytes, msg->message.size, node->private_key, resp->signature.bytes) == 0) { resp->has_address = true; uint8_t addr_raw[21]; ecdsa_get_address_raw(node->public_key, coin->address_type, addr_raw); base58_encode_check(addr_raw, 21, resp->address, sizeof(resp->address)); resp->has_signature = true; resp->signature.size = 65; msg_write(MessageType_MessageType_MessageSignature, resp); } else { fsm_sendFailure(FailureType_Failure_Other, "Error signing message"); } go_home(); }
void fsm_msgSignTx(SignTx *msg) { if (!storage_is_initialized()) { fsm_sendFailure(FailureType_Failure_NotInitialized, "Device not initialized"); return; } if(msg->inputs_count < 1) { fsm_sendFailure(FailureType_Failure_Other, "Transaction must have at least one input"); go_home(); return; } if(msg->outputs_count < 1) { fsm_sendFailure(FailureType_Failure_Other, "Transaction must have at least one output"); go_home(); return; } if(!pin_protect("Enter Current PIN")) { go_home(); return; } const CoinType *coin = fsm_getCoin(msg->coin_name); if(!coin) { return; } /* master node */ const HDNode *node = fsm_getDerivedNode(0, 0); if(!node) { return; } layout_simple_message("Preparing Transaction..."); signing_init(msg->inputs_count, msg->outputs_count, coin, node); }
void fsm_msgVerifyMessage(VerifyMessage *msg) { if(!msg->has_address) { fsm_sendFailure(FailureType_Failure_Other, "No address provided"); return; } if(!msg->has_message) { fsm_sendFailure(FailureType_Failure_Other, "No message provided"); return; } const CoinType *coin = fsm_getCoin(msg->coin_name); if (!coin) return; layout_simple_message("Verifying Message..."); uint8_t addr_raw[21]; if(!ecdsa_address_decode(msg->address, addr_raw)) { fsm_sendFailure(FailureType_Failure_InvalidSignature, "Invalid address"); } if(msg->signature.size == 65 && cryptoMessageVerify(coin, msg->message.bytes, msg->message.size, addr_raw, msg->signature.bytes) == 0) { if(review(ButtonRequestType_ButtonRequest_Other, "Message Verified", (char *)msg->message.bytes)) { fsm_sendSuccess("Message verified"); } } else { fsm_sendFailure(FailureType_Failure_InvalidSignature, "Invalid signature"); } go_home(); }
void fsm_msgGetAddress(GetAddress *msg) { RESP_INIT(Address); if (!storage_is_initialized()) { fsm_sendFailure(FailureType_Failure_NotInitialized, "Device not initialized"); return; } if(!pin_protect_cached()) { go_home(); return; } const CoinType *coin = fsm_getCoin(msg->coin_name); if(!coin) { return; } const HDNode *node = fsm_getDerivedNode(msg->address_n, msg->address_n_count); if(!node) { return; } if(msg->has_multisig) { if(cryptoMultisigPubkeyIndex(&(msg->multisig), node->public_key) < 0) { fsm_sendFailure(FailureType_Failure_Other, "Pubkey not found in multisig script"); go_home(); return; } uint8_t buf[32]; if(compile_script_multisig_hash(&(msg->multisig), buf) == 0) { fsm_sendFailure(FailureType_Failure_Other, "Invalid multisig script"); go_home(); return; } ripemd160(buf, 32, buf + 1); buf[0] = coin->address_type_p2sh; // multisig cointype base58_encode_check(buf, 21, resp->address, sizeof(resp->address)); } else { ecdsa_get_address(node->public_key, coin->address_type, resp->address, sizeof(resp->address)); } if(msg->has_show_display && msg->show_display) { char desc[MEDIUM_STR_BUF] = ""; if(msg->has_multisig) { const uint32_t m = msg->multisig.m; const uint32_t n = msg->multisig.pubkeys_count; /* snprintf: 22 + 10 (%lu) + 10 (%lu) + 1 (NULL) = 43 */ snprintf(desc, MEDIUM_STR_BUF, "(Multi-Signature %lu of %lu)", (unsigned long)m, (unsigned long)n); } if(!confirm_address(desc, resp->address)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, "Show address cancelled"); go_home(); return; } } msg_write(MessageType_MessageType_Address, resp); go_home(); }