mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-18 11:09:39 +00:00
Add WebSocketClient::enable_server_hostname_verification
WebSocketClient's TLS setup already threaded ClientTlsSessionOptions::server_hostname_verification through setup_client_tls_session(), the same path SSLClient uses, but never exposed a way to set it: create_stream() called setup_client_tls_session() without an options argument, so the default (verification on) was the only reachable value. Add the public setter, mirroring ClientImpl/SSLClient/Client, and wire it into create_stream()'s ClientTlsSessionOptions. Last open item from issue #2531's WebSocketClient/SSLClient API alignment.
This commit is contained in:
1 parent
6018c7feb3
commit
86d0210391
3 files changed
+34
-5
No files matched your search
@@ -188,6 +188,7 @@ void set_ca_cert_path(const std::string &ca_cert_file_path,
|
|||||||
const std::string &ca_cert_dir_path = std::string());
|
const std::string &ca_cert_dir_path = std::string());
|
||||||
void set_ca_cert_store(tls::ca_store_t store);
|
void set_ca_cert_store(tls::ca_store_t store);
|
||||||
void enable_server_certificate_verification(bool enabled);
|
void enable_server_certificate_verification(bool enabled);
|
||||||
|
void enable_server_hostname_verification(bool enabled);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
@@ -395,6 +396,7 @@ if (ws.connect()) {
|
|||||||
httplib::ws::WebSocketClient ws("wss://example.com/ws");
|
httplib::ws::WebSocketClient ws("wss://example.com/ws");
|
||||||
ws.set_ca_cert_path("/path/to/ca-bundle.crt");
|
ws.set_ca_cert_path("/path/to/ca-bundle.crt");
|
||||||
ws.enable_server_certificate_verification(true);
|
ws.enable_server_certificate_verification(true);
|
||||||
|
ws.enable_server_hostname_verification(true); // default; false skips the identity check
|
||||||
|
|
||||||
if (ws.connect()) {
|
if (ws.connect()) {
|
||||||
ws.send("secure message");
|
ws.send("secure message");
|
||||||
|
|||||||
@@ -4360,6 +4360,7 @@ public:
|
|||||||
void set_ca_cert_store(tls::ca_store_t store);
|
void set_ca_cert_store(tls::ca_store_t store);
|
||||||
void load_ca_cert_store(const char *ca_cert, std::size_t size);
|
void load_ca_cert_store(const char *ca_cert, std::size_t size);
|
||||||
void enable_server_certificate_verification(bool enabled);
|
void enable_server_certificate_verification(bool enabled);
|
||||||
|
void enable_server_hostname_verification(bool enabled);
|
||||||
void enable_system_ca(bool enabled);
|
void enable_system_ca(bool enabled);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -4406,6 +4407,7 @@ private:
|
|||||||
bool certs_loaded_ = false;
|
bool certs_loaded_ = false;
|
||||||
SystemCAMode system_ca_mode_ = SystemCAMode::Auto;
|
SystemCAMode system_ca_mode_ = SystemCAMode::Auto;
|
||||||
bool server_certificate_verification_ = true;
|
bool server_certificate_verification_ = true;
|
||||||
|
bool server_hostname_verification_ = true;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -10137,11 +10139,12 @@ inline bool load_client_ca_config(tls::ctx_t ctx,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The parts of session setup that only SSLClient needs. WebSocketClient takes
|
// The parts of session setup that only SSLClient needs, plus the handful
|
||||||
// the defaults, which is what keeps the two clients on one implementation.
|
// WebSocketClient also exposes; everything else takes the defaults, which is
|
||||||
|
// what keeps the two clients on one implementation.
|
||||||
struct ClientTlsSessionOptions {
|
struct ClientTlsSessionOptions {
|
||||||
// SSLClient exposes this independently of certificate verification;
|
// Both SSLClient and WebSocketClient expose this independently of
|
||||||
// WebSocketClient always checks the identity when it verifies the chain.
|
// certificate verification.
|
||||||
bool server_hostname_verification = true;
|
bool server_hostname_verification = true;
|
||||||
std::function<SSLVerifierResponse(tls::session_t)> session_verifier;
|
std::function<SSLVerifierResponse(tls::session_t)> session_verifier;
|
||||||
// When non-null, guards session creation against concurrent use of the
|
// When non-null, guards session creation against concurrent use of the
|
||||||
@@ -21463,11 +21466,14 @@ inline bool WebSocketClient::create_stream(std::unique_ptr<Stream> &strm,
|
|||||||
certs_loaded_ = true;
|
certs_loaded_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
detail::ClientTlsSessionOptions options;
|
||||||
|
options.server_hostname_verification = server_hostname_verification_;
|
||||||
|
|
||||||
detail::ClientTlsSessionError tls_error;
|
detail::ClientTlsSessionError tls_error;
|
||||||
if (!detail::setup_client_tls_session(host_, tls_ctx_, tls_session_, sock_,
|
if (!detail::setup_client_tls_session(host_, tls_ctx_, tls_session_, sock_,
|
||||||
server_certificate_verification_,
|
server_certificate_verification_,
|
||||||
read_timeout_sec_, read_timeout_usec_,
|
read_timeout_sec_, read_timeout_usec_,
|
||||||
&tls_error)) {
|
&tls_error, options)) {
|
||||||
error = tls_error.error;
|
error = tls_error.error;
|
||||||
ssl_error = tls_error.ssl_error;
|
ssl_error = tls_error.ssl_error;
|
||||||
ssl_backend_error = tls_error.backend_error;
|
ssl_backend_error = tls_error.backend_error;
|
||||||
@@ -21660,6 +21666,10 @@ WebSocketClient::enable_server_certificate_verification(bool enabled) {
|
|||||||
server_certificate_verification_ = enabled;
|
server_certificate_verification_ = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void WebSocketClient::enable_server_hostname_verification(bool enabled) {
|
||||||
|
server_hostname_verification_ = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
inline void WebSocketClient::enable_system_ca(bool enabled) {
|
inline void WebSocketClient::enable_system_ca(bool enabled) {
|
||||||
system_ca_mode_ = enabled ? SystemCAMode::Enabled : SystemCAMode::Disabled;
|
system_ca_mode_ = enabled ? SystemCAMode::Enabled : SystemCAMode::Disabled;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21123,6 +21123,23 @@ TEST_F(WebSocketSSLDnsHostTest, TrustedChainWrongNameFails) {
|
|||||||
EXPECT_EQ(-1, res.status());
|
EXPECT_EQ(-1, res.status());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Same setup as TrustedChainWrongNameFails, but with hostname verification
|
||||||
|
// disabled: the chain is still checked, only the identity check is skipped
|
||||||
|
TEST_F(WebSocketSSLDnsHostTest, HostnameVerificationDisabledAcceptsWrongName) {
|
||||||
|
Start(SERVER_CERT_FILE);
|
||||||
|
|
||||||
|
ws::WebSocketClient client(url());
|
||||||
|
client.set_ca_cert_path(SERVER_CERT_FILE);
|
||||||
|
client.enable_server_hostname_verification(false);
|
||||||
|
|
||||||
|
ASSERT_TRUE(client.connect());
|
||||||
|
ASSERT_TRUE(client.send("hello"));
|
||||||
|
std::string msg;
|
||||||
|
EXPECT_EQ(ws::Text, client.read(msg));
|
||||||
|
EXPECT_EQ("hello", msg);
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
// A CA that did not sign the server certificate fails the chain, even though
|
// A CA that did not sign the server certificate fails the chain, even though
|
||||||
// the name would match
|
// the name would match
|
||||||
TEST_F(WebSocketSSLDnsHostTest, UntrustedChainFails) {
|
TEST_F(WebSocketSSLDnsHostTest, UntrustedChainFails) {
|
||||||
|
|||||||
Reference in new issue
Block a user