implement SignIdentity workflow

pull/25/head
Pavol Rusnak 9 years ago
parent acb8305ced
commit 73c42402b9

@ -340,3 +340,30 @@ int cryptoMultisigFingerprint(const MultisigRedeemScriptType *multisig, uint8_t
layoutProgressUpdate(true);
return 1;
}
int cryptoIdentityFingerprint(const IdentityType *identity, uint8_t *hash)
{
SHA256_CTX ctx;
sha256_Init(&ctx);
sha256_Update(&ctx, (const uint8_t *)&(identity->index), sizeof(uint32_t));
if (identity->has_proto && identity->proto[0]) {
sha256_Update(&ctx, (const uint8_t *)(identity->proto), strlen(identity->proto));
sha256_Update(&ctx, (const uint8_t *)"://", 3);
}
if (identity->has_user && identity->user[0]) {
sha256_Update(&ctx, (const uint8_t *)(identity->user), strlen(identity->user));
sha256_Update(&ctx, (const uint8_t *)"@", 1);
}
if (identity->has_host && identity->host[0]) {
sha256_Update(&ctx, (const uint8_t *)(identity->host), strlen(identity->host));
}
if (identity->has_port && identity->port[0]) {
sha256_Update(&ctx, (const uint8_t *)":", 1);
sha256_Update(&ctx, (const uint8_t *)(identity->port), strlen(identity->port));
}
if (identity->has_path && identity->path[0]) {
sha256_Update(&ctx, (const uint8_t *)(identity->path), strlen(identity->path));
}
sha256_Final(hash, &ctx);
return 1;
}

@ -48,4 +48,6 @@ int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const ui
int cryptoMultisigFingerprint(const MultisigRedeemScriptType *multisig, uint8_t *hash);
int cryptoIdentityFingerprint(const IdentityType *identity, uint8_t *hash);
#endif

@ -620,6 +620,61 @@ void fsm_msgVerifyMessage(VerifyMessage *msg)
layoutHome();
}
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 | 46;
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 message[128];
memcpy(message, msg->challenge_hidden.bytes, msg->challenge_hidden.size);
const int len = strlen(msg->challenge_visual);
memcpy(message + msg->challenge_hidden.size, msg->challenge_visual, len);
layoutProgressSwipe("Signing", 0);
if (cryptoMessageSign(message, msg->challenge_hidden.size + len, node->private_key, resp->signature.bytes) == 0) {
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, node->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();
}
void fsm_msgEncryptMessage(EncryptMessage *msg)
{
if (!msg->has_pubkey) {

@ -49,6 +49,7 @@ void fsm_msgGetAddress(GetAddress *msg);
void fsm_msgEntropyAck(EntropyAck *msg);
void fsm_msgSignMessage(SignMessage *msg);
void fsm_msgVerifyMessage(VerifyMessage *msg);
void fsm_msgSignIdentity(SignIdentity *msg);
void fsm_msgEncryptMessage(EncryptMessage *msg);
void fsm_msgDecryptMessage(DecryptMessage *msg);
//void fsm_msgPassphraseAck(PassphraseAck *msg);

@ -261,3 +261,15 @@ void layoutAddress(const char *address, const char *desc)
oledRefresh();
}
void layoutSignIdentity(const IdentityType *identity, const char *challenge)
{
layoutDialogSwipe(DIALOG_ICON_QUESTION, "Cancel", "Confirm",
"Sign identity?",
identity->has_proto ? identity->proto : NULL,
identity->has_user ? identity->user : NULL,
identity->has_host ? identity->host : NULL,
challenge,
NULL,
NULL);
}

@ -36,5 +36,6 @@ void layoutCipherKeyValue(bool encrypt, const char *key);
void layoutEncryptMessage(const uint8_t *msg, uint32_t len, bool signing);
void layoutDecryptMessage(const uint8_t *msg, uint32_t len, const char *address);
void layoutAddress(const char *address, const char *desc);
void layoutSignIdentity(const IdentityType *identity, const char *challenge);
#endif

@ -60,6 +60,7 @@ static const struct MessagesMap_t MessagesMap[] = {
{'n', 'i', MessageType_MessageType_GetAddress, GetAddress_fields, (void (*)(void *))fsm_msgGetAddress},
{'n', 'i', MessageType_MessageType_EntropyAck, EntropyAck_fields, (void (*)(void *))fsm_msgEntropyAck},
{'n', 'i', MessageType_MessageType_SignMessage, SignMessage_fields, (void (*)(void *))fsm_msgSignMessage},
{'n', 'i', MessageType_MessageType_SignIdentity, SignIdentity_fields, (void (*)(void *))fsm_msgSignIdentity},
{'n', 'i', MessageType_MessageType_VerifyMessage, VerifyMessage_fields, (void (*)(void *))fsm_msgVerifyMessage},
{'n', 'i', MessageType_MessageType_EncryptMessage, EncryptMessage_fields, (void (*)(void *))fsm_msgEncryptMessage},
{'n', 'i', MessageType_MessageType_DecryptMessage, DecryptMessage_fields, (void (*)(void *))fsm_msgDecryptMessage},
@ -80,6 +81,7 @@ static const struct MessagesMap_t MessagesMap[] = {
{'n', 'o', MessageType_MessageType_Address, Address_fields, 0},
{'n', 'o', MessageType_MessageType_EntropyRequest, EntropyRequest_fields, 0},
{'n', 'o', MessageType_MessageType_MessageSignature, MessageSignature_fields, 0},
{'n', 'o', MessageType_MessageType_SignedIdentity, SignedIdentity_fields, 0},
{'n', 'o', MessageType_MessageType_EncryptedMessage, EncryptedMessage_fields, 0},
{'n', 'o', MessageType_MessageType_DecryptedMessage, DecryptedMessage_fields, 0},
{'n', 'o', MessageType_MessageType_PassphraseRequest, PassphraseRequest_fields, 0},

Loading…
Cancel
Save