提问人:IH8CODINGBUTILOVEIT 提问时间:11/7/2023 更新时间:11/7/2023 访问量:33
握手错误(无共享密码) 具有反向代理的 HTTPS 服务器 ASIO C++
handshake errors (no shared cipher) https server with reverse proxy ASIO c++
问:
嘿,我在握手过程中遇到了问题,握手失败/没有共享密码或未知证书。这是一个反向代理服务器,我正在尝试创建它数周。我目前无法通过这个阶段。请帮忙。
法典:
asio::ssl::context ctx_server(asio::ssl::context::tlsv12_server);
ctx_server.set_options(asio::ssl::context::default_workarounds
| asio::ssl::context::no_sslv2
| asio::ssl::context::no_sslv3
| asio::ssl::context::no_tlsv1_1
| asio::ssl::context::tlsv12_server);
add_windows_root_certs(ctx_server);
ctx_server.set_verify_mode(asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert);
std::filesystem::path cert_path = std::filesystem::current_path() / "server.crt";
std::filesystem::path key_path = std::filesystem::current_path() / "server.key";
std::filesystem::path csr_path = std::filesystem::current_path() / "server.csr";
ctx_server.set_password_callback([](auto, auto) -> std::string { return "195709059"; });
ctx_server.use_certificate_chain_file(cert_path.string());
ctx_server.use_private_key_file(key_path.string(), asio::ssl::context::pem);
auto ioc = std::make_shared<asio::io_context>();
auto ioc2 = std::make_shared<asio::io_context>();
asio::ip::tcp::acceptor acceptor{ *ioc, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 40000)};
while (1) {
asio::streambuf streambuffer;
std::error_code ec;
asio::ssl::stream<asio::ip::tcp::socket> socket{ *ioc, ctx_server };
acceptor.accept(socket.lowest_layer());
acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
socket.lowest_layer().set_option(asio::ip::tcp::socket::keep_alive(true));
socket.lowest_layer().set_option(asio::ip::tcp::no_delay(true));
std::string repquest, repsponse;
while (socket.lowest_layer().is_open()) {
// read http status
auto length = asio::read_until(socket.next_layer(), streambuffer, "\n", ec);
if (!ec) {
if (length <= 0) {
std::cout << "do_read_http_status empty length" << std::endl;
break;
}
std::istream iss(&streambuffer);
std::string temp;
std::string host, port;
// Process the response headers.
while (std::getline(iss, temp) && temp != "\r")
{
size_t i = temp.find("Host: ");
if (i != std::string::npos) {
std::string t = temp.substr(6);
size_t j = t.find(":");
host = t.substr(i, j);
port = t.substr(j + 1, t.size());
repquest += temp + '\n';
}
}
std::cout << repquest << std::endl;
ctx_server.set_verify_callback(asio::ssl::rfc2818_verification(host));
std::cout << "host: " << host << std::endl;
ready = false;
auto query = asio::ip::tcp::resolver::query(host,/*port == "443" ? "https" : "http"*/"https");
asio::ip::tcp::resolver resolver{ *ioc };
asio::error_code ec;
asio::ip::tcp::resolver::results_type results = resolver.resolve(query, ec);
if (ec || results.empty()) {
std::cout << "failed to resolve dns: " << ec.message() << std::endl;
socket.lowest_layer().shutdown(asio::socket_base::shutdown_both);
break;
}
std::string h =
"HTTP/1.1 200 OK\n"
"Connection: close\n"
"\n";
// establish TLS
socket.set_verify_mode(asio::ssl::verify_peer);
socket.set_verify_callback([&](bool preverified, asio::ssl::verify_context& ctx)
{
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);
std::cout << "Verifying:\n" << subject_name << std::endl;
return preverified;
});
// Set SNI Hostname (many hosts need this to handshake successfully)
if (!SSL_set_tlsext_host_name(socket.native_handle(), "..."))
{
std::error_code ec{ static_cast<int>(::ERR_get_error()), asio::error::get_ssl_category() };
throw asio::system_error{ ec };
};
std::shared_ptr<connection> connection(std::make_shared<connection>(*ioc2, ctx_client, results));
// initializes a connection (connect to a socket)
connection->init();
std::thread contextThread2([&ioc2]() { ioc2->run(); });
std::this_thread::sleep_for(1s);
if (!connection->isRunning()) {
std::cout << "connection couldn't establish properly.. " << std::endl;
socket.lowest_layer().shutdown(asio::socket_base::shutdown_both);
break;
}
// send CONNECT response..
auto sz = asio::write(socket.next_layer(), asio::buffer(h, h.size()), ec);
if (sz <= 0 || ec) {
std::cout << "error writing back connect response" << std::endl;
socket.lowest_layer().shutdown(asio::socket_base::shutdown_both);
break;
}
socket.handshake(asio::ssl::stream_base::server, ec);
if (ec) {
std::cout << "handshake failed" << ec.message() << std::endl;
break;
}
输出:
主机:www.google.com 早期连接成功 172.217.22.4 握手连接成功 握手失败SSLv3 警报证书未知(SSL 例程)
openssl 输出:
asiotest/server.crt -key D:/source/repos/httpasiotest/httpasiotest/server.key
>>
Enter pass phrase for D:/source/repos/httpasiotest/httpasiotest/server.key:
CONNECTED(00000148)
300A0000:error:0A000126:SSL routines:ssl3_read_n:unexpected eof while reading:ssl\record\rec_layer_s3.c:304:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 304 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
请帮忙!我严重迷路了。
答: 暂无答案
评论