1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the QtNetwork module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
43 #include "qsslsocket_openssl_symbols_p.h"
46 # include <private/qsystemlibrary_p.h>
48 # include <QtCore/qlibrary.h>
50 #include <QtCore/qmutex.h>
51 #include <private/qmutexpool_p.h>
52 #include <QtCore/qdatetime.h>
53 #if defined(Q_OS_UNIX)
54 #include <QtCore/qdir.h>
68 We load OpenSSL symbols dynamically. Because symbols are known to
69 disappear, and signatures sometimes change, between releases, we need to
70 be careful about how this is done. To ensure we don't end up dereferencing
71 null function pointers, and continue running even if certain functions are
72 missing, we define helper functions for each of the symbols we load from
73 OpenSSL, all prefixed with "q_" (declared in
74 qsslsocket_openssl_symbols_p.h). So instead of calling SSL_connect
75 directly, we call q_SSL_connect, which is a function that checks if the
76 actual SSL_connect fptr is null, and returns a failure if it is, or calls
77 SSL_connect if it isn't.
79 This requires a somewhat tedious process of declaring each function we
80 want to call in OpenSSL thrice: once with the q_, in _p.h, once using the
81 DEFINEFUNC macros below, and once in the function that actually resolves
82 the symbols, below the DEFINEFUNC declarations below.
84 There's one DEFINEFUNC macro declared for every number of arguments
85 exposed by OpenSSL (feel free to extend when needed). The easiest thing to
86 do is to find an existing entry that matches the arg count of the function
87 you want to import, and do the same.
89 The first macro arg is the function return type. The second is the
90 verbatim name of the function/symbol. Then follows a list of N pairs of
91 argument types with a variable name, and just the variable name (char *a,
92 a, char *b, b, etc). Finally there's two arguments - a suitable return
93 statement for the error case (for an int function, return 0 or return -1
94 is usually right). Then either just "return" or DUMMYARG, the latter being
97 Note: Take into account that these macros and declarations are processed
98 at compile-time, and the result depends on the OpenSSL headers the
99 compiling host has installed, but the symbols are resolved at run-time,
100 possibly with a different version of OpenSSL.
104 DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, return 0, return)
106 DEFINEFUNC(long, ASN1_INTEGER_get, ASN1_INTEGER *a, a, return 0, return)
107 DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return 0, return)
108 DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return)
109 DEFINEFUNC2(int, ASN1_STRING_to_UTF8, unsigned char **a, a, ASN1_STRING *b, b, return 0, return);
110 DEFINEFUNC4(long, BIO_ctrl, BIO *a, a, int b, b, long c, c, void *d, d, return -1, return)
111 DEFINEFUNC(int, BIO_free, BIO *a, a, return 0, return)
112 DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return 0, return)
113 DEFINEFUNC2(BIO *, BIO_new_mem_buf, void *a, a, int b, b, return 0, return)
114 DEFINEFUNC3(int, BIO_read, BIO *a, a, void *b, b, int c, c, return -1, return)
115 DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return)
116 DEFINEFUNC3(int, BIO_write, BIO *a, a, const void *b, b, int c, c, return -1, return)
117 DEFINEFUNC(int, BN_num_bits, const BIGNUM *a, a, return 0, return)
118 DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return)
119 DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG)
120 DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG)
121 DEFINEFUNC(void, CRYPTO_free, void *a, a, return, DUMMYARG)
122 DEFINEFUNC(void, DSA_free, DSA *a, a, return, DUMMYARG)
123 #if OPENSSL_VERSION_NUMBER < 0x00908000L
124 DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, unsigned char **b, b, long c, c, return 0, return)
125 #else // 0.9.8 broke SC and BC by changing this signature.
126 DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, const unsigned char **b, b, long c, c, return 0, return)
128 DEFINEFUNC2(char *, ERR_error_string, unsigned long a, a, char *b, b, return 0, return)
129 DEFINEFUNC(unsigned long, ERR_get_error, DUMMYARG, DUMMYARG, return 0, return)
130 DEFINEFUNC(void, ERR_free_strings, void, DUMMYARG, return, DUMMYARG)
131 DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return 0, return)
132 DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return)
133 DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return)
134 DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return)
135 DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG)
136 DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return 0, return)
137 DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return 0, return)
138 DEFINEFUNC(EVP_PKEY *, EVP_PKEY_new, DUMMYARG, DUMMYARG, return 0, return)
139 DEFINEFUNC(int, EVP_PKEY_type, int a, a, return NID_undef, return)
140 DEFINEFUNC2(int, i2d_X509, X509 *a, a, unsigned char **b, b, return -1, return)
141 DEFINEFUNC(const char *, OBJ_nid2sn, int a, a, return 0, return)
142 DEFINEFUNC(const char *, OBJ_nid2ln, int a, a, return 0, return)
143 DEFINEFUNC3(int, i2t_ASN1_OBJECT, char *a, a, int b, b, ASN1_OBJECT *c, c, return -1, return)
144 DEFINEFUNC4(int, OBJ_obj2txt, char *a, a, int b, b, ASN1_OBJECT *c, c, int d, d, return -1, return)
146 DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return)
148 DEFINEFUNC6(void *, PEM_ASN1_read_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
149 DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
151 DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
152 DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
153 DEFINEFUNC7(int, PEM_write_bio_DSAPrivateKey, BIO *a, a, DSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
154 DEFINEFUNC7(int, PEM_write_bio_RSAPrivateKey, BIO *a, a, RSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
156 DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
157 DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
158 DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, return)
159 DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return)
160 DEFINEFUNC2(void, RAND_seed, const void *a, a, int b, b, return, DUMMYARG)
161 DEFINEFUNC(int, RAND_status, void, DUMMYARG, return -1, return)
162 DEFINEFUNC(void, RSA_free, RSA *a, a, return, DUMMYARG)
163 DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return)
164 DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
165 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
166 DEFINEFUNC(_STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
167 DEFINEFUNC2(void, sk_push, _STACK *a, a, void *b, b, return, DUMMYARG)
168 DEFINEFUNC(void, sk_free, _STACK *a, a, return, DUMMYARG)
169 DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return 0, return)
171 DEFINEFUNC(STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
172 DEFINEFUNC2(void, sk_push, STACK *a, a, void *b, b, return, DUMMYARG)
173 DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG)
174 DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return 0, return)
176 DEFINEFUNC(int, SSL_accept, SSL *a, a, return -1, return)
177 DEFINEFUNC(int, SSL_clear, SSL *a, a, return -1, return)
178 DEFINEFUNC3(char *, SSL_CIPHER_description, SSL_CIPHER *a, a, char *b, b, int c, c, return 0, return)
179 DEFINEFUNC(int, SSL_connect, SSL *a, a, return -1, return)
180 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
181 // 0.9.8 broke SC and BC by changing this function's signature.
182 DEFINEFUNC(int, SSL_CTX_check_private_key, const SSL_CTX *a, a, return -1, return)
184 DEFINEFUNC(int, SSL_CTX_check_private_key, SSL_CTX *a, a, return -1, return)
186 DEFINEFUNC4(long, SSL_CTX_ctrl, SSL_CTX *a, a, int b, b, long c, c, void *d, d, return -1, return)
187 DEFINEFUNC(void, SSL_CTX_free, SSL_CTX *a, a, return, DUMMYARG)
188 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
189 DEFINEFUNC(SSL_CTX *, SSL_CTX_new, const SSL_METHOD *a, a, return 0, return)
191 DEFINEFUNC(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a, a, return 0, return)
193 DEFINEFUNC2(int, SSL_CTX_set_cipher_list, SSL_CTX *a, a, const char *b, b, return -1, return)
194 DEFINEFUNC(int, SSL_CTX_set_default_verify_paths, SSL_CTX *a, a, return -1, return)
195 DEFINEFUNC3(void, SSL_CTX_set_verify, SSL_CTX *a, a, int b, b, int (*c)(int, X509_STORE_CTX *), c, return, DUMMYARG)
196 DEFINEFUNC2(void, SSL_CTX_set_verify_depth, SSL_CTX *a, a, int b, b, return, DUMMYARG)
197 DEFINEFUNC2(int, SSL_CTX_use_certificate, SSL_CTX *a, a, X509 *b, b, return -1, return)
198 DEFINEFUNC3(int, SSL_CTX_use_certificate_file, SSL_CTX *a, a, const char *b, b, int c, c, return -1, return)
199 DEFINEFUNC2(int, SSL_CTX_use_PrivateKey, SSL_CTX *a, a, EVP_PKEY *b, b, return -1, return)
200 DEFINEFUNC2(int, SSL_CTX_use_RSAPrivateKey, SSL_CTX *a, a, RSA *b, b, return -1, return)
201 DEFINEFUNC3(int, SSL_CTX_use_PrivateKey_file, SSL_CTX *a, a, const char *b, b, int c, c, return -1, return)
202 DEFINEFUNC(void, SSL_free, SSL *a, a, return, DUMMYARG)
203 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
204 // 0.9.8 broke SC and BC by changing this function's signature.
205 DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, const SSL *a, a, return 0, return)
207 DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, SSL *a, a, return 0, return)
209 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
210 DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
212 DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
214 DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
215 DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return 0, return)
216 DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return 0, return)
217 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
218 // 0.9.8 broke SC and BC by changing this function's signature.
219 DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
221 DEFINEFUNC(long, SSL_get_verify_result, SSL *a, a, return -1, return)
223 DEFINEFUNC(int, SSL_library_init, void, DUMMYARG, return -1, return)
224 DEFINEFUNC(void, SSL_load_error_strings, void, DUMMYARG, return, DUMMYARG)
225 DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return 0, return)
226 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
227 DEFINEFUNC4(long, SSL_ctrl, SSL *a, a, int cmd, cmd, long larg, larg, void *parg, parg, return -1, return)
229 DEFINEFUNC3(int, SSL_read, SSL *a, a, void *b, b, int c, c, return -1, return)
230 DEFINEFUNC3(void, SSL_set_bio, SSL *a, a, BIO *b, b, BIO *c, c, return, DUMMYARG)
231 DEFINEFUNC(void, SSL_set_accept_state, SSL *a, a, return, DUMMYARG)
232 DEFINEFUNC(void, SSL_set_connect_state, SSL *a, a, return, DUMMYARG)
233 DEFINEFUNC(int, SSL_shutdown, SSL *a, a, return -1, return)
234 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
235 #ifndef OPENSSL_NO_SSL2
236 DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
238 DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
239 DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
240 DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
241 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
242 DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return 0, return)
243 DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return 0, return)
245 #ifndef OPENSSL_NO_SSL2
246 DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
248 DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
249 DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
250 DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
251 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
252 DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return 0, return)
253 DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return 0, return)
256 DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
257 DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
258 DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
259 DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
260 DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
261 DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
262 DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
263 DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
265 DEFINEFUNC3(int, SSL_write, SSL *a, a, const void *b, b, int c, c, return -1, return)
266 DEFINEFUNC2(int, X509_cmp, X509 *a, a, X509 *b, b, return -1, return)
267 #ifndef SSLEAY_MACROS
268 DEFINEFUNC(X509 *, X509_dup, X509 *a, a, return 0, return)
270 DEFINEFUNC2(void, X509_print, BIO *a, a, X509 *b, b, return, DUMMYARG);
271 DEFINEFUNC(ASN1_OBJECT *, X509_EXTENSION_get_object, X509_EXTENSION *a, a, return 0, return)
272 DEFINEFUNC(void, X509_free, X509 *a, a, return, DUMMYARG)
273 DEFINEFUNC2(X509_EXTENSION *, X509_get_ext, X509 *a, a, int b, b, return 0, return)
274 DEFINEFUNC(int, X509_get_ext_count, X509 *a, a, return 0, return)
275 DEFINEFUNC4(void *, X509_get_ext_d2i, X509 *a, a, int b, b, int *c, c, int *d, d, return 0, return)
276 DEFINEFUNC(const X509V3_EXT_METHOD *, X509V3_EXT_get, X509_EXTENSION *a, a, return 0, return)
277 DEFINEFUNC(void *, X509V3_EXT_d2i, X509_EXTENSION *a, a, return 0, return)
278 DEFINEFUNC(int, X509_EXTENSION_get_critical, X509_EXTENSION *a, a, return 0, return)
279 DEFINEFUNC(ASN1_OCTET_STRING *, X509_EXTENSION_get_data, X509_EXTENSION *a, a, return 0, return)
280 DEFINEFUNC(void, BASIC_CONSTRAINTS_free, BASIC_CONSTRAINTS *a, a, return, DUMMYARG)
281 DEFINEFUNC(void, AUTHORITY_KEYID_free, AUTHORITY_KEYID *a, a, return, DUMMYARG)
282 DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, const ASN1_STRING *b, b, return 0, return)
283 DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return 0, return)
284 DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return 0, return)
285 DEFINEFUNC(int, X509_verify_cert, X509_STORE_CTX *a, a, return -1, return)
286 DEFINEFUNC(int, X509_NAME_entry_count, X509_NAME *a, a, return 0, return)
287 DEFINEFUNC2(X509_NAME_ENTRY *, X509_NAME_get_entry, X509_NAME *a, a, int b, b, return 0, return)
288 DEFINEFUNC(ASN1_STRING *, X509_NAME_ENTRY_get_data, X509_NAME_ENTRY *a, a, return 0, return)
289 DEFINEFUNC(ASN1_OBJECT *, X509_NAME_ENTRY_get_object, X509_NAME_ENTRY *a, a, return 0, return)
290 DEFINEFUNC(EVP_PKEY *, X509_PUBKEY_get, X509_PUBKEY *a, a, return 0, return)
291 DEFINEFUNC(void, X509_STORE_free, X509_STORE *a, a, return, DUMMYARG)
292 DEFINEFUNC(X509_STORE *, X509_STORE_new, DUMMYARG, DUMMYARG, return 0, return)
293 DEFINEFUNC2(int, X509_STORE_add_cert, X509_STORE *a, a, X509 *b, b, return 0, return)
294 DEFINEFUNC(void, X509_STORE_CTX_free, X509_STORE_CTX *a, a, return, DUMMYARG)
295 DEFINEFUNC4(int, X509_STORE_CTX_init, X509_STORE_CTX *a, a, X509_STORE *b, b, X509 *c, c, STACK_OF(X509) *d, d, return -1, return)
296 DEFINEFUNC2(int, X509_STORE_CTX_set_purpose, X509_STORE_CTX *a, a, int b, b, return -1, return)
297 DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return 0, return)
299 DEFINEFUNC2(int, i2d_DSAPrivateKey, const DSA *a, a, unsigned char **b, b, return -1, return)
300 DEFINEFUNC2(int, i2d_RSAPrivateKey, const RSA *a, a, unsigned char **b, b, return -1, return)
301 DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return 0, return)
302 DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return 0, return)
304 DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG)
305 DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG)
306 DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return)
307 DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
308 DEFINEFUNC(const char *, SSLeay_version, int a, a, return 0, return)
310 #define RESOLVEFUNC(func) \
311 if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \
312 && !(_q_##func = _q_PTR_##func(libs.second->resolve(#func)))) \
313 qWarning("QSslSocket: cannot resolve "#func);
315 #if !defined QT_LINKED_OPENSSL
318 bool q_resolveOpenSslSymbols()
320 qWarning("QSslSocket: unable to resolve symbols. "
321 "QT_NO_LIBRARY is defined which means runtime resolving of "
322 "libraries won't work.");
323 qWarning("Either compile Qt statically or with support for runtime resolving "
330 static bool libGreaterThan(const QString &lhs, const QString &rhs)
332 QStringList lhsparts = lhs.split(QLatin1Char('.'));
333 QStringList rhsparts = rhs.split(QLatin1Char('.'));
334 Q_ASSERT(lhsparts.count() > 1 && rhsparts.count() > 1);
336 for (int i = 1; i < rhsparts.count(); ++i) {
337 if (lhsparts.count() <= i)
338 // left hand side is shorter, so it's less than rhs
343 int a = lhsparts.at(i).toInt(&ok);
345 b = rhsparts.at(i).toInt(&ok);
347 // both toInt succeeded
352 // compare as strings;
353 if (lhsparts.at(i) == rhsparts.at(i))
355 return lhsparts.at(i) > rhsparts.at(i);
359 // they compared strictly equally so far
360 // lhs cannot be less than rhs
365 static int dlIterateCallback(struct dl_phdr_info *info, size_t size, void *data)
367 if (size < sizeof (info->dlpi_addr) + sizeof (info->dlpi_name))
369 QSet<QString> *paths = (QSet<QString> *)data;
370 QString path = QString::fromLocal8Bit(info->dlpi_name);
371 if (!path.isEmpty()) {
373 path = fi.absolutePath();
381 static QStringList libraryPathList()
385 paths = QString::fromLatin1(qgetenv("DYLD_LIBRARY_PATH"))
386 .split(QLatin1Char(':'), QString::SkipEmptyParts);
388 paths = QString::fromLatin1(qgetenv("LD_LIBRARY_PATH"))
389 .split(QLatin1Char(':'), QString::SkipEmptyParts);
391 paths << QLatin1String("/lib") << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib");
392 paths << QLatin1String("/lib64") << QLatin1String("/usr/lib64") << QLatin1String("/usr/local/lib64");
393 paths << QLatin1String("/lib32") << QLatin1String("/usr/lib32") << QLatin1String("/usr/local/lib32");
396 // discover paths of already loaded libraries
397 QSet<QString> loadedPaths;
398 dl_iterate_phdr(dlIterateCallback, &loadedPaths);
399 paths.append(loadedPaths.toList());
406 static QStringList findAllLibSsl()
408 QStringList paths = libraryPathList();
409 QStringList foundSsls;
411 foreach (const QString &path, paths) {
413 QStringList entryList = dir.entryList(QStringList() << QLatin1String("libssl.*"), QDir::Files);
415 std::sort(entryList.begin(), entryList.end(), libGreaterThan);
416 foreach (const QString &entry, entryList)
417 foundSsls << path + QLatin1Char('/') + entry;
423 static QStringList findAllLibCrypto()
425 QStringList paths = libraryPathList();
427 QStringList foundCryptos;
428 foreach (const QString &path, paths) {
430 QStringList entryList = dir.entryList(QStringList() << QLatin1String("libcrypto.*"), QDir::Files);
432 std::sort(entryList.begin(), entryList.end(), libGreaterThan);
433 foreach (const QString &entry, entryList)
434 foundCryptos << path + QLatin1Char('/') + entry;
442 static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
444 QPair<QSystemLibrary*,QSystemLibrary*> pair;
448 QSystemLibrary *ssleay32 = new QSystemLibrary(QLatin1String("ssleay32"));
449 if (!ssleay32->load(false)) {
450 // Cannot find ssleay32.dll
455 QSystemLibrary *libeay32 = new QSystemLibrary(QLatin1String("libeay32"));
456 if (!libeay32->load(false)) {
462 pair.first = ssleay32;
463 pair.second = libeay32;
468 static QPair<QLibrary*, QLibrary*> loadOpenSsl()
470 QPair<QLibrary*,QLibrary*> pair;
474 # if defined(Q_OS_UNIX)
475 QLibrary *&libssl = pair.first;
476 QLibrary *&libcrypto = pair.second;
477 libssl = new QLibrary;
478 libcrypto = new QLibrary;
480 // Try to find the libssl library on the system.
482 // Up until Qt 4.3, this only searched for the "ssl" library at version -1, that
483 // is, libssl.so on most Unix systems. However, the .so file isn't present in
484 // user installations because it's considered a development file.
486 // The right thing to do is to load the library at the major version we know how
487 // to work with: the SHLIB_VERSION_NUMBER version (macro defined in opensslv.h)
489 // However, OpenSSL is a well-known case of binary-compatibility breakage. To
490 // avoid such problems, many system integrators and Linux distributions change
491 // the soname of the binary, letting the full version number be the soname. So
492 // we'll find libssl.so.0.9.7, libssl.so.0.9.8, etc. in the system. For that
493 // reason, we will search a few common paths (see findAllLibSsl() above) in hopes
494 // we find one that works.
496 // It is important, however, to try the canonical name and the unversioned name
497 // without going through the loop. By not specifying a path, we let the system
498 // dlopen(3) function determine it for us. This will include any DT_RUNPATH or
499 // DT_RPATH tags on our library header as well as other system-specific search
500 // paths. See the man page for dlopen(3) on your system for more information.
503 libcrypto->setLoadHints(QLibrary::ExportExternalSymbolsHint);
505 #ifdef SHLIB_VERSION_NUMBER
506 // first attempt: the canonical name is libssl.so.<SHLIB_VERSION_NUMBER>
507 libssl->setFileNameAndVersion(QLatin1String("ssl"), QLatin1String(SHLIB_VERSION_NUMBER));
508 libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String(SHLIB_VERSION_NUMBER));
509 if (libcrypto->load() && libssl->load()) {
510 // libssl.so.<SHLIB_VERSION_NUMBER> and libcrypto.so.<SHLIB_VERSION_NUMBER> found
518 // second attempt: find the development files libssl.so and libcrypto.so
519 libssl->setFileNameAndVersion(QLatin1String("ssl"), -1);
520 libcrypto->setFileNameAndVersion(QLatin1String("crypto"), -1);
521 if (libcrypto->load() && libssl->load()) {
522 // libssl.so.0 and libcrypto.so.0 found
529 // third attempt: loop on the most common library paths and find libssl
530 QStringList sslList = findAllLibSsl();
531 QStringList cryptoList = findAllLibCrypto();
533 foreach (const QString &crypto, cryptoList) {
534 libcrypto->setFileNameAndVersion(crypto, -1);
535 if (libcrypto->load()) {
536 QFileInfo fi(crypto);
537 QString version = fi.completeSuffix();
539 foreach (const QString &ssl, sslList) {
540 if (!ssl.endsWith(version))
543 libssl->setFileNameAndVersion(ssl, -1);
545 if (libssl->load()) {
546 // libssl.so.x and libcrypto.so.x found
556 // failed to load anything
559 libssl = libcrypto = 0;
563 // not implemented for this platform yet
569 bool q_resolveOpenSslSymbols()
571 static bool symbolsResolved = false;
572 static bool triedToResolveSymbols = false;
574 QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_SSL_library_init));
578 if (triedToResolveSymbols)
580 triedToResolveSymbols = true;
583 QPair<QSystemLibrary *, QSystemLibrary *> libs = loadOpenSslWin32();
585 QPair<QLibrary *, QLibrary *> libs = loadOpenSsl();
587 if (!libs.first || !libs.second)
588 // failed to load them
592 RESOLVEFUNC(ASN1_dup)
594 RESOLVEFUNC(ASN1_INTEGER_get)
595 RESOLVEFUNC(ASN1_STRING_data)
596 RESOLVEFUNC(ASN1_STRING_length)
597 RESOLVEFUNC(ASN1_STRING_to_UTF8)
598 RESOLVEFUNC(BIO_ctrl)
599 RESOLVEFUNC(BIO_free)
601 RESOLVEFUNC(BIO_new_mem_buf)
602 RESOLVEFUNC(BIO_read)
603 RESOLVEFUNC(BIO_s_mem)
604 RESOLVEFUNC(BIO_write)
605 RESOLVEFUNC(BN_num_bits)
606 RESOLVEFUNC(CRYPTO_free)
607 RESOLVEFUNC(CRYPTO_num_locks)
608 RESOLVEFUNC(CRYPTO_set_id_callback)
609 RESOLVEFUNC(CRYPTO_set_locking_callback)
610 RESOLVEFUNC(DSA_free)
611 RESOLVEFUNC(ERR_error_string)
612 RESOLVEFUNC(ERR_get_error)
613 RESOLVEFUNC(ERR_free_strings)
614 RESOLVEFUNC(EVP_des_ede3_cbc)
615 RESOLVEFUNC(EVP_PKEY_assign)
616 RESOLVEFUNC(EVP_PKEY_set1_RSA)
617 RESOLVEFUNC(EVP_PKEY_set1_DSA)
618 RESOLVEFUNC(EVP_PKEY_free)
619 RESOLVEFUNC(EVP_PKEY_get1_DSA)
620 RESOLVEFUNC(EVP_PKEY_get1_RSA)
621 RESOLVEFUNC(EVP_PKEY_new)
622 RESOLVEFUNC(EVP_PKEY_type)
623 RESOLVEFUNC(OBJ_nid2sn)
624 RESOLVEFUNC(OBJ_nid2ln)
625 RESOLVEFUNC(i2t_ASN1_OBJECT)
626 RESOLVEFUNC(OBJ_obj2txt)
627 RESOLVEFUNC(OBJ_obj2nid)
628 #ifdef SSLEAY_MACROS // ### verify
629 RESOLVEFUNC(PEM_ASN1_read_bio)
631 RESOLVEFUNC(PEM_read_bio_DSAPrivateKey)
632 RESOLVEFUNC(PEM_read_bio_RSAPrivateKey)
633 RESOLVEFUNC(PEM_write_bio_DSAPrivateKey)
634 RESOLVEFUNC(PEM_write_bio_RSAPrivateKey)
636 RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY)
637 RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY)
638 RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY)
639 RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY)
640 RESOLVEFUNC(RAND_seed)
641 RESOLVEFUNC(RAND_status)
642 RESOLVEFUNC(RSA_free)
643 RESOLVEFUNC(sk_new_null)
647 RESOLVEFUNC(sk_pop_free)
648 RESOLVEFUNC(sk_value)
649 RESOLVEFUNC(SSL_CIPHER_description)
650 RESOLVEFUNC(SSL_CTX_check_private_key)
651 RESOLVEFUNC(SSL_CTX_ctrl)
652 RESOLVEFUNC(SSL_CTX_free)
653 RESOLVEFUNC(SSL_CTX_new)
654 RESOLVEFUNC(SSL_CTX_set_cipher_list)
655 RESOLVEFUNC(SSL_CTX_set_default_verify_paths)
656 RESOLVEFUNC(SSL_CTX_set_verify)
657 RESOLVEFUNC(SSL_CTX_set_verify_depth)
658 RESOLVEFUNC(SSL_CTX_use_certificate)
659 RESOLVEFUNC(SSL_CTX_use_certificate_file)
660 RESOLVEFUNC(SSL_CTX_use_PrivateKey)
661 RESOLVEFUNC(SSL_CTX_use_RSAPrivateKey)
662 RESOLVEFUNC(SSL_CTX_use_PrivateKey_file)
663 RESOLVEFUNC(SSL_accept)
664 RESOLVEFUNC(SSL_clear)
665 RESOLVEFUNC(SSL_connect)
666 RESOLVEFUNC(SSL_free)
667 RESOLVEFUNC(SSL_get_ciphers)
668 RESOLVEFUNC(SSL_get_current_cipher)
669 RESOLVEFUNC(SSL_get_error)
670 RESOLVEFUNC(SSL_get_peer_cert_chain)
671 RESOLVEFUNC(SSL_get_peer_certificate)
672 RESOLVEFUNC(SSL_get_verify_result)
673 RESOLVEFUNC(SSL_library_init)
674 RESOLVEFUNC(SSL_load_error_strings)
676 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
677 RESOLVEFUNC(SSL_ctrl)
679 RESOLVEFUNC(SSL_read)
680 RESOLVEFUNC(SSL_set_accept_state)
681 RESOLVEFUNC(SSL_set_bio)
682 RESOLVEFUNC(SSL_set_connect_state)
683 RESOLVEFUNC(SSL_shutdown)
684 RESOLVEFUNC(SSL_write)
685 #ifndef OPENSSL_NO_SSL2
686 RESOLVEFUNC(SSLv2_client_method)
688 RESOLVEFUNC(SSLv3_client_method)
689 RESOLVEFUNC(SSLv23_client_method)
690 RESOLVEFUNC(TLSv1_client_method)
691 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
692 RESOLVEFUNC(TLSv1_1_client_method)
693 RESOLVEFUNC(TLSv1_2_client_method)
695 #ifndef OPENSSL_NO_SSL2
696 RESOLVEFUNC(SSLv2_server_method)
698 RESOLVEFUNC(SSLv3_server_method)
699 RESOLVEFUNC(SSLv23_server_method)
700 RESOLVEFUNC(TLSv1_server_method)
701 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
702 RESOLVEFUNC(TLSv1_1_server_method)
703 RESOLVEFUNC(TLSv1_2_server_method)
705 RESOLVEFUNC(X509_NAME_entry_count)
706 RESOLVEFUNC(X509_NAME_get_entry)
707 RESOLVEFUNC(X509_NAME_ENTRY_get_data)
708 RESOLVEFUNC(X509_NAME_ENTRY_get_object)
709 RESOLVEFUNC(X509_PUBKEY_get)
710 RESOLVEFUNC(X509_STORE_free)
711 RESOLVEFUNC(X509_STORE_new)
712 RESOLVEFUNC(X509_STORE_add_cert)
713 RESOLVEFUNC(X509_STORE_CTX_free)
714 RESOLVEFUNC(X509_STORE_CTX_init)
715 RESOLVEFUNC(X509_STORE_CTX_new)
716 RESOLVEFUNC(X509_STORE_CTX_set_purpose)
717 RESOLVEFUNC(X509_cmp)
718 #ifndef SSLEAY_MACROS
719 RESOLVEFUNC(X509_dup)
721 RESOLVEFUNC(X509_print)
722 RESOLVEFUNC(X509_EXTENSION_get_object)
723 RESOLVEFUNC(X509_free)
724 RESOLVEFUNC(X509_get_ext)
725 RESOLVEFUNC(X509_get_ext_count)
726 RESOLVEFUNC(X509_get_ext_d2i)
727 RESOLVEFUNC(X509V3_EXT_get)
728 RESOLVEFUNC(X509V3_EXT_d2i)
729 RESOLVEFUNC(X509_EXTENSION_get_critical)
730 RESOLVEFUNC(X509_EXTENSION_get_data)
731 RESOLVEFUNC(BASIC_CONSTRAINTS_free)
732 RESOLVEFUNC(AUTHORITY_KEYID_free)
733 RESOLVEFUNC(ASN1_STRING_print)
734 RESOLVEFUNC(X509_get_issuer_name)
735 RESOLVEFUNC(X509_get_subject_name)
736 RESOLVEFUNC(X509_verify_cert)
737 RESOLVEFUNC(d2i_X509)
738 RESOLVEFUNC(i2d_X509)
740 RESOLVEFUNC(i2d_DSAPrivateKey)
741 RESOLVEFUNC(i2d_RSAPrivateKey)
742 RESOLVEFUNC(d2i_DSAPrivateKey)
743 RESOLVEFUNC(d2i_RSAPrivateKey)
745 RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf)
746 RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
747 RESOLVEFUNC(SSL_CTX_load_verify_locations)
749 RESOLVEFUNC(SSLeay_version)
751 symbolsResolved = true;
756 #endif // QT_NO_LIBRARY
758 #else // !defined QT_LINKED_OPENSSL
760 bool q_resolveOpenSslSymbols()
767 #endif // !defined QT_LINKED_OPENSSL
769 //==============================================================================
770 // contributed by Jay Case of Sarvega, Inc.; http://sarvega.com/
771 // Based on X509_cmp_time() for intitial buffer hacking.
772 //==============================================================================
773 QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime)
775 size_t lTimeLength = aTime->length;
776 char *pString = (char *) aTime->data;
778 if (aTime->type == V_ASN1_UTCTIME) {
781 char *pBuffer = lBuffer;
783 if ((lTimeLength < 11) || (lTimeLength > 17))
786 memcpy(pBuffer, pString, 10);
790 if ((*pString == 'Z') || (*pString == '-') || (*pString == '+')) {
794 *pBuffer++ = *pString++;
795 *pBuffer++ = *pString++;
796 // Skip any fractional seconds...
797 if (*pString == '.') {
799 while ((*pString >= '0') && (*pString <= '9'))
807 time_t lSecondsFromUCT;
808 if (*pString == 'Z') {
811 if ((*pString != '+') && (*pString != '-'))
814 lSecondsFromUCT = ((pString[1] - '0') * 10 + (pString[2] - '0')) * 60;
815 lSecondsFromUCT += (pString[3] - '0') * 10 + (pString[4] - '0');
816 lSecondsFromUCT *= 60;
818 lSecondsFromUCT = -lSecondsFromUCT;
822 lTime.tm_sec = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
823 lTime.tm_min = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
824 lTime.tm_hour = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
825 lTime.tm_mday = ((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0');
826 lTime.tm_mon = (((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0')) - 1;
827 lTime.tm_year = ((lBuffer[0] - '0') * 10) + (lBuffer[1] - '0');
828 if (lTime.tm_year < 50)
829 lTime.tm_year += 100; // RFC 2459
831 QDate resDate(lTime.tm_year + 1900, lTime.tm_mon + 1, lTime.tm_mday);
832 QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec);
834 QDateTime result(resDate, resTime, Qt::UTC);
835 result = result.addSecs(lSecondsFromUCT);
838 } else if (aTime->type == V_ASN1_GENERALIZEDTIME) {
840 if (lTimeLength < 15)
841 return QDateTime(); // hopefully never triggered
843 // generalized time is always YYYYMMDDHHMMSSZ (RFC 2459, section 4.1.2.5.2)
845 lTime.tm_sec = ((pString[12] - '0') * 10) + (pString[13] - '0');
846 lTime.tm_min = ((pString[10] - '0') * 10) + (pString[11] - '0');
847 lTime.tm_hour = ((pString[8] - '0') * 10) + (pString[9] - '0');
848 lTime.tm_mday = ((pString[6] - '0') * 10) + (pString[7] - '0');
849 lTime.tm_mon = (((pString[4] - '0') * 10) + (pString[5] - '0'));
850 lTime.tm_year = ((pString[0] - '0') * 1000) + ((pString[1] - '0') * 100) +
851 ((pString[2] - '0') * 10) + (pString[3] - '0');
853 QDate resDate(lTime.tm_year, lTime.tm_mon, lTime.tm_mday);
854 QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec);
856 QDateTime result(resDate, resTime, Qt::UTC);
860 qWarning("unsupported date format detected");