Esempio n. 1
0
void fsm_msgGetPublicKey(GetPublicKey *msg)
{
    RESP_INIT(PublicKey);

    if (!storage_is_initialized()) 
    {
        fsm_sendFailure(FailureType_Failure_NotInitialized, "Device not initialized");
        return;
    }

    if(!pin_protect_cached())
    {
        go_home();
        return;
    }

    const HDNode *node = fsm_getDerivedNode(msg->address_n, msg->address_n_count);

    if(!node) { return; }

    uint8_t public_key[33];  // copy public key to temporary buffer
    memcpy(public_key, node->public_key, sizeof(public_key));

    if(msg->has_ecdsa_curve_name)
    {
        const ecdsa_curve *curve = get_curve_by_name(msg->ecdsa_curve_name);

        if(curve)
        {
            // correct public key (since fsm_getDerivedNode uses secp256k1 curve)
            ecdsa_get_public_key33(curve, node->private_key, public_key);
        }
    }

    resp->node.depth = node->depth;
    resp->node.fingerprint = node->fingerprint;
    resp->node.child_num = node->child_num;
    resp->node.chain_code.size = 32;
    memcpy(resp->node.chain_code.bytes, node->chain_code, 32);
    resp->node.has_private_key = false;
    resp->node.has_public_key = true;
    resp->node.public_key.size = 33;
    memcpy(resp->node.public_key.bytes, public_key, 33);
    resp->has_xpub = true;
    hdnode_serialize_public(node, resp->xpub, sizeof(resp->xpub));

    if(msg->has_show_display && msg->show_display)
    {
        if(!confirm_xpub(resp->xpub))
        {
            fsm_sendFailure(FailureType_Failure_ActionCancelled, "Show extended public key cancelled");
            go_home();
            return;
        }
    }

    msg_write(MessageType_MessageType_PublicKey, resp);
    go_home();
}
Esempio n. 2
0
/*
 * verify_exchange_address - verify address specified in exchange contract belongs to device.
 *
 * INPUT
 *     coin - the CoinType
 *     address_n_count - depth of node
 *     address_n - pointer to node path
 *     address_str - string representation of address
 *     address_str_len - address length
 *     root - root hd node
 *
 * OUTPUT
 *     true/false - success/failure
 */
static bool verify_exchange_address(const CoinType *coin, size_t address_n_count,
                                    uint32_t *address_n, char *address_str, size_t address_str_len,
                                    const HDNode *root, bool is_token)
{
    static CONFIDENTIAL HDNode node;
    memcpy(&node, root, sizeof(HDNode));
    if (hdnode_private_ckd_cached(&node, address_n, address_n_count, NULL) == 0) {
        memzero(&node, sizeof(node));
        return false;
    }

    if (isEthereumLike(coin->coin_name) || is_token) {
        char tx_out_address[sizeof(((ExchangeAddress *)NULL)->address)];
        EthereumAddress_address_t ethereum_addr;

        ethereum_addr.size = 20;
        if (hdnode_get_ethereum_pubkeyhash(&node, ethereum_addr.bytes) == 0) {
            memzero(&node, sizeof(node));
            return false;
        }

        data2hex((char *)ethereum_addr.bytes, 20, tx_out_address);
        return addresses_same(tx_out_address, sizeof(tx_out_address),
                              address_str, address_str_len, true);
    }

    const curve_info *curve = get_curve_by_name(coin->curve_name);
    if (!curve) {
        memzero(&node, sizeof(node));
        return false;
    }

    char tx_out_address[36];
    hdnode_fill_public_key(&node);
    ecdsa_get_address(node.public_key, coin->address_type, curve->hasher_pubkey,
                      curve->hasher_base58, tx_out_address,
                      sizeof(tx_out_address));

    memzero(&node, sizeof(node));
    return strncmp(tx_out_address, address_str, sizeof(tx_out_address)) == 0;
}
Esempio n. 3
0
void fsm_msgGetPublicKey(GetPublicKey *msg)
{
	RESP_INIT(PublicKey);

	if (!protectPin(true)) {
		layoutHome();
		return;
	}

	const HDNode *node = fsm_getDerivedNode(msg->address_n, msg->address_n_count);
	if (!node) return;

	uint8_t public_key[33];  // copy public key to temporary buffer
	memcpy(public_key, node->public_key, sizeof(public_key));

	if (msg->has_ecdsa_curve_name) {
		const ecdsa_curve *curve = get_curve_by_name(msg->ecdsa_curve_name);
		if (curve) {
			// correct public key (since fsm_getDerivedNode uses secp256k1 curve)
			ecdsa_get_public_key33(curve, node->private_key, public_key);
		}
	}

	resp->node.depth = node->depth;
	resp->node.fingerprint = node->fingerprint;
	resp->node.child_num = node->child_num;
	resp->node.chain_code.size = 32;
	memcpy(resp->node.chain_code.bytes, node->chain_code, 32);
	resp->node.has_private_key = false;
	resp->node.has_public_key = true;
	resp->node.public_key.size = 33;
	memcpy(resp->node.public_key.bytes, public_key, 33);
	resp->has_xpub = true;
	hdnode_serialize_public(node, resp->xpub, sizeof(resp->xpub));
	msg_write(MessageType_MessageType_PublicKey, resp);
	layoutHome();
}
Esempio n. 4
0
void fsm_msgSignIdentity(SignIdentity *msg)
{
	RESP_INIT(SignedIdentity);

	layoutSignIdentity(&(msg->identity), msg->has_challenge_visual ? msg->challenge_visual : 0);
	if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) {
		fsm_sendFailure(FailureType_Failure_ActionCancelled, "Sign identity cancelled");
		layoutHome();
		return;
	}

	if (!protectPin(true)) {
		layoutHome();
		return;
	}

	uint8_t hash[32];
	if (!msg->has_identity || cryptoIdentityFingerprint(&(msg->identity), hash) == 0) {
		fsm_sendFailure(FailureType_Failure_Other, "Invalid identity");
		layoutHome();
		return;
	}

	uint32_t address_n[5];
	address_n[0] = 0x80000000 | 13;
	address_n[1] = 0x80000000 | hash[ 0] | (hash[ 1] << 8) | (hash[ 2] << 16) | (hash[ 3] << 24);
	address_n[2] = 0x80000000 | hash[ 4] | (hash[ 5] << 8) | (hash[ 6] << 16) | (hash[ 7] << 24);
	address_n[3] = 0x80000000 | hash[ 8] | (hash[ 9] << 8) | (hash[10] << 16) | (hash[11] << 24);
	address_n[4] = 0x80000000 | hash[12] | (hash[13] << 8) | (hash[14] << 16) | (hash[15] << 24);

	const HDNode *node = fsm_getDerivedNode(address_n, 5);
	if (!node) return;

	uint8_t public_key[33];  // copy public key to temporary buffer
	memcpy(public_key, node->public_key, sizeof(public_key));

	if (msg->has_ecdsa_curve_name) {
		const ecdsa_curve *curve = get_curve_by_name(msg->ecdsa_curve_name);
		if (curve) {
			// correct public key (since fsm_getDerivedNode uses secp256k1 curve)
			ecdsa_get_public_key33(curve, node->private_key, public_key);
		}
	}

	bool sign_ssh = msg->identity.has_proto && (strcmp(msg->identity.proto, "ssh") == 0);

	int result = 0;
	layoutProgressSwipe("Signing", 0);
	if (sign_ssh) { // SSH does not sign visual challenge
		result = sshMessageSign(msg->challenge_hidden.bytes, msg->challenge_hidden.size, node->private_key, resp->signature.bytes);
	} else {
		uint8_t digest[64];
		sha256_Raw(msg->challenge_hidden.bytes, msg->challenge_hidden.size, digest);
		sha256_Raw((const uint8_t *)msg->challenge_visual, strlen(msg->challenge_visual), digest + 32);
		result = cryptoMessageSign(digest, 64, node->private_key, resp->signature.bytes);
	}

	if (result == 0) {
		if (sign_ssh) {
			resp->has_address = false;
		} else {
			resp->has_address = true;
			uint8_t addr_raw[21];
			ecdsa_get_address_raw(node->public_key, 0x00, addr_raw); // hardcoded Bitcoin address type
			base58_encode_check(addr_raw, 21, resp->address, sizeof(resp->address));
		}
		resp->has_public_key = true;
		resp->public_key.size = 33;
		memcpy(resp->public_key.bytes, public_key, 33);
		resp->has_signature = true;
		resp->signature.size = 65;
		msg_write(MessageType_MessageType_SignedIdentity, resp);
	} else {
		fsm_sendFailure(FailureType_Failure_Other, "Error signing identity");
	}
	layoutHome();
}