openssl: bump minimum OpenSSL version to 3.0.0

It also means that all supported OpenSSL versions and forks support
TLSv1.3 after this patch.

It reduces `openssl.c` size by more than 10%, or 400 LOC.

Ref: #18822
Closes #18330
This commit is contained in:
Viktor Szakats
2025-08-27 00:54:22 +02:00
parent 2e1a045d89
commit 69c89bf3d3
10 changed files with 59 additions and 493 deletions

View File

@@ -329,10 +329,10 @@ jobs:
install_steps: intel
configure: CC=icc --enable-debug --with-openssl
- name: 'Slackware openssl gssapi gcc'
# These are essentially the same flags used to build the curl Slackware package
- name: 'Slackware !ssl gssapi gcc'
# Flags used to build the curl Slackware package, except OpenSSL 1.1.0:
# https://ftpmirror.infania.net/slackware/slackware64-current/source/n/curl/curl.SlackBuild
configure: --enable-debug --with-openssl --with-libssh2 --with-gssapi --enable-ares --enable-static=no --without-ca-bundle --with-ca-path=/etc/ssl/certs
configure: --enable-debug --without-ssl --with-libssh2 --with-gssapi --enable-ares --enable-static=no --without-ca-bundle --with-ca-path=/etc/ssl/certs
# Docker Hub image that `container-job` executes in
container: 'andy5995/slackware-build-essential:15.0'

View File

@@ -2152,8 +2152,7 @@ message(STATUS "Features: ${SUPPORT_FEATURES}")
# Clear list and collect SSL backends
set(_items "")
curl_add_if("Schannel" _ssl_enabled AND USE_SCHANNEL)
curl_add_if("${_openssl}" _ssl_enabled AND USE_OPENSSL AND OPENSSL_VERSION VERSION_LESS 3.0.0)
curl_add_if("${_openssl} v3+" _ssl_enabled AND USE_OPENSSL AND OPENSSL_VERSION VERSION_GREATER_EQUAL 3.0.0)
curl_add_if("${_openssl}" _ssl_enabled AND USE_OPENSSL)
curl_add_if("mbedTLS" _ssl_enabled AND USE_MBEDTLS)
curl_add_if("wolfSSL" _ssl_enabled AND USE_WOLFSSL)
curl_add_if("GnuTLS" _ssl_enabled AND USE_GNUTLS)

View File

@@ -35,12 +35,11 @@ esac
if [ "${APPVEYOR_BUILD_WORKER_IMAGE}" = 'Visual Studio 2022' ]; then
openssl_root_win="C:/OpenSSL-v35${openssl_suffix}"
openssl_root="$(cygpath "${openssl_root_win}")"
elif [ "${APPVEYOR_BUILD_WORKER_IMAGE}" = 'Visual Studio 2019' ]; then
openssl_root_win="C:/OpenSSL-v30${openssl_suffix}"
else
openssl_root_win="C:/OpenSSL-v111${openssl_suffix}"
openssl_root="$(cygpath "${openssl_root_win}")"
fi
openssl_root="$(cygpath "${openssl_root_win}")"
if [ "${BUILD_SYSTEM}" = 'CMake' ]; then
# Set env CHKPREFILL to the value '_chkprefill' to compare feature detection

View File

@@ -70,35 +70,34 @@ environment:
SCHANNEL: 'ON'
SHARED: 'ON'
EXAMPLES: 'ON'
- job_name: 'CM VS2012, Release, x86, OpenSSL 1.1.1 + Schannel, Shared, Build-tests'
- job_name: 'CM VS2012, Release, x86, Schannel, Shared, Build-tests'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2015'
PRJ_GEN: 'Visual Studio 11 2012'
TARGET: '-A Win32'
PRJ_CFG: Release
OPENSSL: 'ON'
SCHANNEL: 'ON'
SHARED: 'ON'
- job_name: 'CM VS2013, Debug, x64, OpenSSL 1.1.1, Shared, Build-only'
- job_name: 'CM VS2013, Debug, x64, Schannel, Shared, Build-only'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2015'
PRJ_GEN: 'Visual Studio 12 2013'
TARGET: '-A x64'
PRJ_CFG: Debug
OPENSSL: 'ON'
SCHANNEL: 'ON'
SHARED: 'ON'
TFLAGS: 'skipall'
- job_name: 'CM VS2015, Debug, x64, OpenSSL 1.1.1, Static, Build-only'
- job_name: 'CM VS2015, Debug, x64, Schannel, Static, Build-only'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2015'
PRJ_GEN: 'Visual Studio 14 2015'
TARGET: '-A x64'
PRJ_CFG: Debug
OPENSSL: 'ON'
SCHANNEL: 'ON'
TFLAGS: 'skipall'
- job_name: 'CM VS2017, Debug, x64, OpenSSL 1.1.1, Shared, Build-only'
- job_name: 'CM VS2017, Debug, x64, Schannel, Shared, Build-only'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2017'
PRJ_GEN: 'Visual Studio 15 2017'
TARGET: '-A x64'
PRJ_CFG: Debug
OPENSSL: 'ON'
SCHANNEL: 'ON'
SHARED: 'ON'
TFLAGS: 'skipall'
- job_name: 'CM VS2019, Debug, x64, OpenSSL 3.0 + Schannel, Shared, Build-tests'

View File

@@ -24,7 +24,7 @@ versions of libs and build tools.
We aim to support these or later versions.
- OpenSSL 1.0.2a
- OpenSSL 3.0.0
- LibreSSL 2.9.1
- GnuTLS 3.1.10
- mbedTLS 3.2.0

View File

@@ -40,10 +40,8 @@
#ifdef USE_OPENSSL
# include <openssl/opensslv.h>
# if (!defined(LIBRESSL_VERSION_NUMBER) && \
OPENSSL_VERSION_NUMBER >= 0x10101000L) || \
(defined(LIBRESSL_VERSION_NUMBER) && \
LIBRESSL_VERSION_NUMBER >= 0x3080000fL)
# if !defined(LIBRESSL_VERSION_NUMBER) || \
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3080000fL)
# include <openssl/opensslconf.h>
# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
# include <openssl/evp.h>

View File

@@ -37,7 +37,7 @@
#if defined(USE_OPENSSL) && \
!defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) && \
!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
!defined(LIBRESSL_VERSION_NUMBER)
#define PREVENT_OPENSSL_MEMLEAK
#endif

View File

@@ -108,8 +108,10 @@
# if LIBRESSL_VERSION_NUMBER < 0x2090100fL /* 2019-04-13 */
# error "LibreSSL 2.9.1 or later required"
# endif
#elif OPENSSL_VERSION_NUMBER < 0x1000201fL /* 2015-03-19 */
# error "OpenSSL 1.0.2a or later required"
#elif !defined(HAVE_BORINGSSL_LIKE)
# ifndef HAVE_OPENSSL3 /* 2021-09-07 */
# error "OpenSSL 3.0.0 or later required"
# endif
#endif
#if defined(HAVE_OPENSSL3) && !defined(OPENSSL_NO_UI_CONSOLE)
@@ -123,8 +125,7 @@ static void ossl_provider_cleanup(struct Curl_easy *data);
/* AWS-LC fixed a bug with large buffers in v1.61.0 which also introduced
* X509_V_ERR_EC_KEY_EXPLICIT_PARAMS. */
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
!defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL) && \
#if !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL) && \
(!defined(OPENSSL_IS_AWSLC) || defined(X509_V_ERR_EC_KEY_EXPLICIT_PARAMS))
#define HAVE_SSL_CTX_SET_DEFAULT_READ_BUFFER_LEN 1
#endif
@@ -137,31 +138,6 @@ static void ossl_provider_cleanup(struct Curl_easy *data);
#if defined(USE_OPENSSL_ENGINE) || defined(OPENSSL_HAS_PROVIDERS)
#include <openssl/ui.h>
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
#define OSSL_UI_METHOD_CAST(x) (x)
#else
#define OSSL_UI_METHOD_CAST(x) CURL_UNCONST(x)
#endif
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* OpenSSL 1.1.0+ and LibreSSL */
#define HAVE_X509_GET0_EXTENSIONS 1 /* added in 1.1.0 -pre1 */
#define HAVE_OPAQUE_EVP_PKEY 1 /* since 1.1.0 -pre3 */
#define HAVE_OPAQUE_RSA_DSA_DH 1 /* since 1.1.0 -pre5 */
#define HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED 1
#else
/* For OpenSSL before 1.1.0 */
#define ASN1_STRING_get0_data(x) ASN1_STRING_data(x)
#define X509_get0_notBefore(x) X509_get_notBefore(x)
#define X509_get0_notAfter(x) X509_get_notAfter(x)
#define OpenSSL_version_num() SSLeay()
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10002003L && \
OPENSSL_VERSION_NUMBER <= 0x10002FFFL && \
!defined(OPENSSL_NO_COMP)
#define HAVE_SSL_COMP_FREE_COMPRESSION_METHODS 1
#endif
#ifdef HAVE_OPENSSL3
@@ -182,8 +158,7 @@ static void ossl_provider_cleanup(struct Curl_easy *data);
* BoringSSL: no
* LibreSSL: supported since 3.4.1 (released 2021-10-14)
*/
#if ((OPENSSL_VERSION_NUMBER >= 0x10101000L && \
!defined(LIBRESSL_VERSION_NUMBER)) || \
#if (!defined(LIBRESSL_VERSION_NUMBER) || \
(defined(LIBRESSL_VERSION_NUMBER) && \
LIBRESSL_VERSION_NUMBER >= 0x3040100fL)) && \
!defined(OPENSSL_IS_BORINGSSL)
@@ -198,7 +173,7 @@ static void ossl_provider_cleanup(struct Curl_easy *data);
* BoringSSL: supported since 0.20240913.0 (commit 826ce15)
* LibreSSL: no
*/
#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
#ifndef LIBRESSL_VERSION_NUMBER
#define HAVE_SSL_CTX_SET1_SIGALGS
#endif
@@ -224,30 +199,6 @@ typedef unsigned long sslerr_t;
#endif
#define ossl_valsize_t numcert_t
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
/* up2date versions of OpenSSL maintain reasonably secure defaults without
* breaking compatibility, so it is better not to override the defaults in curl
*/
#define DEFAULT_CIPHER_SELECTION NULL
#else
/* not the case with old versions of OpenSSL */
#define DEFAULT_CIPHER_SELECTION \
"ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH"
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
#define HAVE_RANDOM_INIT_BY_DEFAULT 1
#endif
/*
* Whether the OpenSSL version has the API needed to support sharing an
* X509_STORE between connections. The API is:
* * `X509_STORE_up_ref` -- Introduced: OpenSSL 1.1.0.
*/
#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* OpenSSL >= 1.1.0 */
#define HAVE_SSL_X509_STORE_SHARE
#endif
static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl);
static CURLcode push_certinfo(struct Curl_easy *data,
@@ -280,27 +231,12 @@ static CURLcode pubkey_show(struct Curl_easy *data,
return push_certinfo(data, mem, namebuf, num);
}
#ifdef HAVE_OPAQUE_RSA_DSA_DH
#define print_pubkey_BN(_type, _name, _num) \
pubkey_show(data, mem, _num, #_type, #_name, _name)
#else
#define print_pubkey_BN(_type, _name, _num) \
do { \
if(_type->_name) { \
pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \
} \
} while(0)
#endif
static int asn1_object_dump(const ASN1_OBJECT *a, char *buf, size_t len)
{
int i;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
i = i2t_ASN1_OBJECT(buf, (int)len, a);
#else
i = i2t_ASN1_OBJECT(buf, (int)len, CURL_UNCONST(a));
#endif
int i = i2t_ASN1_OBJECT(buf, (int)len, a);
return (i >= (int)len); /* buffer too small */
}
@@ -310,10 +246,10 @@ static CURLcode X509V3_ext(struct Curl_easy *data,
{
int i;
CURLcode result = CURLE_OK;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
const STACK_OF(X509_EXTENSION) *exts = extsarg;
#else
#ifdef LIBRESSL_VERSION_NUMBER
STACK_OF(X509_EXTENSION) *exts = CURL_UNCONST(extsarg);
#else
const STACK_OF(X509_EXTENSION) *exts = extsarg;
#endif
if((int)sk_X509_EXTENSION_num(exts) <= 0)
@@ -409,7 +345,6 @@ static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl)
if(result)
break;
#ifdef HAVE_X509_GET0_EXTENSIONS
{
const X509_ALGOR *sigalg = NULL;
X509_PUBKEY *xpubkey = NULL;
@@ -440,28 +375,6 @@ static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl)
if(result)
break;
}
#else
{
/* before OpenSSL 1.0.2 */
X509_CINF *cinf = x->cert_info;
i2a_ASN1_OBJECT(mem, cinf->signature->algorithm);
result = push_certinfo(data, mem, "Signature Algorithm", i);
if(!result) {
i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm);
result = push_certinfo(data, mem, "Public Key Algorithm", i);
}
if(!result)
result = X509V3_ext(data, i, cinf->extensions);
if(result)
break;
psig = x->signature;
}
#endif
ASN1_TIME_print(mem, X509_get0_notBefore(x));
result = push_certinfo(data, mem, "Start date", i);
@@ -477,25 +390,14 @@ static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl)
if(!pubkey)
infof(data, " Unable to load public key");
else {
int pktype;
#ifdef HAVE_OPAQUE_EVP_PKEY
pktype = EVP_PKEY_id(pubkey);
#else
pktype = pubkey->type;
#endif
switch(pktype) {
switch(EVP_PKEY_id(pubkey)) {
case EVP_PKEY_RSA: {
#ifndef HAVE_EVP_PKEY_GET_PARAMS
RSA *rsa;
#ifdef HAVE_OPAQUE_EVP_PKEY
rsa = EVP_PKEY_get0_RSA(pubkey);
#else
rsa = pubkey->pkey.rsa;
#endif /* HAVE_OPAQUE_EVP_PKEY */
#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
{
#ifdef HAVE_OPAQUE_RSA_DSA_DH
DECLARE_PKEY_PARAM_BIGNUM(n);
DECLARE_PKEY_PARAM_BIGNUM(e);
#ifdef HAVE_EVP_PKEY_GET_PARAMS
@@ -505,9 +407,6 @@ static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl)
RSA_get0_key(rsa, &n, &e, NULL);
#endif /* HAVE_EVP_PKEY_GET_PARAMS */
BIO_printf(mem, "%d", n ? BN_num_bits(n) : 0);
#else
BIO_printf(mem, "%d", rsa->n ? BN_num_bits(rsa->n) : 0);
#endif /* HAVE_OPAQUE_RSA_DSA_DH */
result = push_certinfo(data, mem, "RSA Public Key", i);
if(result)
break;
@@ -523,15 +422,9 @@ static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl)
{
#ifndef OPENSSL_NO_DSA
#ifndef HAVE_EVP_PKEY_GET_PARAMS
DSA *dsa;
#ifdef HAVE_OPAQUE_EVP_PKEY
dsa = EVP_PKEY_get0_DSA(pubkey);
#else
dsa = pubkey->pkey.dsa;
#endif /* HAVE_OPAQUE_EVP_PKEY */
DSA *dsa = EVP_PKEY_get0_DSA(pubkey);
#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
{
#ifdef HAVE_OPAQUE_RSA_DSA_DH
DECLARE_PKEY_PARAM_BIGNUM(p);
DECLARE_PKEY_PARAM_BIGNUM(q);
DECLARE_PKEY_PARAM_BIGNUM(g);
@@ -545,7 +438,6 @@ static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl)
DSA_get0_pqg(dsa, &p, &q, &g);
DSA_get0_key(dsa, &pub_key, NULL);
#endif /* HAVE_EVP_PKEY_GET_PARAMS */
#endif /* HAVE_OPAQUE_RSA_DSA_DH */
print_pubkey_BN(dsa, p, i);
print_pubkey_BN(dsa, q, i);
print_pubkey_BN(dsa, g, i);
@@ -560,15 +452,9 @@ static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl)
}
case EVP_PKEY_DH: {
#ifndef HAVE_EVP_PKEY_GET_PARAMS
DH *dh;
#ifdef HAVE_OPAQUE_EVP_PKEY
dh = EVP_PKEY_get0_DH(pubkey);
#else
dh = pubkey->pkey.dh;
#endif /* HAVE_OPAQUE_EVP_PKEY */
DH *dh = EVP_PKEY_get0_DH(pubkey);
#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
{
#ifdef HAVE_OPAQUE_RSA_DSA_DH
DECLARE_PKEY_PARAM_BIGNUM(p);
DECLARE_PKEY_PARAM_BIGNUM(q);
DECLARE_PKEY_PARAM_BIGNUM(g);
@@ -585,10 +471,6 @@ static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl)
print_pubkey_BN(dh, p, i);
print_pubkey_BN(dh, q, i);
print_pubkey_BN(dh, g, i);
#else
print_pubkey_BN(dh, p, i);
print_pubkey_BN(dh, g, i);
#endif /* HAVE_OPAQUE_RSA_DSA_DH */
print_pubkey_BN(dh, pub_key, i);
FREE_PKEY_PARAM_BIGNUM(p);
FREE_PKEY_PARAM_BIGNUM(q);
@@ -626,21 +508,10 @@ static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl)
#ifdef USE_OPENSSL
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#define BIO_set_init(x,v) ((x)->init=(v))
#define BIO_get_data(x) ((x)->ptr)
#define BIO_set_data(x,v) ((x)->ptr=(v))
#define BIO_get_shutdown(x) ((x)->shutdown)
#define BIO_set_shutdown(x,v) ((x)->shutdown=(v))
#endif /* HAVE_PRE_1_1_API */
static int ossl_bio_cf_create(BIO *bio)
{
BIO_set_shutdown(bio, 1);
BIO_set_init(bio, 1);
#if OPENSSL_VERSION_NUMBER < 0x10100000L
bio->num = -1;
#endif
BIO_set_data(bio, NULL);
return 1;
}
@@ -759,30 +630,6 @@ static int ossl_bio_cf_in_read(BIO *bio, char *buf, int blen)
return result ? -1 : (int)nread;
}
#if OPENSSL_VERSION_NUMBER < 0x10100000L
static BIO_METHOD ossl_bio_cf_meth_1_0 = {
BIO_TYPE_MEM,
"OpenSSL CF BIO",
ossl_bio_cf_out_write,
ossl_bio_cf_in_read,
NULL, /* puts is never called */
NULL, /* gets is never called */
ossl_bio_cf_ctrl,
ossl_bio_cf_create,
ossl_bio_cf_destroy,
NULL
};
static BIO_METHOD *ossl_bio_cf_method_create(void)
{
return &ossl_bio_cf_meth_1_0;
}
#define ossl_bio_cf_method_free(m) Curl_nop_stmt
#else
static BIO_METHOD *ossl_bio_cf_method_create(void)
{
BIO_METHOD *m = BIO_meth_new(BIO_TYPE_MEM, "OpenSSL CF BIO");
@@ -802,9 +649,6 @@ static void ossl_bio_cf_method_free(BIO_METHOD *m)
BIO_meth_free(m);
}
#endif
#ifdef HAVE_KEYLOG_CALLBACK
static void ossl_keylog_callback(const SSL *ssl, const char *line)
{
@@ -834,19 +678,9 @@ ossl_log_tls12_secret(const SSL *ssl, bool *keylog_done)
return;
}
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
/* ssl->s3 is not checked in OpenSSL 1.1.0-pre6, but let's assume that
* we have a valid SSL context if we have a non-NULL session. */
SSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE);
master_key_length = (int)
SSL_SESSION_get_master_key(session, master_key, SSL_MAX_MASTER_KEY_LENGTH);
#else
if(ssl->s3 && session->master_key_length > 0) {
master_key_length = session->master_key_length;
memcpy(master_key, session->master_key, session->master_key_length);
memcpy(client_random, ssl->s3->client_random, SSL3_RANDOM_SIZE);
}
#endif
ERR_pop_to_mark();
@@ -968,58 +802,8 @@ static CURLcode ossl_seed(struct Curl_easy *data)
data->multi->ssl_seeded = TRUE;
return CURLE_OK;
}
#ifdef HAVE_RANDOM_INIT_BY_DEFAULT
/* with OpenSSL 1.1.0+, a failed RAND_status is a showstopper */
failf(data, "Insufficient randomness");
return CURLE_SSL_CONNECT_ERROR;
#else
/* fallback to a custom seeding of the PRNG using a hash based on a current
time */
do {
unsigned char randb[64];
size_t len = sizeof(randb);
size_t i, i_max;
for(i = 0, i_max = len / sizeof(struct curltime); i < i_max; ++i) {
struct curltime tv = curlx_now();
curlx_wait_ms(1);
tv.tv_sec *= (time_t)i + 1;
tv.tv_usec *= (int)i + 2;
tv.tv_sec ^= ((curlx_now().tv_sec + (time_t)curlx_now().tv_usec) *
(time_t)(i + 3)) << 8;
tv.tv_usec ^= (int) ((curlx_now().tv_sec + (time_t)curlx_now().tv_usec) *
(time_t)(i + 4)) << 16;
memcpy(&randb[i * sizeof(struct curltime)], &tv,
sizeof(struct curltime));
}
RAND_add(randb, (int)len, (double)len/2);
} while(!rand_enough());
/*
* Number of bytes to read from the random number seed file. This must be
* a finite value (because some entropy "files" like /dev/urandom have
* an infinite length), but must be large enough to provide enough
* entropy to properly seed OpenSSL's PRNG.
*/
# define RAND_LOAD_LENGTH 1024
{
/* generates a default path for the random seed file */
char fname[256];
fname[0] = 0; /* blank it first */
RAND_file_name(fname, sizeof(fname));
if(fname[0]) {
/* we got a filename to try */
RAND_load_file(fname, RAND_LOAD_LENGTH);
if(rand_enough())
return CURLE_OK;
}
}
infof(data, "libcurl is now using a weak random seed");
return rand_enough() ? CURLE_OK :
CURLE_SSL_CONNECT_ERROR; /* confusing error code */
#endif
}
#ifndef SSL_FILETYPE_ENGINE
@@ -1247,7 +1031,7 @@ static int enginecheck(struct Curl_easy *data,
if(data->state.engine) {
UI_METHOD *ui_method =
UI_create_method(OSSL_UI_METHOD_CAST("curl user interface"));
UI_create_method("curl user interface");
if(!ui_method) {
failf(data, "unable to create " OSSL_PACKAGE " user-interface method");
return 0;
@@ -1309,7 +1093,7 @@ static int providercheck(struct Curl_easy *data,
OSSL_STORE_CTX *store = NULL;
OSSL_STORE_INFO *info = NULL;
UI_METHOD *ui_method =
UI_create_method(OSSL_UI_METHOD_CAST("curl user interface"));
UI_create_method("curl user interface");
if(!ui_method) {
failf(data, "unable to create " OSSL_PACKAGE " user-interface method");
return 0;
@@ -1797,13 +1581,7 @@ static CURLcode client_cert(struct Curl_easy *data,
/* If RSA is used, do not check the private key if its flags indicate
* it does not support it. */
EVP_PKEY *priv_key = SSL_get_privatekey(ssl);
int pktype;
#ifdef HAVE_OPAQUE_EVP_PKEY
pktype = EVP_PKEY_id(priv_key);
#else
pktype = priv_key->type;
#endif
if(pktype == EVP_PKEY_RSA) {
if(EVP_PKEY_id(priv_key) == EVP_PKEY_RSA) {
RSA *rsa = EVP_PKEY_get1_RSA(priv_key);
if(RSA_flags(rsa) & RSA_METHOD_FLAG_NO_CHECK)
check_privkey = FALSE;
@@ -1861,7 +1639,6 @@ static CURLcode x509_name_oneline(X509_NAME *a, struct dynbuf *d)
*/
static int ossl_init(void)
{
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
const uint64_t flags =
#ifdef OPENSSL_INIT_ENGINE_ALL_BUILTIN
/* not present in BoringSSL */
@@ -1874,28 +1651,6 @@ static int ossl_init(void)
#endif
0;
OPENSSL_init_ssl(flags, NULL);
#else
OPENSSL_load_builtin_modules();
#ifdef USE_OPENSSL_ENGINE
ENGINE_load_builtin_engines();
#endif
#ifndef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG
CONF_modules_load_file(NULL, NULL,
CONF_MFLAGS_DEFAULT_SECTION|
CONF_MFLAGS_IGNORE_MISSING_FILE);
#endif
/* Let's get nice error messages */
SSL_load_error_strings();
/* Init the global ciphers and digests */
if(!SSLeay_add_ssl_algorithms())
return 0;
OpenSSL_add_all_algorithms();
#endif
Curl_tls_keylog_open();
@@ -1905,32 +1660,6 @@ static int ossl_init(void)
/* Global cleanup */
static void ossl_cleanup(void)
{
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
/* OpenSSL 1.1 deprecates all these cleanup functions and
turns them into no-ops in OpenSSL 1.0 compatibility mode */
#else
/* Free ciphers and digests lists */
EVP_cleanup();
#ifdef USE_OPENSSL_ENGINE
/* Free engine list */
ENGINE_cleanup();
#endif
/* Free OpenSSL error strings */
ERR_free_strings();
/* Free thread local error state, destroying hash upon zero refcount */
ERR_remove_thread_state(NULL);
/* Free all memory allocated by all configuration modules */
CONF_modules_free();
#ifdef HAVE_SSL_COMP_FREE_COMPRESSION_METHODS
SSL_COMP_free_compression_methods();
#endif
#endif
Curl_tls_keylog_close();
}
@@ -2284,13 +2013,6 @@ static void ossl_close_all(struct Curl_easy *data)
#ifdef OPENSSL_HAS_PROVIDERS
ossl_provider_cleanup(data);
#endif
#ifndef HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED
/* OpenSSL 1.0.1 and 1.0.2 build an error queue that is stored per-thread
so we need to clean it here in case the thread will be killed. All OpenSSL
code should extract the error in association with the error so clearing
this queue here should be harmless at worst. */
ERR_remove_thread_state(NULL);
#endif
}
/* ====================================================== */
@@ -2777,7 +2499,7 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
const void *buf, size_t len, SSL *ssl,
void *userp)
{
const char *verstr = "???";
const char *verstr;
struct Curl_cfilter *cf = userp;
struct Curl_easy *data = NULL;
char unknown[32];
@@ -2812,13 +2534,9 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
verstr = "TLSv1.2";
break;
#endif
#ifdef TLS1_3_VERSION /* OpenSSL 1.1.1+, all forks */
case TLS1_3_VERSION:
verstr = "TLSv1.3";
break;
#endif
case 0:
break;
default:
curl_msnprintf(unknown, sizeof(unknown), "(%x)", ssl_ver);
verstr = unknown;
@@ -2884,7 +2602,6 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
# define HAS_ALPN_OPENSSL
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */
static CURLcode
ossl_set_ssl_version_min_max(struct Curl_cfilter *cf, SSL_CTX *ctx,
unsigned int ssl_version_min)
@@ -2916,12 +2633,8 @@ ossl_set_ssl_version_min_max(struct Curl_cfilter *cf, SSL_CTX *ctx,
ossl_ssl_version_min = TLS1_2_VERSION;
break;
case CURL_SSLVERSION_TLSv1_3:
#ifdef TLS1_3_VERSION
ossl_ssl_version_min = TLS1_3_VERSION;
break;
#else
return CURLE_NOT_BUILT_IN;
#endif
}
/* ... then, TLS max version */
@@ -2938,11 +2651,9 @@ ossl_set_ssl_version_min_max(struct Curl_cfilter *cf, SSL_CTX *ctx,
case CURL_SSLVERSION_MAX_TLSv1_2:
ossl_ssl_version_max = TLS1_2_VERSION;
break;
#ifdef TLS1_3_VERSION
case CURL_SSLVERSION_MAX_TLSv1_3:
ossl_ssl_version_max = TLS1_3_VERSION;
break;
#endif
case CURL_SSLVERSION_MAX_NONE: /* none selected */
case CURL_SSLVERSION_MAX_DEFAULT: /* max selected */
default:
@@ -2959,80 +2670,15 @@ ossl_set_ssl_version_min_max(struct Curl_cfilter *cf, SSL_CTX *ctx,
return CURLE_OK;
}
#endif
#ifdef HAVE_BORINGSSL_LIKE
typedef uint32_t ctx_option_t;
#elif defined(HAVE_OPENSSL3)
typedef uint64_t ctx_option_t;
#elif OPENSSL_VERSION_NUMBER >= 0x10100000L && \
!defined(LIBRESSL_VERSION_NUMBER)
typedef unsigned long ctx_option_t;
#else
#elif defined(LIBRESSL_VERSION_NUMBER)
typedef long ctx_option_t;
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L /* 1.1.0 */
static CURLcode
ossl_set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
long ssl_version = conn_config->version;
long ssl_version_max = conn_config->version_max;
(void)data; /* In case it is unused. */
switch(ssl_version) {
case CURL_SSLVERSION_TLSv1_3:
#ifdef TLS1_3_VERSION
{
struct ssl_connect_data *connssl = cf->ctx;
struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
DEBUGASSERT(octx);
SSL_CTX_set_max_proto_version(octx->ssl_ctx, TLS1_3_VERSION);
*ctx_options |= SSL_OP_NO_TLSv1_2;
}
#else
(void)ctx_options;
failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
return CURLE_NOT_BUILT_IN;
#endif
FALLTHROUGH();
case CURL_SSLVERSION_TLSv1_2:
*ctx_options |= SSL_OP_NO_TLSv1_1;
FALLTHROUGH();
case CURL_SSLVERSION_TLSv1_1:
*ctx_options |= SSL_OP_NO_TLSv1;
FALLTHROUGH();
case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1:
break;
}
switch(ssl_version_max) {
case CURL_SSLVERSION_MAX_TLSv1_0:
*ctx_options |= SSL_OP_NO_TLSv1_1;
FALLTHROUGH();
case CURL_SSLVERSION_MAX_TLSv1_1:
*ctx_options |= SSL_OP_NO_TLSv1_2;
FALLTHROUGH();
case CURL_SSLVERSION_MAX_TLSv1_2:
#ifdef TLS1_3_VERSION
*ctx_options |= SSL_OP_NO_TLSv1_3;
#endif
break;
case CURL_SSLVERSION_MAX_TLSv1_3:
#ifdef TLS1_3_VERSION
break;
#else
failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
return CURLE_NOT_BUILT_IN;
#endif
}
return CURLE_OK;
}
typedef unsigned long ctx_option_t;
#endif
CURLcode Curl_ossl_add_session(struct Curl_cfilter *cf,
@@ -3538,8 +3184,6 @@ static CURLcode ossl_populate_x509_store(struct Curl_cfilter *cf,
return result;
}
#ifdef HAVE_SSL_X509_STORE_SHARE
/* key to use at `multi->proto_hash` */
#define MPROTO_OSSL_X509_KEY "tls:ossl:x509:share"
@@ -3706,25 +3350,6 @@ CURLcode Curl_ssl_setup_x509_store(struct Curl_cfilter *cf,
return result;
}
#else /* HAVE_SSL_X509_STORE_SHARE */
CURLcode Curl_ssl_setup_x509_store(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct ossl_ctx *octx)
{
CURLcode result;
X509_STORE *store;
ERR_set_mark();
store = SSL_CTX_get_cert_store(octx->ssl_ctx);
result = ossl_populate_x509_store(cf, data, octx, store);
ERR_pop_to_mark();
return result;
}
#endif /* HAVE_SSL_X509_STORE_SHARE */
static CURLcode
ossl_init_session_and_alpns(struct ossl_ctx *octx,
@@ -4020,11 +3645,7 @@ static CURLcode ossl_init_method(struct Curl_cfilter *cf,
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
/* it will be handled later with the context options */
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
*pmethod = TLS_client_method();
#else
*pmethod = SSLv23_client_method();
#endif
break;
case CURL_SSLVERSION_SSLv2:
failf(data, "No SSLv2 support");
@@ -4048,10 +3669,8 @@ static CURLcode ossl_init_method(struct Curl_cfilter *cf,
#ifdef USE_OPENSSL_QUIC
*pmethod = OSSL_QUIC_client_method();
#elif (OPENSSL_VERSION_NUMBER >= 0x10100000L)
*pmethod = TLS_method();
#else
*pmethod = SSLv23_client_method();
*pmethod = TLS_method();
#endif
break;
default:
@@ -4187,11 +3806,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
ctx_options |= SSL_OP_NO_SSLv2;
ctx_options |= SSL_OP_NO_SSLv3;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */
result = ossl_set_ssl_version_min_max(cf, octx->ssl_ctx, ssl_version_min);
#else
result = ossl_set_ssl_version_min_max_legacy(&ctx_options, cf, data);
#endif
if(result)
return result;
break;
@@ -4222,7 +3837,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
ciphers = conn_config->cipher_list;
if(!ciphers && (peer->transport != TRNSPRT_QUIC))
ciphers = DEFAULT_CIPHER_SELECTION;
ciphers = NULL;
if(ciphers && (ssl_version_min < CURL_SSLVERSION_TLSv1_3)) {
if(!SSL_CTX_set_cipher_list(octx->ssl_ctx, ciphers)) {
failf(data, "failed setting cipher list: %s", ciphers);
@@ -4829,9 +4444,8 @@ static CURLcode ossl_pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert,
return result;
}
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
!(defined(LIBRESSL_VERSION_NUMBER) && \
LIBRESSL_VERSION_NUMBER < 0x3060000fL) && \
#if !(defined(LIBRESSL_VERSION_NUMBER) && \
LIBRESSL_VERSION_NUMBER < 0x3060000fL) && \
!defined(HAVE_BORINGSSL_LIKE) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
static void infof_certstack(struct Curl_easy *data, const SSL *ssl)
{
@@ -5650,8 +5264,6 @@ out:
static CURLcode ossl_get_channel_binding(struct Curl_easy *data, int sockindex,
struct dynbuf *binding)
{
/* required for X509_get_signature_nid support */
#if OPENSSL_VERSION_NUMBER > 0x10100000L
X509 *cert;
int algo_nid;
const EVP_MD *algo_type;
@@ -5726,13 +5338,6 @@ static CURLcode ossl_get_channel_binding(struct Curl_easy *data, int sockindex,
error:
X509_free(cert);
return result;
#else
/* No X509_get_signature_nid support */
(void)data;
(void)sockindex;
(void)binding;
return CURLE_OK;
#endif
}
size_t Curl_ossl_version(char *buffer, size_t size)
@@ -5761,41 +5366,9 @@ size_t Curl_ossl_version(char *buffer, size_t size)
#elif defined(OPENSSL_IS_AWSLC)
return curl_msnprintf(buffer, size, "%s/%s",
OSSL_PACKAGE, AWSLC_VERSION_NUMBER_STRING);
#elif defined(OPENSSL_VERSION_STRING) /* OpenSSL 3+ */
#else /* OpenSSL 3+ */
return curl_msnprintf(buffer, size, "%s/%s",
OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING));
#else
/* not LibreSSL, BoringSSL and not using OpenSSL_version */
char sub[3];
unsigned long ssleay_value;
sub[2]='\0';
sub[1]='\0';
ssleay_value = OpenSSL_version_num();
if(ssleay_value&0xff0) {
int minor_ver = (ssleay_value >> 4) & 0xff;
if(minor_ver > 26) {
/* handle extended version introduced for 0.9.8za */
sub[1] = (char) ((minor_ver - 1) % 26 + 'a' + 1);
sub[0] = 'z';
}
else {
sub[0] = (char) (minor_ver + 'a' - 1);
}
}
else
sub[0]='\0';
return curl_msnprintf(buffer, size, "%s/%lx.%lx.%lx%s"
#ifdef OPENSSL_FIPS
"-fips"
#endif
,
OSSL_PACKAGE,
(ssleay_value >> 28) & 0xf,
(ssleay_value >> 20) & 0xff,
(ssleay_value >> 12) & 0xff,
sub);
#endif
}

View File

@@ -51,8 +51,7 @@
* BoringSSL: supported since d28f59c27bac (committed 2015-11-19)
* LibreSSL: not supported. 3.5.0+ has a stub function that does nothing.
*/
#if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \
!defined(LIBRESSL_VERSION_NUMBER)) || defined(HAVE_BORINGSSL_LIKE)
#if !defined(LIBRESSL_VERSION_NUMBER) || defined(HAVE_BORINGSSL_LIKE)
#define HAVE_KEYLOG_CALLBACK
#endif

View File

@@ -282,23 +282,22 @@ if test "x$OPT_OPENSSL" != xno; then
AC_MSG_RESULT([no])
])
AC_MSG_CHECKING([for OpenSSL >= v3])
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
#include <openssl/opensslv.h>
]],[[
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
return 0;
#else
#error older than 3
#endif
]])
],[
AC_MSG_RESULT([yes])
ssl_msg="OpenSSL v3+"
],[
AC_MSG_RESULT([no])
])
if test "$ssl_msg" = 'OpenSSL'; then
AC_MSG_CHECKING([for OpenSSL >= v3])
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
#include <openssl/opensslv.h>
]],[[
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
return 0;
#else
#error older than 3
#endif
]])
],[],[
AC_MSG_ERROR([OpenSSL 3.0.0 or upper required.])
])
fi
fi
dnl is this OpenSSL (fork) providing the original QUIC API?