Exemple #1
0
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();
}
Exemple #2
0
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;
	}
	layoutProgressSwipe("Verifying", 0);
	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(msg->message.bytes, msg->message.size, addr_raw, msg->signature.bytes) == 0) {
		layoutVerifyMessage(msg->message.bytes, msg->message.size);
		protectButton(ButtonRequestType_ButtonRequest_Other, true);
		fsm_sendSuccess("Message verified");
	} else {
		fsm_sendFailure(FailureType_Failure_InvalidSignature, "Invalid signature");
	}
	layoutHome();
}
Exemple #3
0
/*
 * verify_exchange_contract() - Verify content of exchange contract is valid
 *
 * INPUT
 *     exchange:  exchange pointer
 *     root - root hd node
 * OUTPUT
 *     true/false -  success/failure
 */
static bool verify_exchange_contract(const CoinType *coin, void *vtx_out, const HDNode *root)
{
    ExchangeType *exchange;
    if (isEthereumLike(coin->coin_name)) {
        exchange = &((EthereumSignTx *)vtx_out)->exchange_type;

        /*Verify response structure from client is compatible*/
        if (exchange->signed_exchange_response.has_response) {
            /*Obsolete response data structure detected. Should be ExchangeResponseV2! */
            set_exchange_error(ERROR_EXCHANGE_RESPONSE_STRUCTURE);
            return false;
        }
    } else {
        exchange = &((TxOutputType *)vtx_out)->exchange_type;
    }

    void *tx_out_amount;
    char tx_out_address[sizeof(((ExchangeAddress *)NULL)->address)];
    memset(tx_out_address, 0, sizeof(tx_out_address));
    CoinType standard_deposit;
    const CoinType *deposit_coin = NULL;
    if (isEthereumLike(coin->coin_name)) {
        EthereumSignTx *tx_out = (EthereumSignTx *)vtx_out;
        tx_out->has_chain_id = coin->has_forkid;
        tx_out->chain_id = coin->forkid;

        if (ethereum_isNonStandardERC20Transfer(tx_out)) {
            // token specific address, shorcut, and value
            data2hex(tx_out->token_to.bytes, tx_out->token_to.size, tx_out_address);
            tx_out_amount = (void *)tx_out->token_value.bytes;
            deposit_coin = coinByShortcut(tx_out->token_shortcut);
        } else if (ethereum_isStandardERC20Transfer(tx_out)) {
            if (!ethereum_getStandardERC20Recipient(tx_out, tx_out_address, sizeof(tx_out_address)) ||
                !ethereum_getStandardERC20Amount(tx_out, &tx_out_amount) ||
                !ethereum_getStandardERC20Coin(tx_out, &standard_deposit)) {
                set_exchange_error(ERROR_EXCHANGE_RESPONSE_STRUCTURE);
                return false;
            }
            deposit_coin = &standard_deposit;
        } else {
            data2hex(tx_out->to.bytes, tx_out->to.size, tx_out_address);
            tx_out_amount = (void *)tx_out->value.bytes;
            deposit_coin = coin;
        }
    } else {
        TxOutputType *tx_out = (TxOutputType *)vtx_out;
        exchange = &tx_out->exchange_type;
        memcpy(tx_out_address, tx_out->address, sizeof(tx_out->address));
        tx_out_amount = (void *)&tx_out->amount;
        deposit_coin = coin;
    }

    if (!deposit_coin) {
        set_exchange_error(ERROR_EXCHANGE_RESPONSE_STRUCTURE);
        return false;
    }

    /* verify Exchange signature */
    uint8_t response_raw[sizeof(ExchangeResponseV2)];
    memset(response_raw, 0, sizeof(response_raw));
    int response_raw_filled_len = encode_pb(
                                (const void *)&exchange->signed_exchange_response.responseV2,
                                ExchangeResponseV2_fields,
                                response_raw,
                                sizeof(response_raw));

    if(response_raw_filled_len == 0)
    {
        set_exchange_error(ERROR_EXCHANGE_SIGNATURE);
        return false;
    }

    const CoinType *signed_coin = coinByShortcut((const char *)"BTC");
    if(cryptoMessageVerify(signed_coin, response_raw, response_raw_filled_len, ShapeShift_pubkey,
                (uint8_t *)exchange->signed_exchange_response.signature.bytes) != 0)
    {
        set_exchange_error(ERROR_EXCHANGE_SIGNATURE);
        return false;
    }

    /* verify Exchange API-Key */
    if(memcmp(ShapeShift_api_key, exchange->signed_exchange_response.responseV2.api_key.bytes,
                sizeof(ShapeShift_api_key)) != 0)
    {
        set_exchange_error(ERROR_EXCHANGE_API_KEY);
        return false;
    }

    /* verify Deposit coin type */
    if (!verify_coins_match(deposit_coin, getDepositCoin(exchange))) {
        set_exchange_error(ERROR_EXCHANGE_DEPOSIT_COINTYPE);
        return false;
    }

    /* verify Deposit address */
    if(!addresses_same(tx_out_address, sizeof(tx_out_address),
               exchange->signed_exchange_response.responseV2.deposit_address.address,
               sizeof(exchange->signed_exchange_response.responseV2.deposit_address.address),
               isEthereumLike(coin->coin_name)))
    {
        set_exchange_error(ERROR_EXCHANGE_DEPOSIT_ADDRESS);
        return false;
    }

    /* verify Deposit amount*/
    if(!verify_exchange_dep_amount(coin->coin_name,
                tx_out_amount, &exchange->signed_exchange_response.responseV2.deposit_amount))
    {
        set_exchange_error(ERROR_EXCHANGE_DEPOSIT_AMOUNT);
        return false;
    }

    /* verify Withdrawal address */
    const CoinType *withdraw_coin = getWithdrawCoin(exchange);
    if (!withdraw_coin) {
        set_exchange_error(ERROR_EXCHANGE_WITHDRAWAL_COINTYPE);
        return false;
    }

    if (!verify_coins_match(withdraw_coin, coinByNameOrTicker(exchange->withdrawal_coin_name))) {
        set_exchange_error(ERROR_EXCHANGE_WITHDRAWAL_COINTYPE);
        return false;
    }

    if (!verify_exchange_address(
             withdraw_coin,
             exchange->withdrawal_address_n_count,
             exchange->withdrawal_address_n,
             exchange->signed_exchange_response.responseV2.withdrawal_address.address,
             sizeof(exchange->signed_exchange_response.responseV2.withdrawal_address.address),
             root, withdraw_coin->has_contract_address))
    {
        set_exchange_error(ERROR_EXCHANGE_WITHDRAWAL_ADDRESS);
        return false;
    }

    /* verify Return coin type */
    const CoinType *return_coin = getReturnCoin(exchange);
    if (!return_coin) {
        set_exchange_error(ERROR_EXCHANGE_RETURN_COINTYPE);
        return false;
    }

    if (!verify_coins_match(deposit_coin, return_coin)) {
        set_exchange_error(ERROR_EXCHANGE_RETURN_COINTYPE);
        return false;
    }

    /* verify Return address */
    if (!verify_exchange_address(
             return_coin,
             exchange->return_address_n_count,
             exchange->return_address_n,
             exchange->signed_exchange_response.responseV2.return_address.address,
             sizeof(exchange->signed_exchange_response.responseV2.return_address.address),
             root, return_coin->has_contract_address))
    {
        set_exchange_error(ERROR_EXCHANGE_RETURN_ADDRESS);
        return false;
    }

    set_exchange_error(NO_EXCHANGE_ERROR);
    return true;
}