@@ -97,10 +97,13 @@ cli.enable_server_hostname_verification(false);
9797
9898### SSL Error Handling
9999
100- When SSL operations fail, cpp-httplib provides detailed error information through two separate error fields:
100+ When SSL operations fail, cpp-httplib provides detailed error information through ` ssl_error() ` and ` ssl_backend_error() ` :
101+
102+ - ` ssl_error() ` - Returns the TLS-level error code (e.g., ` SSL_ERROR_SSL ` for OpenSSL)
103+ - ` ssl_backend_error() ` - Returns the backend-specific error code (e.g., ` ERR_get_error() ` for OpenSSL, return value for Mbed TLS)
101104
102105``` c++
103- #define CPPHTTPLIB_OPENSSL_SUPPORT
106+ #define CPPHTTPLIB_OPENSSL_SUPPORT // or CPPHTTPLIB_MBEDTLS_SUPPORT
104107#include "path/to/httplib.h"
105108
106109httplib::Client cli ("https://example.com ");
@@ -117,18 +120,18 @@ if (!res) {
117120 break;
118121
119122 case httplib::Error::SSLLoadingCerts:
120- std::cout << "SSL cert loading failed, OpenSSL error: "
121- << std::hex << res.ssl_openssl_error () << std::endl;
123+ std::cout << "SSL cert loading failed, backend error: "
124+ << std::hex << res.ssl_backend_error () << std::endl;
122125 break;
123126
124127 case httplib::Error::SSLServerVerification:
125- std::cout << "SSL verification failed, X509 error: "
126- << res.ssl_openssl_error () << std::endl;
128+ std::cout << "SSL verification failed, verify error: "
129+ << res.ssl_backend_error () << std::endl;
127130 break;
128131
129132 case httplib::Error::SSLServerHostnameVerification:
130- std::cout << "SSL hostname verification failed, X509 error: "
131- << res.ssl_openssl_error () << std::endl;
133+ std::cout << "SSL hostname verification failed, verify error: "
134+ << res.ssl_backend_error () << std::endl;
132135 break;
133136
134137 default:
@@ -137,6 +140,50 @@ if (!res) {
137140}
138141```
139142
143+ ### Custom Certificate Verification
144+
145+ You can set a custom verification callback using `tls::VerifyCallback`:
146+
147+ ```c++
148+ httplib::Client cli("https://example.com");
149+
150+ cli.set_server_certificate_verifier(
151+ [](const httplib::tls::VerifyContext &ctx) -> bool {
152+ std::cout << "Subject CN: " << ctx.subject_cn() << std::endl;
153+ std::cout << "Issuer: " << ctx.issuer_name() << std::endl;
154+ std::cout << "Depth: " << ctx.depth << std::endl;
155+ std::cout << "Pre-verified: " << ctx.preverify_ok << std::endl;
156+
157+ // Inspect SANs (Subject Alternative Names)
158+ for (const auto &san : ctx.sans()) {
159+ std::cout << "SAN: " << san.value << std::endl;
160+ }
161+
162+ // Return true to accept, false to reject
163+ return ctx.preverify_ok;
164+ });
165+ ```
166+
167+ ### Peer Certificate Inspection
168+
169+ On the server side, you can inspect the client's peer certificate from a request handler:
170+
171+ ``` c++
172+ httplib::SSLServer svr ("./cert.pem", "./key.pem",
173+ "./client-ca-cert.pem");
174+
175+ svr.Get("/", [ ] (const httplib::Request &req, httplib::Response &res) {
176+ auto cert = req.peer_cert();
177+ if (cert) {
178+ std::cout << "Client CN: " << cert.subject_cn() << std::endl;
179+ std::cout << "Serial: " << cert.serial() << std::endl;
180+ }
181+
182+ auto sni = req.sni();
183+ std::cout << "SNI: " << sni << std::endl;
184+ });
185+ ```
186+
140187Server
141188------
142189
0 commit comments