aboutsummaryrefslogtreecommitdiff
blob: e1faac926feb4352ccf578f5ae16395ac6574d45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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<QSslEllipticCurve> 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);