X-Git-Url: http://www.privoxy.org/gitweb/misc.html?a=blobdiff_plain;f=openssl.c;h=39f465310a07ba4e0cfadf167cccdc22bcdcb0d8;hb=8fbaec9db37a4b73ae23727e60ddac591d2fc911;hp=8a9824ae0231e563e09b68af50056e4aae42e212;hpb=9f34addb5262b6f00b21129955fc327f158f05cf;p=privoxy.git
diff --git a/openssl.c b/openssl.c
index 8a9824ae..39f46531 100644
--- a/openssl.c
+++ b/openssl.c
@@ -8,7 +8,7 @@
*
* Copyright : Written by and Copyright (c) 2020 Maxim Antonov
* Copyright (C) 2017 Vaclav Svec. FIT CVUT.
- * Copyright (C) 2018-2020 by Fabian Keil
+ * Copyright (C) 2018-2022 by Fabian Keil
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
@@ -38,6 +38,13 @@
#include
#include
#include
+#ifdef _WIN32
+/* https://www.openssl.org/docs/faq.html
+ Iâve compiled a program under Windows and it crashes: Why?
+ tl,dr: because it needs this include:
+*/
+#include
+#endif /* _WIN32 */
#include "config.h"
#include "project.h"
@@ -302,7 +309,7 @@ static int ssl_store_cert(struct client_state *csp, X509 *crt)
last->next = malloc_or_die(sizeof(struct certs_chain));
last->next->next = NULL;
memset(last->next->info_buf, 0, sizeof(last->next->info_buf));
- memset(last->next->file_buf, 0, sizeof(last->next->file_buf));
+ last->next->file_buf = NULL;
/*
* Saving certificate file into buffer
@@ -316,15 +323,18 @@ static int ssl_store_cert(struct client_state *csp, X509 *crt)
len = BIO_get_mem_data(bio, &bio_mem_data);
- if (len > (sizeof(last->file_buf) - 1))
+ last->file_buf = malloc((size_t)len + 1);
+ if (last->file_buf == NULL)
{
log_error(LOG_LEVEL_ERROR,
- "X509 PEM cert len %ld is larger than buffer len %lu",
- len, sizeof(last->file_buf) - 1);
- len = sizeof(last->file_buf) - 1;
+ "Failed to allocate %lu bytes to store the X509 PEM certificate",
+ len + 1);
+ ret = -1;
+ goto exit;
}
strncpy(last->file_buf, bio_mem_data, (size_t)len);
+ last->file_buf[len] = '\0';
BIO_free(bio);
bio = BIO_new(BIO_s_mem());
if (!bio)
@@ -787,17 +797,16 @@ extern int create_client_ssl_connection(struct client_state *csp)
* certificate and key inconsistence must be locked.
*/
privoxy_mutex_lock(&certificate_mutex);
-
ret = generate_host_certificate(csp);
+ privoxy_mutex_unlock(&certificate_mutex);
+
if (ret < 0)
{
log_error(LOG_LEVEL_ERROR,
- "generate_host_certificate failed: %d", ret);
- privoxy_mutex_unlock(&certificate_mutex);
+ "generate_host_certificate() failed: %d", ret);
ret = -1;
goto exit;
}
- privoxy_mutex_unlock(&certificate_mutex);
if (!(ssl_attr->openssl_attr.ctx = SSL_CTX_new(SSLv23_server_method())))
{
@@ -1152,6 +1161,11 @@ extern int create_server_ssl_connection(struct client_state *csp)
goto exit;
}
+ /*
+ * XXX: Do we really have to do this always?
+ * Probably it's sufficient to do if the verification fails
+ * in which case we're sending the certificates to the client.
+ */
chain = SSL_get_peer_cert_chain(ssl);
if (chain)
{
@@ -1751,6 +1765,8 @@ static int generate_host_certificate(struct client_state *csp)
cert_options cert_opt;
char cert_valid_from[VALID_DATETIME_BUFLEN];
char cert_valid_to[VALID_DATETIME_BUFLEN];
+ const char *common_name;
+ enum { CERT_PARAM_COMMON_NAME_MAX = 64 };
/* Paths to keys and certificates needed to create certificate */
cert_opt.issuer_key = NULL;
@@ -1861,13 +1877,20 @@ static int generate_host_certificate(struct client_state *csp)
subject_name = X509_NAME_new();
if (!subject_name)
{
- log_ssl_errors(LOG_LEVEL_ERROR, "RSA key memory allocation failure");
+ log_ssl_errors(LOG_LEVEL_ERROR, "X509 memory allocation failure");
ret = -1;
goto exit;
}
+ /*
+ * Make sure OpenSSL doesn't reject the common name due to its length.
+ * The clients should only care about the Subject Alternative Name anyway
+ * and we always use the real host name for that.
+ */
+ common_name = (strlen(csp->http->host) > CERT_PARAM_COMMON_NAME_MAX) ?
+ CGI_SITE_2_HOST : csp->http->host;
if (!X509_NAME_add_entry_by_txt(subject_name, CERT_PARAM_COMMON_NAME_FCODE,
- MBSTRING_ASC, (void *)csp->http->host, -1, -1, 0))
+ MBSTRING_ASC, (void *)common_name, -1, -1, 0))
{
log_ssl_errors(LOG_LEVEL_ERROR,
"X509 subject name (code: %s, val: %s) error",
@@ -1876,7 +1899,7 @@ static int generate_host_certificate(struct client_state *csp)
goto exit;
}
if (!X509_NAME_add_entry_by_txt(subject_name, CERT_PARAM_ORGANIZATION_FCODE,
- MBSTRING_ASC, (void *)csp->http->host, -1, -1, 0))
+ MBSTRING_ASC, (void *)common_name, -1, -1, 0))
{
log_ssl_errors(LOG_LEVEL_ERROR,
"X509 subject name (code: %s, val: %s) error",
@@ -1885,7 +1908,7 @@ static int generate_host_certificate(struct client_state *csp)
goto exit;
}
if (!X509_NAME_add_entry_by_txt(subject_name, CERT_PARAM_ORG_UNIT_FCODE,
- MBSTRING_ASC, (void *)csp->http->host, -1, -1, 0))
+ MBSTRING_ASC, (void *)common_name, -1, -1, 0))
{
log_ssl_errors(LOG_LEVEL_ERROR,
"X509 subject name (code: %s, val: %s) error",
@@ -1898,7 +1921,7 @@ static int generate_host_certificate(struct client_state *csp)
{
log_ssl_errors(LOG_LEVEL_ERROR,
"X509 subject name (code: %s, val: %s) error",
- CERT_PARAM_COUNTRY_FCODE, csp->http->host);
+ CERT_PARAM_COUNTRY_FCODE, CERT_PARAM_COUNTRY_CODE);
ret = -1;
goto exit;
}
@@ -1969,7 +1992,7 @@ static int generate_host_certificate(struct client_state *csp)
goto exit;
}
- issuer_name = X509_get_issuer_name(issuer_cert);
+ issuer_name = X509_get_subject_name(issuer_cert);
/*
* Loading keys from file or from buffer