boost::shared_ptr<boost::asio::ssl::context> http_server_base::new_context(boost::system::error_code & ec) { // see create_server_pem.bat which in the create_pem folder auto ptr = boost::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23); if (!ptr) { return nullptr; } ptr->set_options( boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::single_dh_use, ec); if (ec) return nullptr; ptr->set_password_callback(&http_server_base::get_password, ec); if (ec) return nullptr; ptr->use_certificate_chain_file("work.crt", ec); if (ec) return nullptr; ptr->use_private_key_file("work.key", boost::asio::ssl::context::pem, ec); if (ec) return nullptr; ptr->use_tmp_dh_file("dh512.pem", ec); if (ec) return nullptr; return ptr; }
void TcpServer::AsyncSecureAccept() { auto errorHandler = std::bind(&TcpServer::ErrorHandler, this, std::placeholders::_1, std::placeholders::_2); auto context = boost::asio::ssl::context(boost::asio::ssl::context::sslv23); auto optionsMask = boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::single_dh_use; if (_securityOptions.VerifyClient) { auto verifyCallback = [](bool preverified, boost::asio::ssl::verify_context& ctx) { std::cout << "Verifying certificate, pre-verified: " << std::string(preverified ? "true" : "false"); char subject_name[256]; X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle()); X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256); LOG() << "Verifying, subject: " << subject_name << "\n"; char issuer_name[256]; X509_NAME_oneline(X509_get_issuer_name(cert), issuer_name, 256); LOG() << "Verifying, issuer: " << issuer_name << "\n"; return preverified; }; context.set_verify_mode(boost::asio::ssl::context::verify_fail_if_no_peer_cert | boost::asio::ssl::verify_peer); context.set_verify_callback(verifyCallback); context.load_verify_file(_securityOptions.ClientVerifyFile); } context.set_options(optionsMask); context.set_password_callback(std::bind(&TcpServer::GetPassword, this)); context.use_certificate_chain_file(_securityOptions.CertificateFilename); context.use_rsa_private_key_file(_securityOptions.PrivKeyFilename, boost::asio::ssl::context::pem); context.use_tmp_dh_file(_securityOptions.DHExchangeFilename); auto conn = std::make_shared<TcpSslConnection>(_ioService, std::move(context), std::move(errorHandler)); auto acceptor = std::bind(&TcpServer::SecureAcceptHandler, this, conn, std::placeholders::_1); // Async accept does not block and takes references to the socket and end point of the connection. // The connection smart pointer is kept alive by being bound to the acceptor callback. _acceptor->async_accept(conn->PeerSocket, conn->PeerEndPoint, std::move(acceptor)); }
static boost::shared_ptr<boost::asio::ssl::context> make_context(Func& password_handler, boost::system::error_code& ec, boost::asio::ssl::context::method method = boost::asio::ssl::context::sslv23, std::string certificate_chain_file = "work.crt", std::string private_key_file = "work.key", std::string dh_file = std::string() /* = "dh512.pem" */ ) { // see create_server_pem.bat which in the create_pem folder auto ptr = boost::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23); if (!ptr) { return nullptr; } ptr->set_options( boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::single_dh_use, ec); if (ec) return nullptr; ptr->set_password_callback(password_handler, ec); if (ec) return nullptr; ptr->use_certificate_chain_file(certificate_chain_file, ec); if (ec) return nullptr; ptr->use_private_key_file(private_key_file, boost::asio::ssl::context::pem, ec); if (ec) return nullptr; ptr->use_tmp_dh_file(dh_file, ec); if (ec) return nullptr; return ptr; }