ssl_send_certificate_error(): Don't crash if there's no certificate information available
authorFabian Keil <fk@fabiankeil.de>
Fri, 17 Dec 2021 07:06:09 +0000 (08:06 +0100)
committerFabian Keil <fk@fabiankeil.de>
Sat, 23 Apr 2022 08:42:59 +0000 (10:42 +0200)
This is only relevant when Privoxy is built with wolfSSL 5.0.0 or later.

Earlier wolfSSL versions or the other TLS backends
don't seem to trigger the crash.

ssl_common.c

index 1881713..4cf7291 100644 (file)
@@ -358,11 +358,22 @@ extern void ssl_send_certificate_error(struct client_state *csp)
    cert = &(csp->server_certs_chain);
    while (cert->next != NULL)
    {
-      size_t base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1;
+      size_t base64_len;
 
-      message_len += strlen(cert->info_buf) + strlen("<pre></pre>\n")
-                     +  base64_len + strlen("<a href=\"data:application"
-                        "/x-x509-ca-cert;base64,\">Download certificate</a>");
+      if (cert->file_buf != NULL)
+      {
+         base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1;
+
+         message_len += strlen(cert->info_buf) + strlen("<pre></pre>\n")
+            +  base64_len + strlen("<a href=\"data:application"
+            "/x-x509-ca-cert;base64,\">Download certificate</a>");
+      }
+      else
+      {
+         log_error(LOG_LEVEL_ERROR,
+            "Incomplete certificate information for %s.",
+            csp->http->hostport);
+      }
       cert = cert->next;
    }
 
@@ -379,31 +390,36 @@ extern void ssl_send_certificate_error(struct client_state *csp)
    cert = &(csp->server_certs_chain);
    while (cert->next != NULL)
    {
-      size_t olen = 0;
-      size_t base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1; /* +1 for terminating null*/
-      char base64_buf[base64_len];
-      memset(base64_buf, 0, base64_len);
-
-      /* Encoding certificate into base64 code */
-      ret = ssl_base64_encode((unsigned char*)base64_buf,
-               base64_len, &olen, (const unsigned char*)cert->file_buf,
-               strlen(cert->file_buf));
-      if (ret != 0)
-      {
-         log_error(LOG_LEVEL_ERROR,
-            "Encoding to base64 failed, buffer is to small");
-      }
-
-      strlcat(message, "<pre>",        message_len);
-      strlcat(message, cert->info_buf, message_len);
-      strlcat(message, "</pre>\n",     message_len);
-
-      if (ret == 0)
+      if (cert->file_buf != NULL)
       {
-         strlcat(message, "<a href=\"data:application/x-x509-ca-cert;base64,",
-            message_len);
-         strlcat(message, base64_buf, message_len);
-         strlcat(message, "\">Download certificate</a>", message_len);
+                                                       /* +1 for terminating null */
+         size_t base64_len = base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1;
+         size_t olen = 0;
+         char base64_buf[base64_len];
+
+         memset(base64_buf, 0, base64_len);
+
+         /* Encoding certificate into base64 code */
+         ret = ssl_base64_encode((unsigned char*)base64_buf,
+                  base64_len, &olen, (const unsigned char*)cert->file_buf,
+                  strlen(cert->file_buf));
+         if (ret != 0)
+         {
+            log_error(LOG_LEVEL_ERROR,
+               "Encoding to base64 failed, buffer is to small");
+         }
+
+         strlcat(message, "<pre>",        message_len);
+         strlcat(message, cert->info_buf, message_len);
+         strlcat(message, "</pre>\n",     message_len);
+
+         if (ret == 0)
+         {
+            strlcat(message, "<a href=\"data:application/x-x509-ca-cert;base64,",
+               message_len);
+            strlcat(message, base64_buf, message_len);
+            strlcat(message, "\">Download certificate</a>", message_len);
+         }
       }
 
       cert = cert->next;