]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
%ssl::<cert_errors logformat code part2: provide depth information
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Sun, 13 Dec 2015 17:53:57 +0000 (19:53 +0200)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Sun, 13 Dec 2015 17:53:57 +0000 (19:53 +0200)
The first implementation of %ssl::<cert_errors formating code does not provide
information about the certificate the errors belongs.
This patch prints the chain depth information for error, if exist, using the
following format for the printed certificate error:
   ERROR@depth=X

The patch also adds the "error_depth_" parameter to cert validator, used to
pass depth information from cert validator to squid.

This is a Measurement Factory project

src/format/Format.cc
src/ssl/PeerConnector.cc
src/ssl/cert_validate_message.cc
src/ssl/cert_validate_message.h
src/ssl/support.cc
src/ssl/support.h

index 44b1e878f68df8d5c24d7c66bee24ec007b77b0b..402e5faf22441783a5bd3c9fab21ead14572f1cd 100644 (file)
@@ -1248,6 +1248,10 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS
                             sb.append(errorName);
                         else
                             sb.append(sslErrorName(sslError->element.code, tmp, sizeof(tmp)));
+                        if (sslError->element.depth >= 0) {
+                            snprintf(tmp, sizeof(tmp), "@depth=%d", sslError->element.depth);
+                            sb.append(tmp);
+                        }
                     }
                     if (sb.size())
                         out = sb.termedBuf();
index 40abcb23573d6581ef1e4cb9c6ae05fbaf0fee26..f2b3ecf44fd45055480ade6eeab893739fe50cc4 100644 (file)
@@ -377,7 +377,7 @@ Ssl::PeerConnector::sslCrtvdCheckForErrors(Ssl::CertValidationResponse const &re
         if (!errDetails) {
             bool allowed = false;
             if (check) {
-                check->sslErrors = new Ssl::CertErrors(Ssl::CertError(i->error_no, i->cert.get()));
+                check->sslErrors = new Ssl::CertErrors(Ssl::CertError(i->error_no, i->cert.get(), i->error_depth));
                 if (check->fastCheck() == ACCESS_ALLOWED)
                     allowed = true;
             }
@@ -400,9 +400,9 @@ Ssl::PeerConnector::sslCrtvdCheckForErrors(Ssl::CertValidationResponse const &re
         }
 
         if (!errs)
-            errs = new Ssl::CertErrors(Ssl::CertError(i->error_no, i->cert.get()));
+            errs = new Ssl::CertErrors(Ssl::CertError(i->error_no, i->cert.get(), i->error_depth));
         else
-            errs->push_back_unique(Ssl::CertError(i->error_no, i->cert.get()));
+            errs->push_back_unique(Ssl::CertError(i->error_no, i->cert.get(), i->error_depth));
     }
     if (check)
         delete check;
index 071795d28a85438516ab7165c0476c69da3edd6a..d3a3130bf0c9ef672b6e59cbd52b78ffbde451c1 100644 (file)
@@ -145,6 +145,10 @@ Ssl::CertValidationMsg::parseResponse(CertValidationResponse &resp, STACK_OF(X50
                 //if certId is not correct sk_X509_value returns NULL
                 currentItem.setCert(sk_X509_value(peerCerts, certId));
             }
+        } else if (param_len > param_error_depth.length() &&
+                   strncmp(param, param_error_depth.c_str(), param_error_depth.length()) == 0 &&
+                   std::all_of(v.begin(), v.end(), isdigit)) {
+            currentItem.error_depth = std::stoi(v);
         } else {
             debugs(83, DBG_IMPORTANT, "WARNING: cert validator response parse error: Unknown parameter name " << std::string(param, param_len).c_str());
             return false;
@@ -238,6 +242,7 @@ const std::string Ssl::CertValidationMsg::param_cert("cert_");
 const std::string Ssl::CertValidationMsg::param_error_name("error_name_");
 const std::string Ssl::CertValidationMsg::param_error_reason("error_reason_");
 const std::string Ssl::CertValidationMsg::param_error_cert("error_cert_");
+const std::string Ssl::CertValidationMsg::param_error_depth("error_depth_");
 const std::string Ssl::CertValidationMsg::param_proto_version("proto_version");
 const std::string Ssl::CertValidationMsg::param_cipher("cipher");
 
index 2aa4e84d8361c858c77d36fe8e95bdca01501ece..59b2a4fb3166d0f5127756b81aa2dbbcbb6ccd0e 100644 (file)
@@ -48,7 +48,7 @@ public:
     class  RecvdError
     {
     public:
-        RecvdError(): id(0), error_no(SSL_ERROR_NONE), cert(NULL) {}
+        RecvdError(): id(0), error_no(SSL_ERROR_NONE), cert(NULL), error_depth(-1) {}
         RecvdError(const RecvdError &);
         RecvdError & operator =(const RecvdError &);
         void setCert(X509 *);  ///< Sets cert to the given certificate
@@ -56,6 +56,7 @@ public:
         ssl_error_t error_no; ///< The OpenSSL error code
         std::string error_reason; ///< A string describing the error
         Security::CertPointer cert; ///< The broken certificate
+        int error_depth; ///< The error depth
     };
 
     typedef std::vector<RecvdError> RecvdErrors;
@@ -116,6 +117,8 @@ public:
     static const std::string param_error_reason;
     /// Parameter name for passing the error cert ID
     static const std::string param_error_cert;
+    /// Parameter name for passing the error depth
+    static const std::string param_error_depth;
     /// Parameter name for SSL version
     static const std::string param_proto_version;
     /// Parameter name for SSL cipher
index 17bc85459bb05fcacea8cb5b5d1e83f5e02bf0f5..429fd812068208c496bbcf15da79970e92e51007 100644 (file)
@@ -285,7 +285,8 @@ ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
 
         Ssl::CertErrors *errs = static_cast<Ssl::CertErrors *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_errors));
         if (!errs) {
-            errs = new Ssl::CertErrors(Ssl::CertError(error_no, broken_cert));
+            const int depth = X509_STORE_CTX_get_error_depth(ctx);
+            errs = new Ssl::CertErrors(Ssl::CertError(error_no, broken_cert, depth));
             if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_errors,  (void *)errs)) {
                 debugs(83, 2, "Failed to set ssl error_no in ssl_verify_cb: Certificate " << buffer);
                 delete errs;
@@ -1351,12 +1352,12 @@ Ssl::CreateServer(Security::ContextPtr sslContext, const int fd, const char *squ
     return SslCreate(sslContext, fd, Ssl::Bio::BIO_TO_CLIENT, squidCtx);
 }
 
-Ssl::CertError::CertError(ssl_error_t anErr, X509 *aCert): code(anErr)
+Ssl::CertError::CertError(ssl_error_t anErr, X509 *aCert, int aDepth): code(anErr), depth(aDepth)
 {
     cert.resetAndLock(aCert);
 }
 
-Ssl::CertError::CertError(CertError const &err): code(err.code)
+Ssl::CertError::CertError(CertError const &err): code(err.code), depth(err.depth)
 {
     cert.resetAndLock(err.cert.get());
 }
index baf25c810951f853c072c67dccc93517eba87f37..86b4931dede7605edd9769fbdd0ebbf86e772e67 100644 (file)
@@ -80,7 +80,13 @@ class CertError
 public:
     ssl_error_t code; ///< certificate error code
     Security::CertPointer cert; ///< certificate with the above error code
-    CertError(ssl_error_t anErr, X509 *aCert);
+    /**
+     * Absolute cert position in the final certificate chain that may include
+     * intermediate certificates. Chain positions start with zero and increase
+     * towards the root certificate. Negative if unknown.
+     */
+    int depth;
+    CertError(ssl_error_t anErr, X509 *aCert, int depth = -1);
     CertError(CertError const &err);
     CertError & operator = (const CertError &old);
     bool operator == (const CertError &ce) const;