View | Details | Raw Unified | Return to bug 217220 | Differences between
and this patch

Collapse All | Expand All

(-)files/patch-libressl (+163 lines)
Line 0 Link Here
1
diff -Naur qtbase-opensource-src-5.7.1.orig/src/network/ssl/qsslcontext_openssl.cpp qtbase-opensource-src-5.7.1/src/network/ssl/qsslcontext_openssl.cpp
2
--- src/network/ssl/qsslcontext_openssl.cpp	2017-02-05 11:52:45.100394264 -0800
3
+++ src/network/ssl/qsslcontext_openssl.cpp	2017-02-05 11:57:21.159178021 -0800
4
@@ -71,6 +71,15 @@
5
     return dh;
6
 }
7
 
8
+static bool q_enableECSetCurves() {
9
+        // The ability to select elliptic curves is
10
+        // present in OpenSSL 1.0.2+ and in LibreSSL 2.5.1+
11
+        // RFC4492 Section 5.1.1 "Supported Elliptic Curves Extension"
12
+        return (q_SSLeay() >= 0x10002000L && !q_LibreSSL()) || 
13
+               q_LibreSSL_version() >= 0x2050100fL;
14
+}
15
+
16
+
17
 QSslContext::QSslContext()
18
     : ctx(0),
19
     pkey(0),
20
@@ -347,23 +356,20 @@
21
 
22
     const QVector<QSslEllipticCurve> qcurves = sslContext->sslConfiguration.ellipticCurves();
23
     if (!qcurves.isEmpty()) {
24
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC)
25
+#if defined(SSL_CTRL_SET_CURVES) && !defined(OPENSSL_NO_EC)
26
         // Set the curves to be used
27
-        if (q_SSLeay() >= 0x10002000L) {
28
-            // SSL_CTX_ctrl wants a non-const pointer as last argument,
29
-            // but let's avoid a copy into a temporary array
30
-            if (!q_SSL_CTX_ctrl(sslContext->ctx,
31
-                                SSL_CTRL_SET_CURVES,
32
-                                qcurves.size(),
33
-                                const_cast<int *>(reinterpret_cast<const int *>(qcurves.data())))) {
34
+        if (q_enableECSetCurves()) {
35
+            if (!q_SSL_CTX_set1_groups(sslContext->ctx,
36
+                                       reinterpret_cast<const int *>(qcurves.data()),
37
+                                       qcurves.size())) {
38
                 sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
39
                 sslContext->errorCode = QSslError::UnspecifiedError;
40
             }
41
         } else
42
-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC)
43
+#endif // defined(SSL_CTRL_SET_CURVES) && !defined(OPENSSL_NO_EC)
44
         {
45
             // specific curves requested, but not possible to set -> error
46
-            sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("OpenSSL version too old, need at least v1.0.2"));
47
+            sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("This version of OpenSSL lacks support for selecting specific elliptic curves."));
48
             sslContext->errorCode = QSslError::UnspecifiedError;
49
         }
50
     }
51
diff -Naur qtbase-opensource-src-5.7.1.orig/src/network/ssl/qsslsocket_openssl.cpp qtbase-opensource-src-5.7.1/src/network/ssl/qsslsocket_openssl.cpp
52
--- src/network/ssl/qsslsocket_openssl.cpp	2017-02-05 11:52:45.098394244 -0800
53
+++ src/network/ssl/qsslsocket_openssl.cpp	2017-02-05 11:52:58.870533121 -0800
54
@@ -98,6 +98,14 @@
55
 int QSslSocketBackendPrivate::s_indexForSSLExtraData = -1;
56
 #endif
57
 
58
+static bool q_enableGetServerTmpKey() {
59
+        // The ability to get the ephemeral server key is
60
+        // present in OpenSSL 1.0.2+ and in LibreSSL 2.5.1+
61
+        // RFC4492 Section 5.4 "Server Key Exchange"
62
+        return (q_SSLeay() >= 0x10002000L && !q_LibreSSL()) || 
63
+               q_LibreSSL_version() >= 0x2050100fL;
64
+}
65
+
66
 /* \internal
67
 
68
     From OpenSSL's thread(3) manual page:
69
@@ -1587,13 +1595,13 @@
70
     }
71
 #endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
72
 
73
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L
74
-    if (q_SSLeay() >= 0x10002000L && mode == QSslSocket::SslClientMode) {
75
+#if defined(SSL_CTRL_GET_SERVER_TMP_KEY)
76
+    if (q_enableGetServerTmpKey() && mode == QSslSocket::SslClientMode) {
77
         EVP_PKEY *key;
78
         if (q_SSL_get_server_tmp_key(ssl, &key))
79
             configuration.ephemeralServerKey = QSslKey(key, QSsl::PublicKey);
80
     }
81
-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...
82
+#endif // defined(SSL_CTRL_GET_SERVER_TMP_KEY)
83
 
84
     connectionEncrypted = true;
85
     emit q->encrypted();
86
diff -Naur qtbase-opensource-src-5.7.1.orig/src/network/ssl/qsslsocket_openssl_symbols.cpp qtbase-opensource-src-5.7.1/src/network/ssl/qsslsocket_openssl_symbols.cpp
87
--- src/network/ssl/qsslsocket_openssl_symbols.cpp	2017-02-05 11:52:45.102394284 -0800
88
+++ network/ssl/qsslsocket_openssl_symbols.cpp	2017-02-05 11:56:53.848902627 -0800
89
@@ -247,6 +247,7 @@
90
 DEFINEFUNC(int, SSL_connect, SSL *a, a, return -1, return)
91
 DEFINEFUNC(int, SSL_CTX_check_private_key, const SSL_CTX *a, a, return -1, return)
92
 DEFINEFUNC4(long, SSL_CTX_ctrl, SSL_CTX *a, a, int b, b, long c, c, void *d, d, return -1, return)
93
+DEFINEFUNC3(int, SSL_CTX_set1_groups, SSL_CTX *a, a, const int* b, b, size_t c, c, return 0, return)
94
 DEFINEFUNC(void, SSL_CTX_free, SSL_CTX *a, a, return, DUMMYARG)
95
 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
96
 DEFINEFUNC(SSL_CTX *, SSL_CTX_new, const SSL_METHOD *a, a, return 0, return)
97
@@ -846,6 +847,7 @@
98
     RESOLVEFUNC(SSL_CIPHER_get_bits)
99
     RESOLVEFUNC(SSL_CTX_check_private_key)
100
     RESOLVEFUNC(SSL_CTX_ctrl)
101
+    RESOLVEFUNC(SSL_CTX_set1_groups)
102
     RESOLVEFUNC(SSL_CTX_free)
103
     RESOLVEFUNC(SSL_CTX_new)
104
     RESOLVEFUNC(SSL_CTX_set_cipher_list)
105
@@ -1006,6 +1008,20 @@
106
 #endif
107
     return true;
108
 }
109
+
110
+bool q_LibreSSL()
111
+{
112
+    return strncmp(q_SSLeay_version(SSLEAY_VERSION), "LibreSSL", 8) == 0;
113
+}
114
+
115
+long q_LibreSSL_version()
116
+{
117
+#ifdef LIBRESSL_VERSION_NUMBER
118
+    return LIBRESSL_VERSION_NUMBER;
119
+#else
120
+    return 0L;
121
+#endif
122
+}
123
 #endif // !defined QT_LINKED_OPENSSL
124
 
125
 //==============================================================================
126
diff -Naur qtbase-opensource-src-5.7.1.orig/src/network/ssl/qsslsocket_openssl_symbols_p.h qtbase-opensource-src-5.7.1/src/network/ssl/qsslsocket_openssl_symbols_p.h
127
--- src/network/ssl/qsslsocket_openssl_symbols_p.h	2017-02-05 11:52:45.100394264 -0800
128
+++ src/network/ssl/qsslsocket_openssl_symbols_p.h	2017-02-05 11:52:58.871533131 -0800
129
@@ -215,6 +215,8 @@
130
 #endif // !defined QT_LINKED_OPENSSL
131
 
132
 bool q_resolveOpenSslSymbols();
133
+bool q_LibreSSL();
134
+long q_LibreSSL_version();
135
 long q_ASN1_INTEGER_get(ASN1_INTEGER *a);
136
 unsigned char * q_ASN1_STRING_data(ASN1_STRING *a);
137
 int q_ASN1_STRING_length(ASN1_STRING *a);
138
@@ -327,6 +329,7 @@
139
 int q_SSL_connect(SSL *a);
140
 int q_SSL_CTX_check_private_key(const SSL_CTX *a);
141
 long q_SSL_CTX_ctrl(SSL_CTX *a, int b, long c, void *d);
142
+int q_SSL_CTX_set1_groups(SSL_CTX *a, const int* b, size_t c);
143
 void q_SSL_CTX_free(SSL_CTX *a);
144
 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
145
 SSL_CTX *q_SSL_CTX_new(const SSL_METHOD *a);
146
@@ -489,9 +492,9 @@
147
 int q_EC_curve_nist2nid(const char *name);
148
 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
149
 #endif // OPENSSL_NO_EC
150
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L
151
+#if defined(SSL_CTRL_GET_SERVER_TMP_KEY)
152
 #define q_SSL_get_server_tmp_key(ssl, key) q_SSL_ctrl((ssl), SSL_CTRL_GET_SERVER_TMP_KEY, 0, (char *)key)
153
-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
154
+#endif // defined(SSL_CTRL_GET_SERVER_TMP_KEY)
155
 
156
 // PKCS#12 support
157
 int q_PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca);
158
159
    Contact GitHub API Training Shop Blog About 
160
161
162
::
163
(-)files/patch-src_network_ssl_qsslcontext__openssl.cpp (-43 lines)
Lines 1-43 Link Here
1
* Instead of using the SSL_CTRL_SET_CURVES macros which only exists in OpenSSL,
2
* call the SSL_CTX_set1_curves functions as suggested by BoringSSL porting docs
3
* and which is the function in OpenSSL that is called through the replaced macro.
4
* LibreSSL has a SSL_CTX_set1_groups functions and provides a compat macro.
5
* Unfortunately, since Qt resolves the symbols at runtime, we cannot call through
6
* that macro and must instead explicitly call SSL_CTX_set1_groups if the library
7
* doesn't export a function called SSL_CTX_set1_curves, as in the case of LibreSSL.
8
*
9
--- src/network/ssl/qsslcontext_openssl.cpp.orig	2016-12-01 08:17:04 UTC
10
+++ src/network/ssl/qsslcontext_openssl.cpp
11
@@ -350,14 +350,24 @@ init_context:
12
 #if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC)
13
         // Set the curves to be used
14
         if (q_SSLeay() >= 0x10002000L) {
15
-            // SSL_CTX_ctrl wants a non-const pointer as last argument,
16
-            // but let's avoid a copy into a temporary array
17
-            if (!q_SSL_CTX_ctrl(sslContext->ctx,
18
-                                SSL_CTRL_SET_CURVES,
19
-                                qcurves.size(),
20
-                                const_cast<int *>(reinterpret_cast<const int *>(qcurves.data())))) {
21
-                sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
22
-                sslContext->errorCode = QSslError::UnspecifiedError;
23
+            switch (q_SSL_CTX_set1_curves(sslContext->ctx,
24
+                                          const_cast<int *>(reinterpret_cast<const int *>(qcurves.data())),
25
+                                          qcurves.size())) {
26
+                case 1:
27
+                default:
28
+                    break;
29
+                case 0:
30
+                    sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
31
+                    sslContext->errorCode = QSslError::UnspecifiedError;
32
+                    break;
33
+                case -1:
34
+                    if (q_SSL_CTX_set1_groups(sslContext->ctx,
35
+                                              reinterpret_cast<const int *>(qcurves.data()),
36
+                                              qcurves.size()) < 1) {
37
+                        sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
38
+                        sslContext->errorCode = QSslError::UnspecifiedError;
39
+                    }
40
+                    break;
41
             }
42
         } else
43
 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC)
(-)files/patch-src_network_ssl_qsslsocket__openssl__symbols.cpp (-51 lines)
Lines 1-51 Link Here
1
* Boilerplate for SSL_CTX_set1_curves/groups() used in qsslcontext_openssl.cpp
2
*
3
* Prepend the path of the SSL libraries used for building so the same libraries are
4
* found and loaded at runtime. Normal search finds base SSL libraries before ports.
5
*
6
--- src/network/ssl/qsslsocket_openssl_symbols.cpp.orig	2016-09-16 05:49:42 UTC
7
+++ src/network/ssl/qsslsocket_openssl_symbols.cpp
8
@@ -424,6 +424,8 @@ DEFINEFUNC(void, EC_KEY_free, EC_KEY *ec
9
 DEFINEFUNC2(size_t, EC_get_builtin_curves, EC_builtin_curve * r, r, size_t nitems, nitems, return 0, return)
10
 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
11
 DEFINEFUNC(int, EC_curve_nist2nid, const char *name, name, return 0, return)
12
+DEFINEFUNC3(int, SSL_CTX_set1_curves, SSL_CTX *a, a, int *b, b, int c, c, return -1, return)
13
+DEFINEFUNC3(int, SSL_CTX_set1_groups, SSL_CTX *a, a, const int *b, b, size_t c, c, return -1, return)
14
 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
15
 #endif // OPENSSL_NO_EC
16
 
17
@@ -652,8 +654,8 @@ static QPair<QLibrary*, QLibrary*> loadO
18
 #endif
19
 #if defined(SHLIB_VERSION_NUMBER) && !defined(Q_OS_QNX) // on QNX, the libs are always libssl.so and libcrypto.so
20
     // first attempt: the canonical name is libssl.so.<SHLIB_VERSION_NUMBER>
21
-    libssl->setFileNameAndVersion(QLatin1String("ssl"), QLatin1String(SHLIB_VERSION_NUMBER));
22
-    libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String(SHLIB_VERSION_NUMBER));
23
+    libssl->setFileNameAndVersion(QLatin1String("%%OPENSSLLIB%%/libssl"), QLatin1String(SHLIB_VERSION_NUMBER));
24
+    libcrypto->setFileNameAndVersion(QLatin1String("%%OPENSSLLIB%%/libcrypto"), QLatin1String(SHLIB_VERSION_NUMBER));
25
     if (libcrypto->load() && libssl->load()) {
26
         // libssl.so.<SHLIB_VERSION_NUMBER> and libcrypto.so.<SHLIB_VERSION_NUMBER> found
27
         return pair;
28
@@ -670,8 +672,8 @@ static QPair<QLibrary*, QLibrary*> loadO
29
     //  OS X's /usr/lib/libssl.dylib, /usr/lib/libcrypto.dylib will be picked up in the third
30
     //    attempt, _after_ <bundle>/Contents/Frameworks has been searched.
31
     //  iOS does not ship a system libssl.dylib, libcrypto.dylib in the first place.
32
-    libssl->setFileNameAndVersion(QLatin1String("ssl"), -1);
33
-    libcrypto->setFileNameAndVersion(QLatin1String("crypto"), -1);
34
+    libssl->setFileNameAndVersion(QLatin1String("%%OPENSSLLIB%%/libssl"), -1);
35
+    libcrypto->setFileNameAndVersion(QLatin1String("%%OPENSSLLIB%%/libcrypto"), -1);
36
     if (libcrypto->load() && libssl->load()) {
37
         // libssl.so.0 and libcrypto.so.0 found
38
         return pair;
39
@@ -976,8 +978,11 @@ bool q_resolveOpenSslSymbols()
40
     RESOLVEFUNC(EC_KEY_free)
41
     RESOLVEFUNC(EC_get_builtin_curves)
42
 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
43
-    if (q_SSLeay() >= 0x10002000L)
44
+    if (q_SSLeay() >= 0x10002000L) {
45
         RESOLVEFUNC(EC_curve_nist2nid)
46
+        RESOLVEFUNC(SSL_CTX_set1_curves)
47
+        RESOLVEFUNC(SSL_CTX_set1_groups)
48
+	}
49
 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
50
 #endif // OPENSSL_NO_EC
51
     RESOLVEFUNC(PKCS12_parse)
(-)files/patch-src_network_ssl_qsslsocket__openssl__symbols__p.h (-13 lines)
Lines 1-13 Link Here
1
* Boilerplate for SSL_CTX_set1_curves/groups() used in qsslcontext_openssl.cpp
2
*
3
--- src/network/ssl/qsslsocket_openssl_symbols_p.h.orig	2016-09-16 05:49:42 UTC
4
+++ src/network/ssl/qsslsocket_openssl_symbols_p.h
5
@@ -481,6 +481,8 @@ void q_EC_KEY_free(EC_KEY *ecdh);
6
 size_t q_EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
7
 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
8
 int q_EC_curve_nist2nid(const char *name);
9
+int q_SSL_CTX_set1_curves(SSL_CTX *a, int *b, int c);
10
+int q_SSL_CTX_set1_groups(SSL_CTX *a, const int *b, size_t c);
11
 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
12
 #endif // OPENSSL_NO_EC
13
 

Return to bug 217220