diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index 68caaeb..5b8a809 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -65,6 +65,13 @@ static DH *get_dh1024() return dh; } +static bool q_enableECSetCurves() { + // The ability to select elliptic curves is + // present in OpenSSL 1.0.2+ but not in LibreSSL. + // RFC4492 Section 5.1.1 "Supported Elliptic Curves Extension" + return q_SSLeay() >= 0x10002000L && !q_LibreSSL(); +} + QSslContext::QSslContext() : ctx(0), pkey(0), @@ -340,9 +347,9 @@ init_context: const QVector qcurves = sslContext->sslConfiguration.ellipticCurves(); if (!qcurves.isEmpty()) { -#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC) +#if defined(SSL_CTRL_SET_CURVES) && !defined(OPENSSL_NO_EC) // Set the curves to be used - if (q_SSLeay() >= 0x10002000L) { + if (q_enableECSetCurves()) { // SSL_CTX_ctrl wants a non-const pointer as last argument, // but let's avoid a copy into a temporary array if (!q_SSL_CTX_ctrl(sslContext->ctx, @@ -354,10 +361,10 @@ init_context: return sslContext; } } else -#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC) +#endif // defined(SSL_CTRL_SET_CURVES) && !defined(OPENSSL_NO_EC) { // specific curves requested, but not possible to set -> error - sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("OpenSSL version too old, need at least v1.0.2")); + sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("This version of OpenSSL lacks support for selecting specific elliptic curves.")); sslContext->errorCode = QSslError::UnspecifiedError; return sslContext; } diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index e7829ba..7b164d0 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -1000,6 +1000,11 @@ bool q_resolveOpenSslSymbols() #endif return true; } + +bool q_LibreSSL() +{ + return strncmp(q_SSLeay_version(SSLEAY_VERSION), "LibreSSL", 8) == 0; +} #endif // !defined QT_LINKED_OPENSSL //============================================================================== diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index 7f87f11..5da6ad1 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -209,6 +209,7 @@ QT_BEGIN_NAMESPACE #endif // !defined QT_LINKED_OPENSSL bool q_resolveOpenSslSymbols(); +bool q_LibreSSL(); long q_ASN1_INTEGER_get(ASN1_INTEGER *a); unsigned char * q_ASN1_STRING_data(ASN1_STRING *a); int q_ASN1_STRING_length(ASN1_STRING *a);