END_TEST START_TEST(test_serialize_pre_key_signal_message) { int result = 0; static const char ciphertext[] = "WhisperCipherText"; ec_public_key *sender_ratchet_key = create_test_ec_public_key(global_context); ec_public_key *sender_identity_key = create_test_ec_public_key(global_context); ec_public_key *receiver_identity_key = create_test_ec_public_key(global_context); ec_public_key *base_key = create_test_ec_public_key(global_context); ec_public_key *identity_key = create_test_ec_public_key(global_context); uint8_t mac_key[RATCHET_MAC_KEY_LENGTH]; memset(mac_key, 1, sizeof(mac_key)); signal_message *message = 0; pre_key_signal_message *pre_key_message = 0; pre_key_signal_message *result_pre_key_message = 0; result = signal_message_create(&message, 3, mac_key, sizeof(mac_key), sender_ratchet_key, 2, /* counter */ 1, /* previous counter */ (uint8_t *)ciphertext, sizeof(ciphertext) - 1, sender_identity_key, receiver_identity_key, global_context); ck_assert_int_eq(result, 0); uint32_t pre_key_id = 56; result = pre_key_signal_message_create(&pre_key_message, 3, /* message version */ 42, /* registration ID */ &pre_key_id, /* pre key ID */ 72, /* signed pre key ID */ base_key, identity_key, message, global_context); ck_assert_int_eq(result, 0); signal_buffer *serialized = ciphertext_message_get_serialized((ciphertext_message *)pre_key_message); ck_assert_ptr_ne(serialized, 0); result = pre_key_signal_message_deserialize(&result_pre_key_message, signal_buffer_data(serialized), signal_buffer_len(serialized), global_context); ck_assert_int_eq(result, 0); int version1 = pre_key_signal_message_get_message_version(pre_key_message); int version2 = pre_key_signal_message_get_message_version(result_pre_key_message); ck_assert_int_eq(version1, version2); ec_public_key *identity_key1 = pre_key_signal_message_get_identity_key(pre_key_message); ec_public_key *identity_key2 = pre_key_signal_message_get_identity_key(result_pre_key_message); ck_assert_int_eq(ec_public_key_compare(identity_key1, identity_key2), 0); int registration_id1 = pre_key_signal_message_get_registration_id(pre_key_message); int registration_id2 = pre_key_signal_message_get_registration_id(result_pre_key_message); ck_assert_int_eq(registration_id1, registration_id2); int has_pre_key_id1 = pre_key_signal_message_has_pre_key_id(pre_key_message); int has_pre_key_id2 = pre_key_signal_message_has_pre_key_id(result_pre_key_message); ck_assert_int_eq(has_pre_key_id1, has_pre_key_id2); if(has_pre_key_id1) { int pre_key_id1 = pre_key_signal_message_get_pre_key_id(pre_key_message); int pre_key_id2 = pre_key_signal_message_get_pre_key_id(result_pre_key_message); ck_assert_int_eq(pre_key_id1, pre_key_id2); } int signed_pre_key_id1 = pre_key_signal_message_get_signed_pre_key_id(pre_key_message); int signed_pre_key_id2 = pre_key_signal_message_get_signed_pre_key_id(result_pre_key_message); ck_assert_int_eq(signed_pre_key_id1, signed_pre_key_id2); ec_public_key *base_key1 = pre_key_signal_message_get_base_key(pre_key_message); ec_public_key *base_key2 = pre_key_signal_message_get_base_key(result_pre_key_message); ck_assert_int_eq(ec_public_key_compare(base_key1, base_key2), 0); signal_message *message1 = pre_key_signal_message_get_signal_message(pre_key_message); signal_message *message2 = pre_key_signal_message_get_signal_message(result_pre_key_message); compare_signal_messages(message1, message2); /* Cleanup */ SIGNAL_UNREF(message); SIGNAL_UNREF(result_pre_key_message); SIGNAL_UNREF(pre_key_message); SIGNAL_UNREF(sender_ratchet_key); SIGNAL_UNREF(sender_identity_key); SIGNAL_UNREF(receiver_identity_key); SIGNAL_UNREF(base_key); SIGNAL_UNREF(identity_key); }
int session_cipher_decrypt_pre_key_signal_message(session_cipher *cipher, pre_key_signal_message *ciphertext, void *decrypt_context, signal_buffer **plaintext) { int result = 0; signal_buffer *result_buf = 0; session_record *record = 0; int has_unsigned_pre_key_id = 0; uint32_t unsigned_pre_key_id = 0; assert(cipher); signal_lock(cipher->global_context); if(cipher->inside_callback == 1) { result = SG_ERR_INVAL; goto complete; } result = signal_protocol_session_load_session(cipher->store, &record, cipher->remote_address); if(result < 0) { goto complete; } result = session_builder_process_pre_key_signal_message(cipher->builder, record, ciphertext, &unsigned_pre_key_id); if(result < 0) { goto complete; } has_unsigned_pre_key_id = result; result = session_cipher_decrypt_from_record_and_signal_message(cipher, record, pre_key_signal_message_get_signal_message(ciphertext), &result_buf); if(result < 0) { goto complete; } result = session_cipher_decrypt_callback(cipher, result_buf, decrypt_context); if(result < 0) { goto complete; } result = signal_protocol_session_store_session(cipher->store, cipher->remote_address, record); if(result < 0) { goto complete; } if(has_unsigned_pre_key_id) { result = signal_protocol_pre_key_remove_key(cipher->store, unsigned_pre_key_id); if(result < 0) { goto complete; } } complete: SIGNAL_UNREF(record); if(result >= 0) { *plaintext = result_buf; } else { signal_buffer_free(result_buf); } signal_unlock(cipher->global_context); return result; }