]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Use the right certificate when detailing SSL certificate validation errors.
authorMathias Fischer <maf@open.ch>
Thu, 17 Nov 2011 15:31:57 +0000 (08:31 -0700)
committerAlex Rousskov <rousskov@measurement-factory.com>
Thu, 17 Nov 2011 15:31:57 +0000 (08:31 -0700)
When an _intermediate_ SSL server certificate fails validation, we should
report errors using information in that certificate and not in the top-level
"peer" certificate. Otherwise, our details may make no sense. For example, we
may say that the validation failed due to the expired certificate and then show
an expiration date in the future (because the top-level certificate did not
expire but the intermediate certificate did).

OpenSSL X509_STORE_CTX_get_current_cert() returns the certificate that was
being tested when our certificate validation callback was called.

src/ssl/support.cc

index 8a04b5386f27d7c9a264db01f2eaf0e943560bf2..a5b5ab1e52bdb1cfeef86ef277abcec4b1925cc0 100644 (file)
@@ -252,7 +252,18 @@ ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
     if (!dont_verify_domain && server) {}
 
     if (!ok && !SSL_get_ex_data(ssl, ssl_ex_index_ssl_error_detail) ) {
-        Ssl::ErrorDetail *errDetail = new Ssl::ErrorDetail(error_no, peer_cert);
+
+        // Find the broken certificate. It may be intermediate.
+        X509 *broken_cert = peer_cert; // reasonable default if search fails
+        // Our SQUID_X509_V_ERR_DOMAIN_MISMATCH implies peer_cert is at fault.
+        if (error_no != SQUID_X509_V_ERR_DOMAIN_MISMATCH) {
+            if (X509 *last_used_cert = X509_STORE_CTX_get_current_cert(ctx))
+                broken_cert = last_used_cert;
+        }
+
+        Ssl::ErrorDetail *errDetail =
+            new Ssl::ErrorDetail(error_no, broken_cert);
+
         if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_error_detail,  errDetail)) {
             debugs(83, 2, "Failed to set Ssl::ErrorDetail in ssl_verify_cb: Certificate " << buffer);
             delete errDetail;