static int host_to_hash(struct client_state *csp);
static int ssl_verify_callback(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags);
static void free_certificate_chain(struct client_state *csp);
-static unsigned int get_certificate_mutex_id(struct client_state *csp);
static unsigned long get_certificate_serial(struct client_state *csp);
static void free_client_ssl_structures(struct client_state *csp);
static void free_server_ssl_structures(struct client_state *csp);
* Generating certificate for requested host. Mutex to prevent
* certificate and key inconsistence must be locked.
*/
- unsigned int cert_mutex_id = get_certificate_mutex_id(csp);
- privoxy_mutex_lock(&(certificates_mutexes[cert_mutex_id]));
+ privoxy_mutex_lock(&certificate_mutex);
ret = generate_webpage_certificate(csp);
if (ret < 0)
{
log_error(LOG_LEVEL_ERROR,
"Generate_webpage_certificate failed: %d", ret);
- privoxy_mutex_unlock(&(certificates_mutexes[cert_mutex_id]));
+ privoxy_mutex_unlock(&certificate_mutex);
ret = -1;
goto exit;
}
- privoxy_mutex_unlock(&(certificates_mutexes[cert_mutex_id]));
+ privoxy_mutex_unlock(&certificate_mutex);
/*
* Seed the RNG
/* Log the reason without the trailing new line */
log_error(LOG_LEVEL_ERROR,
- "The X509 certificate verification failed: %N",
- strlen(reason)-1, reason);
+ "X509 certificate verification for %s failed: %N",
+ csp->http->hostport, strlen(reason)-1, reason);
ret = -1;
}
else
}
+/*********************************************************************
+ *
+ * Function : ssl_certificate_is_invalid
+ *
+ * Description : Checks whether or not a certificate is valid.
+ * Currently only checks that the certificate can be
+ * parsed and that the "valid to" date is in the future.
+ *
+ * Parameters :
+ * 1 : cert_file = The certificate to check
+ *
+ * Returns : 0 => The certificate is valid.
+ * 1 => The certificate is invalid
+ *
+ *********************************************************************/
+static int ssl_certificate_is_invalid(const char *cert_file)
+{
+ mbedtls_x509_crt cert;
+ int ret;
+
+ mbedtls_x509_crt_init(&cert);
+
+ ret = mbedtls_x509_crt_parse_file(&cert, cert_file);
+ if (ret != 0)
+ {
+ char err_buf[ERROR_BUF_SIZE];
+
+ mbedtls_strerror(ret, err_buf, sizeof(err_buf));
+ log_error(LOG_LEVEL_ERROR,
+ "Loading certificate %s to check validity failed: %s",
+ cert_file, err_buf);
+ mbedtls_x509_crt_free(&cert);
+
+ return 1;
+ }
+ if (mbedtls_x509_time_is_past(&cert.valid_to))
+ {
+ mbedtls_x509_crt_free(&cert);
+
+ return 1;
+ }
+
+ mbedtls_x509_crt_free(&cert);
+
+ return 0;
+
+}
+
+
/*********************************************************************
*
* Function : generate_webpage_certificate
*/
if (file_exists(cert_opt.output_file) == 1 && subject_key_len == 0)
{
- ret = 0;
- goto exit;
+ /* The file exists, but is it valid */
+ if (ssl_certificate_is_invalid(cert_opt.output_file))
+ {
+ log_error(LOG_LEVEL_CONNECT,
+ "Certificate %s is no longer valid. Removing.",
+ cert_opt.output_file);
+ if (unlink(cert_opt.output_file))
+ {
+ log_error(LOG_LEVEL_ERROR, "Failed to unlink %s: %E",
+ cert_opt.output_file);
+ ret = -1;
+ goto exit;
+ }
+ }
+ else
+ {
+ ret = 0;
+ goto exit;
+ }
}
/*
}
-/*********************************************************************
- *
- * Function : get_certificate_mutex_id
- *
- * Description : Computes mutex id from host name hash. This hash must
- * be already saved in csp structure
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : Mutex id for given host name
- *
- *********************************************************************/
-static unsigned int get_certificate_mutex_id(struct client_state *csp) {
-#ifdef LIMIT_MUTEX_NUMBER
- return (unsigned int)(csp->http->hash_of_host[0] % 32);
-#else
- return (unsigned int)(csp->http->hash_of_host[1]
- + 256 * (int)csp->http->hash_of_host[0]);
-#endif /* LIMIT_MUTEX_NUMBER */
-}
-
-
/*********************************************************************
*
* Function : get_certificate_serial
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Connection: close\r\n\r\n"
- "<html><body><h1>Invalid server certificate</h1><p>Reason: ";
+ "<html><body><h1>Server certificate verification failed</h1><p>Reason: ";
const char message_end[] = "</body></html>\r\n\r\n";
char reason[INVALID_CERT_INFO_BUF_SIZE];
memset(reason, 0, sizeof(reason));
*/
ssl_send_data(&(csp->mbedtls_client_attr.ssl),
(const unsigned char *)message, strlen(message));
- /*
- * Waiting before closing connection. Some browsers don't show received
- * message if there isn't this delay.
- */
- sleep(1);
free_certificate_chain(csp);
}