void ssl_acceptot_proc(void *arg) { iocp::fiber_acceptor *acceptor = static_cast<iocp::fiber_acceptor *>(arg); iocp::error_code ec; ec = acceptor->bind_and_listen(iocp::address::any, 60443, 500); if (ec) std::cerr << "bind & listen: " << ec.to_string() << std::endl; ssl::init(); ssl::context server_ctx(ssl::sslv23_server), client_ctx(ssl::sslv23_client); server_ctx.use_certificate_file("chain.pem", ssl::pem); server_ctx.use_rsa_private_key_file("privkey.pem", ssl::pem); iocp::fiber_ssl_socket *ns; for (;;) { ns = new iocp::fiber_ssl_socket(server_ctx, acceptor->service()); ec = acceptor->accept(*ns); if (ec) { std::cerr << "accept: " << ec.to_string() << std::endl; break; } else { ns->invoke(ssl_proc, ns); } } }
void test_ssl() { interface ifs[16]; active_interfaces(ifs, 16); char *passwd = "password"; char *dir = chdir_temp_dir(); kdfp kdfp = { .N = 2, .r = 1, .p = 1}; uint8_t kek[KEY_LEN] = { 0 }; struct server_cfg cfg = { .passwd = passwd, .cert = "server.pem", .ifa = &ifs[0], }; pthread_t tid; EC_GROUP *group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(EC_CURVE_NAME)); EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); init_certs(group, passwd, "server.pem", "client.pem"); init_certs(group, passwd, "zerver.pem", "zlient.pem"); init_index("index", kek, &kdfp); EC_GROUP_free(group); assert(pthread_create(&tid, NULL, &run_server, &cfg) == 0); struct timeval timeout = { .tv_usec = 500 }; uint32_t usecs = 10000; sockaddr6 addr; X509 *cert = NULL, *sert = NULL; EVP_PKEY *pk = NULL, *sk = NULL; SSL_CTX *ctx = NULL; SSL *ssl = NULL; uint8_t data[KDFP_LEN]; // client/server cert & pk mismatch read_pem("client.pem", NULL, passwd, &pk, 2, &sert, &cert); read_pem("server.pem", NULL, passwd, &sk, 0); assert(client_ctx(sert, cert, sk) == NULL); assert(server_sock(&ctx, sert, pk, cfg.ifa, &addr) == -1); assert(ctx == NULL); cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk); // incorrect signature on pong read_pem("zerver.pem", NULL, passwd, &sk, 1, &sert); assert(find_server(sk, &addr, usecs, 30) == false); cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk); // incorrect server certificate read_pem("server.pem", NULL, passwd, &sk, 1, &sert); assert(find_server(sk, &addr, usecs, 30) == true); cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk); read_pem("client.pem", NULL, passwd, &pk, 2, &sert, &cert); X509_free(sert); read_pem("zerver.pem", NULL, passwd, &sk, 1, &sert); ctx = client_ctx(sert, cert, pk); assert(client_socket(ctx, &addr, &timeout) == NULL); assert(ERR_GET_REASON(ERR_get_error()) == SSL_R_CERTIFICATE_VERIFY_FAILED); cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk); // incorrect client certificate read_pem("zlient.pem", NULL, passwd, &pk, 1, &cert); read_pem("server.pem", NULL, passwd, &sk, 1, &sert); ctx = client_ctx(sert, cert, pk); assert(client_socket(ctx, &addr, &timeout) == NULL); cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk); // valid certificates read_pem("client.pem", NULL, passwd, &pk, 2, &sert, &cert); read_pem("server.pem", NULL, passwd, &sk, 0); ctx = client_ctx(sert, cert, pk); assert((ssl = client_socket(ctx, &addr, &timeout))); assert(SSL_read(ssl, &data, KDFP_LEN) == KDFP_LEN); cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk); pthread_kill(tid, SIGINT); pthread_join(tid, NULL); unlink("server.pem"); unlink("client.pem"); unlink("zerver.pem"); unlink("zlient.pem"); unlink("index"); rmdir_temp_dir(dir); }