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 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; }