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, ""); }
wi_rsa_t * wi_socket_ssl_public_key(wi_socket_t *socket) { #ifdef HAVE_OPENSSL_SSL_H RSA *rsa = NULL; X509 *x509 = NULL; EVP_PKEY *pkey = NULL; x509 = SSL_get_peer_certificate(socket->ssl); if(!x509) { wi_error_set_openssl_error(); goto end; } pkey = X509_get_pubkey(x509); if(!pkey) { wi_error_set_openssl_error(); goto end; } rsa = EVP_PKEY_get1_RSA(pkey); if(!rsa) wi_error_set_openssl_error(); end: if(x509) X509_free(x509); if(pkey) EVP_PKEY_free(pkey); return wi_autorelease(wi_rsa_init_with_rsa(wi_rsa_alloc(), rsa)); #else return NULL; #endif }
static wi_runtime_instance_t * _wi_rsa_copy(wi_runtime_instance_t *instance) { wi_rsa_t *rsa = instance; return wi_rsa_init_with_private_key(wi_rsa_alloc(), wi_rsa_private_key(rsa)); }
void wd_server_apply_settings(void) { wi_data_t *data; wi_string_t *hostname; /* reload banner */ if(wd_settings.banner) { if(wd_settings.banner_changed) { data = wi_data_init_with_contents_of_file(wi_data_alloc(), wd_settings.banner); if(data) { wi_release(wd_banner); wd_banner = wi_retain(wi_data_base64(data)); } else { wi_log_err(WI_STR("Could not open %@: %m"), wd_settings.banner); } wi_release(data); } } else { wi_release(wd_banner); wd_banner = NULL; } /* reload server name/description */ if(wd_settings.name_changed || wd_settings.description_changed) wd_server_send_server_info(true); /* set SSL cipher list */ if(wd_settings.controlcipher) { if(!wi_socket_tls_set_ciphers(wd_control_socket_tls, wd_settings.controlcipher)) { wi_log_err(WI_STR("Could not set TLS cipher list \"%@\": %m"), wd_settings.controlcipher); } } if(wd_settings.transfercipher) { if(!wi_socket_tls_set_ciphers(wd_transfer_socket_tls, wd_settings.transfercipher)) { wi_log_err(WI_STR("Could not set TLS cipher list \"%@\": %m"), wd_settings.transfercipher); } } /* load SSL certificate */ if(!wd_certificate && !wd_private_key) { if(wd_settings.certificate) { wd_private_key = wi_rsa_init_with_pem_file(wi_rsa_alloc(), wd_settings.certificate); if(!wd_private_key) wi_log_warn(WI_STR("Could not find RSA key in %@, creating one..."), wd_settings.certificate); wd_certificate = wi_x509_init_with_pem_file(wi_x509_alloc(), wd_settings.certificate); if(!wd_certificate) wi_log_warn(WI_STR("Could not find certificate in %@, creating one..."), wd_settings.certificate); } if(!wd_private_key) { wd_private_key = wi_rsa_init_with_bits(wi_rsa_alloc(), 1024); if(wd_private_key) wi_log_info(WI_STR("Created 1024-bit RSA key")); else wi_log_err(WI_STR("Could not create RSA key: %m")); } if(!wd_certificate) { hostname = wi_process_hostname(wi_process()); wd_certificate = wi_x509_init_with_common_name(wi_x509_alloc(), wd_private_key, hostname); if(wd_certificate) wi_log_info(WI_STR("Created self-signed certificate for %@"), hostname); else wi_log_err(WI_STR("Could not create self-signed certificate: %m")); } if(!wi_socket_tls_set_private_key(wd_control_socket_tls, wd_private_key) || !wi_socket_tls_set_private_key(wd_transfer_socket_tls, wd_private_key)) { wi_log_err(WI_STR("Could not set TLS private key: %m")); } if(!wi_socket_tls_set_certificate(wd_control_socket_tls, wd_certificate) || !wi_socket_tls_set_certificate(wd_transfer_socket_tls, wd_certificate)) { wi_log_err(WI_STR("Could not set TLS certificate: %m")); } } }
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; }