Пример #1
0
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();
}
Пример #2
0
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();
}
Пример #3
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();
}