diff --git a/src/ssb.js.c b/src/ssb.js.c index a9b48e6f..ab7bb90c 100644 --- a/src/ssb.js.c +++ b/src/ssb.js.c @@ -2239,53 +2239,60 @@ static void _tf_ssb_private_message_decrypt_work(tf_ssb_t* ssb, void* user_data) if (found) { - uint8_t* decoded = tf_malloc(work->message_size); - int decoded_length = tf_base64_decode(work->message, work->message_size - strlen(".box"), decoded, work->message_size); - uint8_t* nonce = decoded; - uint8_t* public_key = decoded + crypto_box_NONCEBYTES; - if (public_key + crypto_secretbox_KEYBYTES < decoded + decoded_length) + if (work->message_size >= strlen(".box") && memcmp(work->message + work->message_size - strlen(".box"), ".box", strlen(".box")) == 0) { - uint8_t shared_secret[crypto_secretbox_KEYBYTES] = { 0 }; - if (crypto_scalarmult(shared_secret, private_key, public_key) == 0) + uint8_t* decoded = tf_malloc(work->message_size); + int decoded_length = tf_base64_decode(work->message, work->message_size - strlen(".box"), decoded, work->message_size); + uint8_t* nonce = decoded; + uint8_t* public_key = decoded + crypto_box_NONCEBYTES; + if (public_key + crypto_secretbox_KEYBYTES < decoded + decoded_length) { - enum + uint8_t shared_secret[crypto_secretbox_KEYBYTES] = { 0 }; + if (crypto_scalarmult(shared_secret, private_key, public_key) == 0) { - k_recipient_header_bytes = crypto_secretbox_MACBYTES + sizeof(uint8_t) + crypto_secretbox_KEYBYTES - }; - for (uint8_t* p = decoded + crypto_box_NONCEBYTES + crypto_secretbox_KEYBYTES; p <= decoded + decoded_length - k_recipient_header_bytes; - p += k_recipient_header_bytes) - { - uint8_t out[k_recipient_header_bytes] = { 0 }; - int opened = crypto_secretbox_open_easy(out, p, k_recipient_header_bytes, nonce, shared_secret); - if (opened != -1) + enum { - int recipients = (int)out[0]; - uint8_t* body = decoded + crypto_box_NONCEBYTES + crypto_secretbox_KEYBYTES + k_recipient_header_bytes * recipients; - size_t body_size = decoded + decoded_length - body; - uint8_t* decrypted = tf_malloc(body_size); - uint8_t* key = out + 1; - if (crypto_secretbox_open_easy(decrypted, body, body_size, nonce, key) != -1) + k_recipient_header_bytes = crypto_secretbox_MACBYTES + sizeof(uint8_t) + crypto_secretbox_KEYBYTES + }; + for (uint8_t* p = decoded + crypto_box_NONCEBYTES + crypto_secretbox_KEYBYTES; p <= decoded + decoded_length - k_recipient_header_bytes; + p += k_recipient_header_bytes) + { + uint8_t out[k_recipient_header_bytes] = { 0 }; + int opened = crypto_secretbox_open_easy(out, p, k_recipient_header_bytes, nonce, shared_secret); + if (opened != -1) { - work->decrypted = (const char*)decrypted; - work->decrypted_size = body_size - crypto_secretbox_MACBYTES; - } - else - { - work->error = "Received key to open secret box containing message body, but it did not work."; + int recipients = (int)out[0]; + uint8_t* body = decoded + crypto_box_NONCEBYTES + crypto_secretbox_KEYBYTES + k_recipient_header_bytes * recipients; + size_t body_size = decoded + decoded_length - body; + uint8_t* decrypted = tf_malloc(body_size); + uint8_t* key = out + 1; + if (crypto_secretbox_open_easy(decrypted, body, body_size, nonce, key) != -1) + { + work->decrypted = (const char*)decrypted; + work->decrypted_size = body_size - crypto_secretbox_MACBYTES; + } + else + { + work->error = "Received key to open secret box containing message body, but it did not work."; + } } } } + else + { + work->error = "crypto_scalarmult failed."; + } } else { - work->error = "crypto_scalarmult failed."; + work->error = "Encrypted message was not long enough to contain its one-time public key."; } + tf_free(decoded); } else { - work->error = "Encrypted message was not long enough to contains its one-time public key."; + work->error = "Message does not end in \".box\"."; } - tf_free(decoded); } else {