]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/ssl/cert_validate_message.cc
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / ssl / cert_validate_message.cc
index b7b691eaa3804e68a432352f96739f9337dbdada..34faeaefd426bd9f46e28ebe794f7bba40d02809 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
@@ -10,6 +10,7 @@
 #include "acl/FilledChecklist.h"
 #include "globals.h"
 #include "helper.h"
+#include "sbuf/Stream.h"
 #include "security/CertError.h"
 #include "ssl/cert_validate_message.h"
 #include "ssl/ErrorDetail.h"
@@ -85,11 +86,27 @@ get_error_id(const char *label, size_t len)
     const char *e = label + len -1;
     while (e != label && xisdigit(*e)) --e;
     if (e != label) ++e;
-    return strtol(e, 0, 10);
+    return strtol(e, nullptr, 10);
 }
 
 bool
 Ssl::CertValidationMsg::parseResponse(CertValidationResponse &resp)
+{
+    try {
+        tryParsingResponse(resp);
+        return true;
+    }
+    catch (...) {
+        debugs(83, DBG_IMPORTANT, "ERROR: Cannot parse sslcrtvalidator_program response:" <<
+               Debug::Extra << "problem: " << CurrentException);
+        return false;
+    }
+}
+
+/// implements primary parseResponse() functionality until that method callers
+/// are ready to handle exceptions
+void
+Ssl::CertValidationMsg::tryParsingResponse(CertValidationResponse &resp)
 {
     std::vector<CertItem> certs;
 
@@ -103,8 +120,7 @@ Ssl::CertValidationMsg::parseResponse(CertValidationResponse &resp)
 
         size_t param_len = strcspn(param, "=\r\n");
         if (param[param_len] !=  '=') {
-            debugs(83, DBG_IMPORTANT, "WARNING: cert validator response parse error: " << param);
-            return false;
+            throw TextException(ToSBuf("Missing parameter value: ", param), Here());
         }
         const char *value=param+param_len+1;
 
@@ -112,15 +128,13 @@ Ssl::CertValidationMsg::parseResponse(CertValidationResponse &resp)
                 strncmp(param, param_cert.c_str(), param_cert.length()) == 0) {
             CertItem ci;
             ci.name.assign(param, param_len);
-            Security::CertPointer x509;
-            readCertFromMemory(x509, value);
+            const auto x509 = ReadCertificate(ReadOnlyBioTiedTo(value));
             ci.setCert(x509.get());
             certs.push_back(ci);
 
             const char *b = strstr(value, "-----END CERTIFICATE-----");
-            if (b == NULL) {
-                debugs(83, DBG_IMPORTANT, "WARNING: cert Validator response parse error: Failed  to find certificate boundary " << value);
-                return false;
+            if (b == nullptr) {
+                throw TextException(ToSBuf("Missing END CERTIFICATE boundary: ", value), Here());
             }
             b += strlen("-----END CERTIFICATE-----");
             param = b + 1;
@@ -140,8 +154,7 @@ Ssl::CertValidationMsg::parseResponse(CertValidationResponse &resp)
                 strncmp(param, param_error_name.c_str(), param_error_name.length()) == 0) {
             currentItem.error_no = Ssl::GetErrorCode(v.c_str());
             if (currentItem.error_no == SSL_ERROR_NONE) {
-                debugs(83, DBG_IMPORTANT, "WARNING: cert validator response parse error: Unknown SSL Error: " << v);
-                return false;
+                throw TextException(ToSBuf("Unknown TLS error name: ", v), Here());
             }
         } else if (param_len > param_error_reason.length() &&
                    strncmp(param, param_error_reason.c_str(), param_error_reason.length()) == 0) {
@@ -167,8 +180,7 @@ Ssl::CertValidationMsg::parseResponse(CertValidationResponse &resp)
                    std::all_of(v.begin(), v.end(), isdigit)) {
             currentItem.error_depth = atoi(v.c_str());
         } else {
-            debugs(83, DBG_IMPORTANT, "WARNING: cert validator response parse error: Unknown parameter name " << std::string(param, param_len).c_str());
-            return false;
+            throw TextException(ToSBuf("Unknown parameter name: ", std::string(param, param_len)), Here());
         }
 
         param = value + value_len;
@@ -178,12 +190,9 @@ Ssl::CertValidationMsg::parseResponse(CertValidationResponse &resp)
     typedef Ssl::CertValidationResponse::RecvdErrors::const_iterator SVCRECI;
     for (SVCRECI i = resp.errors.begin(); i != resp.errors.end(); ++i) {
         if (i->error_no == SSL_ERROR_NONE) {
-            debugs(83, DBG_IMPORTANT, "WARNING: cert validator incomplete response: Missing error name from error_id: " << i->id);
-            return false;
+            throw TextException(ToSBuf("Incomplete response; missing error name from error_id: ", i->id), Here());
         }
     }
-
-    return true;
 }
 
 X509 *
@@ -194,7 +203,7 @@ Ssl::CertValidationMsg::getCertByName(std::vector<CertItem> const &certs, std::s
         if (ci->name.compare(name) == 0)
             return ci->cert.get();
     }
-    return NULL;
+    return nullptr;
 }
 
 uint64_t