void wi_test_crypto_rsa(void) { wi_rsa_t *rsa; rsa = wi_autorelease(wi_rsa_init_with_private_key(wi_rsa_alloc(), wi_data_with_base64(WI_STR("MIIBOwIBAAJBANlpi/JRzsGFCHyHARWkjg6qLnNjvgo84Shha4aOKQlQVON6LjVUTKuTGodkp7yZK0W4gfoNF/5CNbXb1Qo4xcUCAwEAAQJAafHFAJBc8HCjcgtXu/Q0RXEosZIpSVPhZIwUmb0swhw9LULNarL244HT2WJ/pSSUu3uIx+sT6mpNL+OtunQJAQIhAPSgtPWiWbHE7Bf3F4GS87PuVD2uYj9nbHuGAqfkrTaLAiEA44Tzb52/2dKz56sOW/ga/4ydsQeIQAxVBmr3uHK9zu8CIQDzQviQp5CQUeYBcurCJHMKA79r0wTKTju3niz37lQ9PwIhANdjtv5UzhpNgalxY++nSw/gtCyy38capaekvo2seoqbAiBYCzlmjq02JpohH29ijG52ecfb88uS9eUufUVoOfTC/A==")))); WI_TEST_ASSERT_NOT_NULL(rsa, ""); WI_TEST_ASSERT_EQUALS(wi_rsa_bits(rsa), 512U, ""); WI_TEST_ASSERT_EQUAL_INSTANCES( wi_rsa_public_key(rsa), wi_data_with_base64(WI_STR("MEgCQQDZaYvyUc7BhQh8hwEVpI4Oqi5zY74KPOEoYWuGjikJUFTjei41VEyrkxqHZKe8mStFuIH6DRf+QjW129UKOMXFAgMBAAE=")), ""); WI_TEST_ASSERT_EQUAL_INSTANCES( wi_rsa_decrypt(rsa, wi_rsa_encrypt(rsa, wi_string_data(WI_STR("hello world")))), wi_string_data(WI_STR("hello world")), "%m"); WI_TEST_ASSERT_EQUAL_INSTANCES( wi_rsa_decrypt(rsa, wi_rsa_encrypt(rsa, wi_string_data(WI_STR("hello world")))), wi_string_data(WI_STR("hello world")), "%m"); rsa = wi_autorelease(wi_rsa_init_with_bits(wi_rsa_alloc(), 512)); WI_TEST_ASSERT_NOT_NULL(rsa, ""); WI_TEST_ASSERT_EQUALS(wi_rsa_bits(rsa), 512U, ""); }
static void _wi_test_crypto_cipher(wi_cipher_type_t type, wi_string_t *name, wi_uinteger_t bits, wi_data_t *key, wi_data_t *iv) { wi_cipher_t *cipher; cipher = wi_autorelease(wi_cipher_init_with_key(wi_cipher_alloc(), type, key, iv)); WI_TEST_ASSERT_NOT_NULL(cipher, ""); WI_TEST_ASSERT_EQUAL_INSTANCES(wi_cipher_key(cipher), key, ""); WI_TEST_ASSERT_EQUAL_INSTANCES(wi_cipher_iv(cipher), iv, ""); WI_TEST_ASSERT_EQUALS(wi_cipher_type(cipher), type, ""); WI_TEST_ASSERT_EQUALS(wi_cipher_bits(cipher), bits, ""); WI_TEST_ASSERT_EQUAL_INSTANCES(wi_cipher_name(cipher), name, ""); WI_TEST_ASSERT_EQUAL_INSTANCES( wi_cipher_decrypt(cipher, wi_cipher_encrypt(cipher, wi_string_data(WI_STR("hello world")))), wi_string_data(WI_STR("hello world")), "%m"); WI_TEST_ASSERT_EQUAL_INSTANCES( wi_cipher_decrypt(cipher, wi_cipher_encrypt(cipher, wi_string_data(WI_STR("hello world")))), wi_string_data(WI_STR("hello world")), "%m"); cipher = wi_autorelease(wi_cipher_init_with_random_key(wi_cipher_alloc(), type)); WI_TEST_ASSERT_NOT_NULL(cipher, ""); }
void wi_test_string_encoding_conversion(void) { #ifdef WI_STRING_ENCODING wi_string_t *string, *path; wi_data_t *data; wi_string_encoding_t *encoding; encoding = wi_string_encoding_with_charset(WI_STR("ISO-8859-1"), 0); string = wi_string_with_c_string("hello world", encoding); WI_TEST_ASSERT_EQUAL_INSTANCES(string, WI_STR("hello world"), ""); data = wi_data_with_base64_string(WI_STR("aGVsbG8gd29ybGQ=")); string = wi_string_with_data(data, encoding); WI_TEST_ASSERT_EQUAL_INSTANCES(string, WI_STR("hello world"), ""); string = wi_string_with_bytes(wi_data_bytes(data), wi_data_length(data), encoding); WI_TEST_ASSERT_EQUAL_INSTANCES(string, WI_STR("hello world"), ""); path = wi_string_by_appending_path_component(wi_test_fixture_path, WI_STR("wi-string-encoding-tests-1.txt")); string = wi_string_with_contents_of_file(path, encoding); WI_TEST_ASSERT_NOT_NULL(string, ""); WI_TEST_ASSERT_EQUALS(wi_string_character_at_index(string, 0), 'h', ""); WI_TEST_ASSERT_EQUALS(wi_string_length(string), 14, ""); data = wi_string_data(WI_STR("hello world"), encoding); WI_TEST_ASSERT_EQUAL_INSTANCES(data, wi_data_with_base64_string(WI_STR("aGVsbG8gd29ybGQ=")), ""); encoding = wi_string_encoding_with_charset(WI_STR("ASCII"), 0); string = wi_string_with_contents_of_file(path, encoding); WI_TEST_ASSERT_NULL(string, ""); encoding = wi_string_encoding_with_charset(WI_STR("hello world"), 0); string = wi_string_with_contents_of_file(path, encoding); WI_TEST_ASSERT_NULL(string, ""); #endif }
static void wd_tracker_update(wd_tracker_t *tracker) { wi_socket_t *socket; wi_data_t *data; wi_string_t *string; wi_integer_t bytes; uint32_t guest, download; guest = (wd_trackers_guest_account != NULL); download = (guest && wd_trackers_guest_account->download); socket = wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), tracker->address, WI_SOCKET_UDP)); if(!socket) { wi_log_err(WI_STR("Could not create a socket for tracker %@: %m"), tracker->host); return; } string = wi_string_with_format(WI_STR("UPDATE %#@%c%u%c%u%c%u%c%u%c%llu%c"), tracker->key, WD_FIELD_SEPARATOR, wd_current_users, WD_FIELD_SEPARATOR, guest, WD_FIELD_SEPARATOR, download, WD_FIELD_SEPARATOR, wd_files_count, WD_FIELD_SEPARATOR, wd_files_size, WD_MESSAGE_SEPARATOR); data = wi_rsa_encrypt(tracker->public_key, wi_string_data(string)); bytes = wi_socket_sendto_data(socket, data); if(bytes < 0) { wi_log_err(WI_STR("Could not send message to tracker %@: %m"), tracker->host); return; } }
static wi_boolean_t _wi_p7_socket_accept_key_exchange(wi_p7_socket_t *p7_socket, wi_time_interval_t timeout) { wi_p7_message_t *p7_message; wi_data_t *data, *rsa, *key, *iv; wi_string_t *string, *username, *client_password, *server_password1, *server_password2; p7_message = wi_p7_message_with_name(WI_STR("p7.encryption"), p7_socket); if(!p7_message) return false; rsa = wi_rsa_public_key(p7_socket->rsa); if(!wi_p7_message_set_data_for_name(p7_message, rsa, WI_STR("p7.encryption.public_key"))) return false; if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) return false; p7_message = wi_p7_socket_read_message(p7_socket, timeout); if(!p7_message) return false; if(!wi_is_equal(p7_message->name, WI_STR("p7.encryption.reply"))) { wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, WI_STR("Message should be \"p7.encryption.reply\", not \"%@\""), p7_message->name); return false; } key = wi_p7_message_data_for_name(p7_message, WI_STR("p7.encryption.cipher_key")); iv = wi_p7_message_data_for_name(p7_message, WI_STR("p7.encryption.cipher_iv")); if(!key) { wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, WI_STR("Message has no \"p7.encryption.cipher_key\" field")); return false; } key = wi_rsa_decrypt(p7_socket->rsa, key); if(iv) iv = wi_rsa_decrypt(p7_socket->rsa, iv); p7_socket->cipher = wi_cipher_init_with_key(wi_cipher_alloc(), _WI_P7_ENCRYPTION_OPTIONS_TO_CIPHER(p7_socket->options), key, iv); if(!p7_socket->cipher) return false; data = wi_p7_message_data_for_name(p7_message, WI_STR("p7.encryption.username")); if(!data) { wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, WI_STR("Message has no \"p7.encryption.username\" field")); return false; } data = wi_rsa_decrypt(p7_socket->rsa, data); if(!data) return false; username = wi_string_with_data(data); data = wi_p7_message_data_for_name(p7_message, WI_STR("p7.encryption.client_password")); if(!data) { wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, WI_STR("Message has no \"p7.encryption.client_password\" field")); return false; } data = wi_rsa_decrypt(p7_socket->rsa, data); if(!data) return false; client_password = wi_string_with_data(data); if(wi_p7_socket_password_provider) { string = (*wi_p7_socket_password_provider)(username); if(!string) { wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, WI_STR("Unknown user \"%@\" during key exchange"), username); return false; } } else { string = wi_string_sha1(WI_STR("")); } server_password1 = wi_data_sha1(wi_data_by_appending_data(wi_string_data(string), rsa)); server_password2 = wi_data_sha1(wi_data_by_appending_data(rsa, wi_string_data(string))); if(!wi_is_equal(client_password, server_password1)) { wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, WI_STR("Password mismatch for \"%@\" during key exchange"), username); return false; } p7_message = wi_p7_message_with_name(WI_STR("p7.encryption.acknowledge"), p7_socket); if(!p7_message) return false; data = wi_cipher_encrypt(p7_socket->cipher, wi_string_data(server_password2)); if(!data) return false; if(!wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.server_password"))) return false; if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) return false; p7_socket->encryption_enabled = true; return true; }
static wi_boolean_t _wi_p7_socket_connect_key_exchange(wi_p7_socket_t *p7_socket, wi_time_interval_t timeout, wi_string_t *username, wi_string_t *password) { wi_p7_message_t *p7_message; wi_data_t *data, *rsa; wi_string_t *client_password1, *client_password2, *server_password; p7_message = wi_p7_socket_read_message(p7_socket, timeout); if(!p7_message) return false; if(!wi_is_equal(p7_message->name, WI_STR("p7.encryption"))) { wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, WI_STR("Message should be \"p7.encryption\", not \"%@\""), p7_message->name); return false; } rsa = wi_p7_message_data_for_name(p7_message, WI_STR("p7.encryption.public_key")); if(!rsa) { wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, WI_STR("Message has no \"p7.encryption.public_key\" field")); return false; } p7_socket->rsa = wi_rsa_init_with_public_key(wi_rsa_alloc(), rsa); if(!p7_socket->rsa) return false; p7_socket->cipher = wi_cipher_init_with_random_key(wi_cipher_alloc(), _WI_P7_ENCRYPTION_OPTIONS_TO_CIPHER(p7_socket->options)); if(!p7_socket->cipher) return false; p7_message = wi_p7_message_with_name(WI_STR("p7.encryption.reply"), p7_socket); if(!p7_message) return false; data = wi_rsa_encrypt(p7_socket->rsa, wi_cipher_key(p7_socket->cipher)); if(!wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.cipher_key"))) return false; data = wi_cipher_iv(p7_socket->cipher); if(data) { data = wi_rsa_encrypt(p7_socket->rsa, data); if(!wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.cipher_iv"))) return false; } data = wi_rsa_encrypt(p7_socket->rsa, wi_string_data(username)); if(!data) return false; if(!wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.username"))) return false; if(!password) password = WI_STR(""); client_password1 = wi_data_sha1(wi_data_by_appending_data(wi_string_data(wi_string_sha1(password)), rsa)); client_password2 = wi_data_sha1(wi_data_by_appending_data(rsa, wi_string_data(wi_string_sha1(password)))); data = wi_rsa_encrypt(p7_socket->rsa, wi_string_data(client_password1)); if(!data) return false; if(!wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.client_password"))) return false; if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) return false; p7_message = wi_p7_socket_read_message(p7_socket, timeout); if(!p7_message) return false; if(!wi_is_equal(p7_message->name, WI_STR("p7.encryption.acknowledge"))) { wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, WI_STR("Message should be \"p7.encryption.acknowledge\", not \"%@\""), p7_message->name); return false; } data = wi_p7_message_data_for_name(p7_message, WI_STR("p7.encryption.server_password")); if(!data) { wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, WI_STR("Message has no \"p7.encryption.server_password\" field")); return false; } data = wi_cipher_decrypt(p7_socket->cipher, data); if(!data) return false; server_password = wi_string_with_data(data); if(!wi_is_equal(server_password, client_password2)) { wi_error_set_libwired_p7_error(WI_ERROR_P7_HANDSHAKEFAILED, WI_STR("Password mismatch during key exchange")); return false; } p7_socket->encryption_enabled = true; return true; }