فهرست منبع

Let the SSL chain policy alone judge the Windows chain (#2618)

verify_cert_with_windows_schannel() rejected a chain whenever
TrustStatus.dwErrorStatus was non-zero, before
CertVerifyCertificateChainPolicy() ran. The
CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGS flag passed to that
policy check was therefore dead code: a certificate without revocation
information, or one whose CRL could not be fetched, failed with
CERT_TRUST_REVOCATION_STATUS_UNKNOWN.

Drop the pre-check so the SSL chain policy is the only judge.
Revocation checking becomes best-effort: a revoked certificate and
every other chain error are still rejected, while an undetermined
revocation status is accepted.

On a rejected chain, ssl_backend_error() now holds the policy status,
such as CERT_E_UNTRUSTEDROOT, instead of the trust status bit mask.
yhirose 13 ساعت پیش
والد
کامیت
e803f5e413
3فایلهای تغییر یافته به همراه4 افزوده شده و 12 حذف شده
  1. 1 1
      README.md
  2. 0 6
      httplib.h
  3. 3 5
      test/test.cc

+ 1 - 1
README.md

@@ -230,7 +230,7 @@ cpp-httplib automatically integrates with the OS certificate store on macOS and
 | Platform | Behavior | Disable (compile time) |
 | :------- | :------- | :--------------------- |
 | macOS | Loads system certs from Keychain (link `CoreFoundation` and `Security` with `-framework`). Requires Apple Clang; GCC is not supported for this feature. | `CPPHTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES` |
-| Windows | Verifies the certificate chain with CryptoAPI (`CertGetCertificateChain` / `CertVerifyCertificateChainPolicy`) instead of the TLS backend, with revocation checking. Windows fetches missing roots and intermediates on demand. With a custom CA, the TLS backend verifies the chain instead; with `set_server_certificate_verifier()`, both do. | `CPPHTTPLIB_DISABLE_WINDOWS_AUTOMATIC_ROOT_CERTIFICATES_UPDATE` |
+| Windows | Verifies the certificate chain with CryptoAPI (`CertGetCertificateChain` / `CertVerifyCertificateChainPolicy`) instead of the TLS backend. Revocation checking is best-effort: a revoked server certificate is rejected, while one whose revocation status cannot be determined is accepted. Windows fetches missing roots and intermediates on demand. With a custom CA, the TLS backend verifies the chain instead; with `set_server_certificate_verifier()`, both do. | `CPPHTTPLIB_DISABLE_WINDOWS_AUTOMATIC_ROOT_CERTIFICATES_UPDATE` |
 
 On Windows, verification can also be disabled at runtime:
 

+ 0 - 6
httplib.h

@@ -10858,12 +10858,6 @@ inline bool verify_cert_with_windows_schannel(
   auto chain_guard =
       scope_exit([&] { CertFreeCertificateChain(chain_context); });
 
-  // Check if chain has errors
-  if (chain_context->TrustStatus.dwErrorStatus != CERT_TRUST_NO_ERROR) {
-    out_error = chain_context->TrustStatus.dwErrorStatus;
-    return false;
-  }
-
   // Verify SSL policy
   SSL_EXTRA_CERT_CHAIN_POLICY_PARA extra_policy_para = {};
   extra_policy_para.cbSize = sizeof(extra_policy_para);

+ 3 - 5
test/test.cc

@@ -14189,9 +14189,8 @@ TEST(SSLClientTest, WindowsCertificateVerification_ServerIntermediates_Online) {
                    << " ssl_backend_error=" << res.ssl_backend_error();
 }
 
-// Windows, not the backend, decides on the chain: the error carries a
-// CryptoAPI trust status, which no backend error for a self-signed
-// certificate has.
+// Windows, not the backend, decides on the chain: the error is a CryptoAPI
+// policy status, which no backend reports for a self-signed certificate.
 TEST(SSLClientTest, WindowsCertificateVerification_RejectsUntrustedRoot) {
   SSLServer svr(SERVER_CERT2_FILE, SERVER_PRIVATE_KEY_FILE);
   ASSERT_TRUE(svr.is_valid());
@@ -14211,8 +14210,7 @@ TEST(SSLClientTest, WindowsCertificateVerification_RejectsUntrustedRoot) {
   auto res = cli.Get("/");
   ASSERT_FALSE(res);
   EXPECT_EQ(Error::SSLServerVerification, res.error());
-  EXPECT_NE(0u, res.ssl_backend_error() & CERT_TRUST_IS_UNTRUSTED_ROOT)
-      << "ssl_backend_error=" << res.ssl_backend_error();
+  EXPECT_EQ(static_cast<DWORD>(CERT_E_UNTRUSTEDROOT), res.ssl_backend_error());
 }
 #endif