a4cc3c493d8a3fba70b0e11c0734a693d93d83f8
[profile/ivi/qtbase.git] / src / network / ssl / qsslsocket_openssl_symbols.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtNetwork module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42
43 #include "qsslsocket_openssl_symbols_p.h"
44
45 #ifdef Q_OS_WIN
46 # include <private/qsystemlibrary_p.h>
47 #else
48 # include <QtCore/qlibrary.h>
49 #endif
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>
55 #endif
56
57 QT_BEGIN_NAMESPACE
58
59 /*
60     Note to maintainer:
61     -------------------
62
63     We load OpenSSL symbols dynamically. Because symbols are known to
64     disappear, and signatures sometimes change, between releases, we need to
65     be careful about how this is done. To ensure we don't end up dereferencing
66     null function pointers, and continue running even if certain functions are
67     missing, we define helper functions for each of the symbols we load from
68     OpenSSL, all prefixed with "q_" (declared in
69     qsslsocket_openssl_symbols_p.h). So instead of calling SSL_connect
70     directly, we call q_SSL_connect, which is a function that checks if the
71     actual SSL_connect fptr is null, and returns a failure if it is, or calls
72     SSL_connect if it isn't.
73
74     This requires a somewhat tedious process of declaring each function we
75     want to call in OpenSSL thrice: once with the q_, in _p.h, once using the
76     DEFINEFUNC macros below, and once in the function that actually resolves
77     the symbols, below the DEFINEFUNC declarations below.
78
79     There's one DEFINEFUNC macro declared for every number of arguments
80     exposed by OpenSSL (feel free to extend when needed). The easiest thing to
81     do is to find an existing entry that matches the arg count of the function
82     you want to import, and do the same.
83
84     The first macro arg is the function return type. The second is the
85     verbatim name of the function/symbol. Then follows a list of N pairs of
86     argument types with a variable name, and just the variable name (char *a,
87     a, char *b, b, etc). Finally there's two arguments - a suitable return
88     statement for the error case (for an int function, return 0 or return -1
89     is usually right). Then either just "return" or DUMMYARG, the latter being
90     for void functions.
91
92     Note: Take into account that these macros and declarations are processed
93     at compile-time, and the result depends on the OpenSSL headers the
94     compiling host has installed, but the symbols are resolved at run-time,
95     possibly with a different version of OpenSSL.
96 */
97
98 #ifdef SSLEAY_MACROS
99 DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, return 0, return)
100 #endif
101 DEFINEFUNC(long, ASN1_INTEGER_get, ASN1_INTEGER *a, a, return 0, return)
102 DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return 0, return)
103 DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return)
104 DEFINEFUNC2(int, ASN1_STRING_to_UTF8, unsigned char **a, a, ASN1_STRING *b, b, return 0, return);
105 DEFINEFUNC4(long, BIO_ctrl, BIO *a, a, int b, b, long c, c, void *d, d, return -1, return)
106 DEFINEFUNC(int, BIO_free, BIO *a, a, return 0, return)
107 DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return 0, return)
108 DEFINEFUNC2(BIO *, BIO_new_mem_buf, void *a, a, int b, b, return 0, return)
109 DEFINEFUNC3(int, BIO_read, BIO *a, a, void *b, b, int c, c, return -1, return)
110 DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return)
111 DEFINEFUNC3(int, BIO_write, BIO *a, a, const void *b, b, int c, c, return -1, return)
112 DEFINEFUNC(int, BN_num_bits, const BIGNUM *a, a, return 0, return)
113 DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return)
114 DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG)
115 DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG)
116 DEFINEFUNC(void, CRYPTO_free, void *a, a, return, DUMMYARG)
117 DEFINEFUNC(void, DSA_free, DSA *a, a, return, DUMMYARG)
118 #if  OPENSSL_VERSION_NUMBER < 0x00908000L
119 DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, unsigned char **b, b, long c, c, return 0, return)
120 #else // 0.9.8 broke SC and BC by changing this signature.
121 DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, const unsigned char **b, b, long c, c, return 0, return)
122 #endif
123 DEFINEFUNC2(char *, ERR_error_string, unsigned long a, a, char *b, b, return 0, return)
124 DEFINEFUNC(unsigned long, ERR_get_error, DUMMYARG, DUMMYARG, return 0, return)
125 DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return 0, return)
126 DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return)
127 DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return)
128 DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return)
129 DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG)
130 DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return 0, return)
131 DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return 0, return)
132 DEFINEFUNC(EVP_PKEY *, EVP_PKEY_new, DUMMYARG, DUMMYARG, return 0, return)
133 DEFINEFUNC(int, EVP_PKEY_type, int a, a, return NID_undef, return)
134 DEFINEFUNC2(int, i2d_X509, X509 *a, a, unsigned char **b, b, return -1, return)
135 DEFINEFUNC(const char *, OBJ_nid2sn, int a, a, return 0, return)
136 DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return)
137 #ifdef SSLEAY_MACROS
138 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)
139 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)
140 #else
141 DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
142 DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
143 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)
144 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)
145 #endif
146 DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
147 DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
148 DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, return)
149 DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return)
150 DEFINEFUNC2(void, RAND_seed, const void *a, a, int b, b, return, DUMMYARG)
151 DEFINEFUNC(int, RAND_status, void, DUMMYARG, return -1, return)
152 DEFINEFUNC(void, RSA_free, RSA *a, a, return, DUMMYARG)
153 DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return)
154 DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
155 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
156 DEFINEFUNC(void, sk_free, _STACK *a, a, return, DUMMYARG)
157 DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return 0, return)
158 #else
159 DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG)
160 DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return 0, return)
161 #endif
162 DEFINEFUNC(int, SSL_accept, SSL *a, a, return -1, return)
163 DEFINEFUNC(int, SSL_clear, SSL *a, a, return -1, return)
164 DEFINEFUNC3(char *, SSL_CIPHER_description, SSL_CIPHER *a, a, char *b, b, int c, c, return 0, return)
165 DEFINEFUNC(int, SSL_connect, SSL *a, a, return -1, return)
166 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
167 // 0.9.8 broke SC and BC by changing this function's signature.
168 DEFINEFUNC(int, SSL_CTX_check_private_key, const SSL_CTX *a, a, return -1, return)
169 #else
170 DEFINEFUNC(int, SSL_CTX_check_private_key, SSL_CTX *a, a, return -1, return)
171 #endif
172 DEFINEFUNC4(long, SSL_CTX_ctrl, SSL_CTX *a, a, int b, b, long c, c, void *d, d, return -1, return)
173 DEFINEFUNC(void, SSL_CTX_free, SSL_CTX *a, a, return, DUMMYARG)
174 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
175 DEFINEFUNC(SSL_CTX *, SSL_CTX_new, const SSL_METHOD *a, a, return 0, return)
176 #else
177 DEFINEFUNC(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a, a, return 0, return)
178 #endif
179 DEFINEFUNC2(int, SSL_CTX_set_cipher_list, SSL_CTX *a, a, const char *b, b, return -1, return)
180 DEFINEFUNC(int, SSL_CTX_set_default_verify_paths, SSL_CTX *a, a, return -1, return)
181 DEFINEFUNC3(void, SSL_CTX_set_verify, SSL_CTX *a, a, int b, b, int (*c)(int, X509_STORE_CTX *), c, return, DUMMYARG)
182 DEFINEFUNC2(void, SSL_CTX_set_verify_depth, SSL_CTX *a, a, int b, b, return, DUMMYARG)
183 DEFINEFUNC2(int, SSL_CTX_use_certificate, SSL_CTX *a, a, X509 *b, b, return -1, return)
184 DEFINEFUNC3(int, SSL_CTX_use_certificate_file, SSL_CTX *a, a, const char *b, b, int c, c, return -1, return)
185 DEFINEFUNC2(int, SSL_CTX_use_PrivateKey, SSL_CTX *a, a, EVP_PKEY *b, b, return -1, return)
186 DEFINEFUNC2(int, SSL_CTX_use_RSAPrivateKey, SSL_CTX *a, a, RSA *b, b, return -1, return)
187 DEFINEFUNC3(int, SSL_CTX_use_PrivateKey_file, SSL_CTX *a, a, const char *b, b, int c, c, return -1, return)
188 DEFINEFUNC(void, SSL_free, SSL *a, a, return, DUMMYARG)
189 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
190 // 0.9.8 broke SC and BC by changing this function's signature.
191 DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, const SSL *a, a, return 0, return)
192 #else
193 DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, SSL *a, a, return 0, return)
194 #endif
195 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
196 DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
197 #else
198 DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
199 #endif
200 DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
201 DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return 0, return)
202 DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return 0, return)
203 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
204 // 0.9.8 broke SC and BC by changing this function's signature.
205 DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
206 #else
207 DEFINEFUNC(long, SSL_get_verify_result, SSL *a, a, return -1, return)
208 #endif
209 DEFINEFUNC(int, SSL_library_init, void, DUMMYARG, return -1, return)
210 DEFINEFUNC(void, SSL_load_error_strings, void, DUMMYARG, return, DUMMYARG)
211 DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return 0, return)
212 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
213 DEFINEFUNC4(long, SSL_ctrl, SSL *a, a, int cmd, cmd, long larg, larg, const void *parg, parg, return -1, return)
214 #endif
215 DEFINEFUNC3(int, SSL_read, SSL *a, a, void *b, b, int c, c, return -1, return)
216 DEFINEFUNC3(void, SSL_set_bio, SSL *a, a, BIO *b, b, BIO *c, c, return, DUMMYARG)
217 DEFINEFUNC(void, SSL_set_accept_state, SSL *a, a, return, DUMMYARG)
218 DEFINEFUNC(void, SSL_set_connect_state, SSL *a, a, return, DUMMYARG)
219 DEFINEFUNC(int, SSL_shutdown, SSL *a, a, return -1, return)
220 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
221 DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
222 DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
223 DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
224 DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
225 DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
226 DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
227 DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
228 DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
229 #else
230 DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
231 DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
232 DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
233 DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
234 DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
235 DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
236 DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
237 DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
238 #endif
239 DEFINEFUNC3(int, SSL_write, SSL *a, a, const void *b, b, int c, c, return -1, return)
240 DEFINEFUNC2(int, X509_cmp, X509 *a, a, X509 *b, b, return -1, return)
241 #ifndef SSLEAY_MACROS
242 DEFINEFUNC(X509 *, X509_dup, X509 *a, a, return 0, return)
243 #endif
244 DEFINEFUNC(ASN1_OBJECT *, X509_EXTENSION_get_object, X509_EXTENSION *a, a, return 0, return)
245 DEFINEFUNC(void, X509_free, X509 *a, a, return, DUMMYARG)
246 DEFINEFUNC2(X509_EXTENSION *, X509_get_ext, X509 *a, a, int b, b, return 0, return)
247 DEFINEFUNC(int, X509_get_ext_count, X509 *a, a, return 0, return)
248 DEFINEFUNC4(void *, X509_get_ext_d2i, X509 *a, a, int b, b, int *c, c, int *d, d, return 0, return)
249 DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return 0, return)
250 DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return 0, return)
251 DEFINEFUNC(int, X509_verify_cert, X509_STORE_CTX *a, a, return -1, return)
252 DEFINEFUNC(int, X509_NAME_entry_count, X509_NAME *a, a, return 0, return)
253 DEFINEFUNC2(X509_NAME_ENTRY *, X509_NAME_get_entry, X509_NAME *a, a, int b, b, return 0, return)
254 DEFINEFUNC(ASN1_STRING *, X509_NAME_ENTRY_get_data, X509_NAME_ENTRY *a, a, return 0, return)
255 DEFINEFUNC(ASN1_OBJECT *, X509_NAME_ENTRY_get_object, X509_NAME_ENTRY *a, a, return 0, return)
256 DEFINEFUNC(EVP_PKEY *, X509_PUBKEY_get, X509_PUBKEY *a, a, return 0, return)
257 DEFINEFUNC(void, X509_STORE_free, X509_STORE *a, a, return, DUMMYARG)
258 DEFINEFUNC(X509_STORE *, X509_STORE_new, DUMMYARG, DUMMYARG, return 0, return)
259 DEFINEFUNC2(int, X509_STORE_add_cert, X509_STORE *a, a, X509 *b, b, return 0, return)
260 DEFINEFUNC(void, X509_STORE_CTX_free, X509_STORE_CTX *a, a, return, DUMMYARG)
261 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)
262 DEFINEFUNC2(int, X509_STORE_CTX_set_purpose, X509_STORE_CTX *a, a, int b, b, return -1, return)
263 DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return 0, return)
264 #ifdef SSLEAY_MACROS
265 DEFINEFUNC2(int, i2d_DSAPrivateKey, const DSA *a, a, unsigned char **b, b, return -1, return)
266 DEFINEFUNC2(int, i2d_RSAPrivateKey, const RSA *a, a, unsigned char **b, b, return -1, return)
267 DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return 0, return)
268 DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return 0, return)
269 #endif
270 DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG)
271 DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG)
272 DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return)
273 DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
274
275 #ifdef Q_OS_SYMBIAN
276 #define RESOLVEFUNC(func, ordinal, lib) \
277     if (!(_q_##func = _q_PTR_##func(lib->resolve(#ordinal)))) \
278         qWarning("QSslSocket: cannot resolve "#func);
279 #else
280 #define RESOLVEFUNC(func) \
281     if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func)))     \
282         && !(_q_##func = _q_PTR_##func(libs.second->resolve(#func)))) \
283         qWarning("QSslSocket: cannot resolve "#func);
284 #endif
285
286 #if !defined QT_LINKED_OPENSSL
287
288 #ifdef QT_NO_LIBRARY
289 bool q_resolveOpenSslSymbols()
290 {
291     qWarning("QSslSocket: unable to resolve symbols. "
292              "QT_NO_LIBRARY is defined which means runtime resolving of "
293              "libraries won't work.");
294     qWarning("Either compile Qt statically or with support for runtime resolving "
295              "of libraries.");
296     return false;
297 }
298 #else
299
300 # ifdef Q_OS_UNIX
301 static bool libGreaterThan(const QString &lhs, const QString &rhs)
302 {
303     QStringList lhsparts = lhs.split(QLatin1Char('.'));
304     QStringList rhsparts = rhs.split(QLatin1Char('.'));
305     Q_ASSERT(lhsparts.count() > 1 && rhsparts.count() > 1);
306
307     for (int i = 1; i < rhsparts.count(); ++i) {
308         if (lhsparts.count() <= i)
309             // left hand side is shorter, so it's less than rhs
310             return false;
311
312         bool ok = false;
313         int b = 0;
314         int a = lhsparts.at(i).toInt(&ok);
315         if (ok)
316             b = rhsparts.at(i).toInt(&ok);
317         if (ok) {
318             // both toInt succeeded
319             if (a == b)
320                 continue;
321             return a > b;
322         } else {
323             // compare as strings;
324             if (lhsparts.at(i) == rhsparts.at(i))
325                 continue;
326             return lhsparts.at(i) > rhsparts.at(i);
327         }
328     }
329
330     // they compared strictly equally so far
331     // lhs cannot be less than rhs
332     return true;
333 }
334
335 static QStringList findAllLibSsl()
336 {
337     QStringList paths;
338 #  ifdef Q_OS_DARWIN
339     paths = QString::fromLatin1(qgetenv("DYLD_LIBRARY_PATH"))
340             .split(QLatin1Char(':'), QString::SkipEmptyParts);
341 #  else
342     paths = QString::fromLatin1(qgetenv("LD_LIBRARY_PATH"))
343             .split(QLatin1Char(':'), QString::SkipEmptyParts);
344 #  endif
345     paths << QLatin1String("/lib") << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib");
346
347     QStringList foundSsls;
348     foreach (const QString &path, paths) {
349         QDir dir = QDir(path);
350         QStringList entryList = dir.entryList(QStringList() << QLatin1String("libssl.*"), QDir::Files);
351
352         qSort(entryList.begin(), entryList.end(), libGreaterThan);
353         foreach (const QString &entry, entryList)
354             foundSsls << path + QLatin1Char('/') + entry;
355     }
356
357     return foundSsls;
358 }
359 # endif
360
361 #ifdef Q_OS_WIN
362 static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
363 {
364     QPair<QSystemLibrary*,QSystemLibrary*> pair;
365     pair.first = 0;
366     pair.second = 0;
367
368     QSystemLibrary *ssleay32 = new QSystemLibrary(QLatin1String("ssleay32"));
369     if (!ssleay32->load(false)) {
370         // Cannot find ssleay32.dll
371         delete ssleay32;
372         return pair;
373     }
374
375     QSystemLibrary *libeay32 = new QSystemLibrary(QLatin1String("libeay32"));
376     if (!libeay32->load(false)) {
377         delete ssleay32;
378         delete libeay32;
379         return pair;
380     }
381
382     pair.first = ssleay32;
383     pair.second = libeay32;
384     return pair;
385 }
386 #else
387
388 static QPair<QLibrary*, QLibrary*> loadOpenSsl()
389 {
390     QPair<QLibrary*,QLibrary*> pair;
391     pair.first = 0;
392     pair.second = 0;
393
394 # if defined(Q_OS_SYMBIAN)
395      QLibrary *libssl = new QLibrary(QLatin1String("libssl"));
396     if (!libssl->load()) {
397         // Cannot find ssleay32.dll
398         delete libssl;
399         return pair;
400     }
401
402     QLibrary *libcrypto = new QLibrary(QLatin1String("libcrypto"));
403     if (!libcrypto->load()) {
404         delete libcrypto;
405         delete libssl;
406         return pair;
407     }
408
409     pair.first = libssl;
410     pair.second = libcrypto;
411     return pair;
412 # elif defined(Q_OS_UNIX)
413     QLibrary *&libssl = pair.first;
414     QLibrary *&libcrypto = pair.second;
415     libssl = new QLibrary;
416     libcrypto = new QLibrary;
417
418     // Try to find the libssl library on the system.
419     //
420     // Up until Qt 4.3, this only searched for the "ssl" library at version -1, that
421     // is, libssl.so on most Unix systems.  However, the .so file isn't present in
422     // user installations because it's considered a development file.
423     //
424     // The right thing to do is to load the library at the major version we know how
425     // to work with: the SHLIB_VERSION_NUMBER version (macro defined in opensslv.h)
426     //
427     // However, OpenSSL is a well-known case of binary-compatibility breakage. To
428     // avoid such problems, many system integrators and Linux distributions change
429     // the soname of the binary, letting the full version number be the soname. So
430     // we'll find libssl.so.0.9.7, libssl.so.0.9.8, etc. in the system. For that
431     // reason, we will search a few common paths (see findAllLibSsl() above) in hopes
432     // we find one that works.
433     //
434     // It is important, however, to try the canonical name and the unversioned name
435     // without going through the loop. By not specifying a path, we let the system
436     // dlopen(3) function determine it for us. This will include any DT_RUNPATH or
437     // DT_RPATH tags on our library header as well as other system-specific search
438     // paths. See the man page for dlopen(3) on your system for more information.
439
440 #ifdef Q_OS_OPENBSD
441     libcrypto->setLoadHints(QLibrary::ExportExternalSymbolsHint);
442 #endif
443 #ifdef SHLIB_VERSION_NUMBER
444     // first attempt: the canonical name is libssl.so.<SHLIB_VERSION_NUMBER>
445     libssl->setFileNameAndVersion(QLatin1String("ssl"), QLatin1String(SHLIB_VERSION_NUMBER));
446     libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String(SHLIB_VERSION_NUMBER));
447     if (libcrypto->load() && libssl->load()) {
448         // libssl.so.<SHLIB_VERSION_NUMBER> and libcrypto.so.<SHLIB_VERSION_NUMBER> found
449         return pair;
450     } else {
451         libssl->unload();
452         libcrypto->unload();
453     }
454 #endif
455
456     // second attempt: find the development files libssl.so and libcrypto.so
457     libssl->setFileNameAndVersion(QLatin1String("ssl"), -1);
458     libcrypto->setFileNameAndVersion(QLatin1String("crypto"), -1);
459     if (libcrypto->load() && libssl->load()) {
460         // libssl.so.0 and libcrypto.so.0 found
461         return pair;
462     } else {
463         libssl->unload();
464         libcrypto->unload();
465     }
466
467     // third attempt: loop on the most common library paths and find libssl
468     QStringList sslList = findAllLibSsl();
469     foreach (const QString &ssl, sslList) {
470         QString crypto = ssl;
471         crypto.replace(QLatin1String("ssl"), QLatin1String("crypto"));
472         libssl->setFileNameAndVersion(ssl, -1);
473         libcrypto->setFileNameAndVersion(crypto, -1);
474         if (libcrypto->load() && libssl->load()) {
475             // libssl.so.0 and libcrypto.so.0 found
476             return pair;
477         } else {
478             libssl->unload();
479             libcrypto->unload();
480         }
481     }
482
483     // failed to load anything
484     delete libssl;
485     delete libcrypto;
486     libssl = libcrypto = 0;
487     return pair;
488
489 # else
490     // not implemented for this platform yet
491     return pair;
492 # endif
493 }
494 #endif
495
496 bool q_resolveOpenSslSymbols()
497 {
498     static volatile bool symbolsResolved = false;
499     static volatile bool triedToResolveSymbols = false;
500 #ifndef QT_NO_THREAD
501     QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_SSL_library_init));
502 #endif
503     if (symbolsResolved)
504         return true;
505     if (triedToResolveSymbols)
506         return false;
507     triedToResolveSymbols = true;
508
509 #ifdef Q_OS_WIN
510     QPair<QSystemLibrary *, QSystemLibrary *> libs = loadOpenSslWin32();
511 #else
512     QPair<QLibrary *, QLibrary *> libs = loadOpenSsl();
513 #endif
514     if (!libs.first || !libs.second)
515         // failed to load them
516         return false;
517
518 #ifdef Q_OS_SYMBIAN
519 #ifdef SSLEAY_MACROS
520     RESOLVEFUNC(ASN1_dup, 125, libs.second )
521 #endif
522     RESOLVEFUNC(ASN1_INTEGER_get, 48, libs.second )
523     RESOLVEFUNC(ASN1_STRING_data, 71, libs.second )
524     RESOLVEFUNC(ASN1_STRING_length, 76, libs.second )
525     RESOLVEFUNC(ASN1_STRING_to_UTF8, 86, libs.second )
526     RESOLVEFUNC(BIO_ctrl, 184, libs.second )
527     RESOLVEFUNC(BIO_free, 209, libs.second )
528     RESOLVEFUNC(BIO_new, 222, libs.second )
529     RESOLVEFUNC(BIO_new_mem_buf, 230, libs.second )
530     RESOLVEFUNC(BIO_read, 244, libs.second )
531     RESOLVEFUNC(BIO_s_mem, 251, libs.second )
532     RESOLVEFUNC(BIO_write, 269, libs.second )
533     RESOLVEFUNC(BN_num_bits, 387, libs.second )
534     RESOLVEFUNC(CRYPTO_free, 469, libs.second )
535     RESOLVEFUNC(CRYPTO_num_locks, 500, libs.second )
536     RESOLVEFUNC(CRYPTO_set_id_callback, 513, libs.second )
537     RESOLVEFUNC(CRYPTO_set_locking_callback, 516, libs.second )
538     RESOLVEFUNC(DSA_free, 594, libs.second )
539     RESOLVEFUNC(ERR_error_string, 744, libs.second )
540     RESOLVEFUNC(ERR_get_error, 749, libs.second )
541     RESOLVEFUNC(EVP_des_ede3_cbc, 919, libs.second )
542     RESOLVEFUNC(EVP_PKEY_assign, 859, libs.second )
543     RESOLVEFUNC(EVP_PKEY_set1_RSA, 880, libs.second )
544     RESOLVEFUNC(EVP_PKEY_set1_DSA, 879, libs.second )
545     RESOLVEFUNC(EVP_PKEY_free, 867, libs.second )
546     RESOLVEFUNC(EVP_PKEY_get1_DSA, 869, libs.second )
547     RESOLVEFUNC(EVP_PKEY_get1_RSA, 870, libs.second )
548     RESOLVEFUNC(EVP_PKEY_new, 876, libs.second )
549     RESOLVEFUNC(EVP_PKEY_type, 882, libs.second )
550     RESOLVEFUNC(OBJ_nid2sn, 1036, libs.second )
551     RESOLVEFUNC(OBJ_obj2nid, 1037, libs.second )
552 #ifdef SSLEAY_MACROS // ### verify
553     RESOLVEFUNC(PEM_ASN1_read_bio, 1180, libs.second )
554 #else
555     RESOLVEFUNC(PEM_read_bio_DSAPrivateKey, 1219, libs.second )
556     RESOLVEFUNC(PEM_read_bio_RSAPrivateKey, 1228, libs.second )
557     RESOLVEFUNC(PEM_write_bio_DSAPrivateKey, 1260, libs.second )
558     RESOLVEFUNC(PEM_write_bio_RSAPrivateKey, 1271, libs.second )
559 #endif
560     RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY, 1220, libs.second )
561     RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY, 1230, libs.second )
562     RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY, 1261, libs.second )
563     RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY, 1273, libs.second )
564     RESOLVEFUNC(RAND_seed, 1426, libs.second )
565     RESOLVEFUNC(RAND_status, 1429, libs.second )
566     RESOLVEFUNC(RSA_free, 1450, libs.second )
567     RESOLVEFUNC(sk_free, 2571, libs.second )
568     RESOLVEFUNC(sk_num, 2576, libs.second )
569     RESOLVEFUNC(sk_pop_free, 2578, libs.second )    
570     RESOLVEFUNC(sk_value, 2585, libs.second )
571     RESOLVEFUNC(SSL_CIPHER_description, 11, libs.first )
572     RESOLVEFUNC(SSL_CTX_check_private_key, 21, libs.first )
573     RESOLVEFUNC(SSL_CTX_ctrl, 22, libs.first )
574     RESOLVEFUNC(SSL_CTX_free, 24, libs.first )
575     RESOLVEFUNC(SSL_CTX_new, 35, libs.first )
576     RESOLVEFUNC(SSL_CTX_set_cipher_list, 40, libs.first )
577     RESOLVEFUNC(SSL_CTX_set_default_verify_paths, 44, libs.first )
578     RESOLVEFUNC(SSL_CTX_set_verify, 56, libs.first )
579     RESOLVEFUNC(SSL_CTX_set_verify_depth, 57, libs.first )
580     RESOLVEFUNC(SSL_CTX_use_certificate, 64, libs.first )
581     RESOLVEFUNC(SSL_CTX_use_certificate_file, 67, libs.first )
582     RESOLVEFUNC(SSL_CTX_use_PrivateKey, 58, libs.first )
583     RESOLVEFUNC(SSL_CTX_use_RSAPrivateKey, 61, libs.first )
584     RESOLVEFUNC(SSL_CTX_use_PrivateKey_file, 60, libs.first )
585     RESOLVEFUNC(SSL_accept, 82, libs.first )
586     RESOLVEFUNC(SSL_clear, 92, libs.first )
587     RESOLVEFUNC(SSL_connect, 93, libs.first )
588     RESOLVEFUNC(SSL_free, 99, libs.first )
589     RESOLVEFUNC(SSL_get_ciphers, 104, libs.first )
590     RESOLVEFUNC(SSL_get_current_cipher, 106, libs.first )
591     RESOLVEFUNC(SSL_get_error, 110, libs.first )
592     RESOLVEFUNC(SSL_get_peer_cert_chain, 117, libs.first )
593     RESOLVEFUNC(SSL_get_peer_certificate, 118, libs.first )
594     RESOLVEFUNC(SSL_get_verify_result, 132, libs.first )
595     RESOLVEFUNC(SSL_library_init, 137, libs.first )
596     RESOLVEFUNC(SSL_load_error_strings, 139, libs.first )
597     RESOLVEFUNC(SSL_new, 140, libs.first )
598 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
599     RESOLVEFUNC(SSL_ctrl, 95, libs.first )
600 #endif
601     RESOLVEFUNC(SSL_read, 143, libs.first )
602     RESOLVEFUNC(SSL_set_accept_state, 148, libs.first )
603     RESOLVEFUNC(SSL_set_bio, 149, libs.first )
604     RESOLVEFUNC(SSL_set_connect_state, 152, libs.first )
605     RESOLVEFUNC(SSL_shutdown, 173, libs.first )
606     RESOLVEFUNC(SSL_write, 188, libs.first )
607     RESOLVEFUNC(SSLv2_client_method, 192, libs.first )
608     RESOLVEFUNC(SSLv3_client_method, 195, libs.first )
609     RESOLVEFUNC(SSLv23_client_method, 189, libs.first )
610     RESOLVEFUNC(TLSv1_client_method, 198, libs.first )
611     RESOLVEFUNC(SSLv2_server_method, 194, libs.first )
612     RESOLVEFUNC(SSLv3_server_method, 197, libs.first )
613     RESOLVEFUNC(SSLv23_server_method, 191, libs.first )
614     RESOLVEFUNC(TLSv1_server_method, 200, libs.first )
615     RESOLVEFUNC(SSL_CTX_load_verify_locations, 34, libs.first )
616     RESOLVEFUNC(X509_NAME_entry_count, 1821, libs.second )
617     RESOLVEFUNC(X509_NAME_get_entry, 1823, libs.second )
618     RESOLVEFUNC(X509_NAME_ENTRY_get_data, 1808, libs.second )
619     RESOLVEFUNC(X509_NAME_ENTRY_get_object, 1809, libs.second )
620     RESOLVEFUNC(X509_PUBKEY_get, 1844, libs.second )
621     RESOLVEFUNC(X509_STORE_free, 1939, libs.second )
622     RESOLVEFUNC(X509_STORE_new, 1942, libs.second )
623     RESOLVEFUNC(X509_STORE_add_cert, 1936, libs.second )
624     RESOLVEFUNC(X509_STORE_CTX_free, 1907, libs.second )
625     RESOLVEFUNC(X509_STORE_CTX_init, 1919, libs.second )
626     RESOLVEFUNC(X509_STORE_CTX_new, 1920, libs.second )
627     RESOLVEFUNC(X509_STORE_CTX_set_purpose, 1931, libs.second )
628     RESOLVEFUNC(X509_cmp, 1992, libs.second )
629 #ifndef SSLEAY_MACROS
630     RESOLVEFUNC(X509_dup, 1997, libs.second )
631 #endif
632     RESOLVEFUNC(X509_EXTENSION_get_object, 1785, libs.second )
633     RESOLVEFUNC(X509_free, 2001, libs.second )
634     RESOLVEFUNC(X509_get_ext, 2012, libs.second )
635     RESOLVEFUNC(X509_get_ext_count, 2016, libs.second )
636     RESOLVEFUNC(X509_get_ext_d2i, 2017, libs.second )
637     RESOLVEFUNC(X509_get_issuer_name, 2018, libs.second )
638     RESOLVEFUNC(X509_get_subject_name, 2022, libs.second )
639     RESOLVEFUNC(X509_verify_cert, 2069, libs.second )
640     RESOLVEFUNC(d2i_X509, 2309, libs.second )
641     RESOLVEFUNC(i2d_X509, 2489, libs.second )
642 #ifdef SSLEAY_MACROS
643     RESOLVEFUNC(i2d_DSAPrivateKey, 2395, libs.second )
644     RESOLVEFUNC(i2d_RSAPrivateKey, 2476, libs.second )
645     RESOLVEFUNC(d2i_DSAPrivateKey, 2220, libs.second )
646     RESOLVEFUNC(d2i_RSAPrivateKey, 2296, libs.second )
647 #endif
648     RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf, 1153, libs.second )
649     RESOLVEFUNC(OPENSSL_add_all_algorithms_conf, 1152, libs.second )
650     RESOLVEFUNC(SSLeay, 1504, libs.second )
651 #else // Q_OS_SYMBIAN
652 #ifdef SSLEAY_MACROS
653     RESOLVEFUNC(ASN1_dup)
654 #endif
655     RESOLVEFUNC(ASN1_INTEGER_get)
656     RESOLVEFUNC(ASN1_STRING_data)
657     RESOLVEFUNC(ASN1_STRING_length)
658     RESOLVEFUNC(ASN1_STRING_to_UTF8)
659     RESOLVEFUNC(BIO_ctrl)
660     RESOLVEFUNC(BIO_free)
661     RESOLVEFUNC(BIO_new)
662     RESOLVEFUNC(BIO_new_mem_buf)
663     RESOLVEFUNC(BIO_read)
664     RESOLVEFUNC(BIO_s_mem)
665     RESOLVEFUNC(BIO_write)
666     RESOLVEFUNC(BN_num_bits)
667     RESOLVEFUNC(CRYPTO_free)
668     RESOLVEFUNC(CRYPTO_num_locks)
669     RESOLVEFUNC(CRYPTO_set_id_callback)
670     RESOLVEFUNC(CRYPTO_set_locking_callback)
671     RESOLVEFUNC(DSA_free)
672     RESOLVEFUNC(ERR_error_string)
673     RESOLVEFUNC(ERR_get_error)
674     RESOLVEFUNC(EVP_des_ede3_cbc)
675     RESOLVEFUNC(EVP_PKEY_assign)
676     RESOLVEFUNC(EVP_PKEY_set1_RSA)
677     RESOLVEFUNC(EVP_PKEY_set1_DSA)
678     RESOLVEFUNC(EVP_PKEY_free)
679     RESOLVEFUNC(EVP_PKEY_get1_DSA)
680     RESOLVEFUNC(EVP_PKEY_get1_RSA)
681     RESOLVEFUNC(EVP_PKEY_new)
682     RESOLVEFUNC(EVP_PKEY_type)
683     RESOLVEFUNC(OBJ_nid2sn)
684     RESOLVEFUNC(OBJ_obj2nid)
685 #ifdef SSLEAY_MACROS // ### verify
686     RESOLVEFUNC(PEM_ASN1_read_bio)
687 #else
688     RESOLVEFUNC(PEM_read_bio_DSAPrivateKey)
689     RESOLVEFUNC(PEM_read_bio_RSAPrivateKey)
690     RESOLVEFUNC(PEM_write_bio_DSAPrivateKey)
691     RESOLVEFUNC(PEM_write_bio_RSAPrivateKey)
692 #endif
693     RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY)
694     RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY)
695     RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY)
696     RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY)
697     RESOLVEFUNC(RAND_seed)
698     RESOLVEFUNC(RAND_status)
699     RESOLVEFUNC(RSA_free)
700     RESOLVEFUNC(sk_free)
701     RESOLVEFUNC(sk_num)
702     RESOLVEFUNC(sk_pop_free)
703     RESOLVEFUNC(sk_value)
704     RESOLVEFUNC(SSL_CIPHER_description)
705     RESOLVEFUNC(SSL_CTX_check_private_key)
706     RESOLVEFUNC(SSL_CTX_ctrl)
707     RESOLVEFUNC(SSL_CTX_free)
708     RESOLVEFUNC(SSL_CTX_new)
709     RESOLVEFUNC(SSL_CTX_set_cipher_list)
710     RESOLVEFUNC(SSL_CTX_set_default_verify_paths)
711     RESOLVEFUNC(SSL_CTX_set_verify)
712     RESOLVEFUNC(SSL_CTX_set_verify_depth)
713     RESOLVEFUNC(SSL_CTX_use_certificate)
714     RESOLVEFUNC(SSL_CTX_use_certificate_file)
715     RESOLVEFUNC(SSL_CTX_use_PrivateKey)
716     RESOLVEFUNC(SSL_CTX_use_RSAPrivateKey)
717     RESOLVEFUNC(SSL_CTX_use_PrivateKey_file)
718     RESOLVEFUNC(SSL_accept)
719     RESOLVEFUNC(SSL_clear)
720     RESOLVEFUNC(SSL_connect)
721     RESOLVEFUNC(SSL_free)
722     RESOLVEFUNC(SSL_get_ciphers)
723     RESOLVEFUNC(SSL_get_current_cipher)
724     RESOLVEFUNC(SSL_get_error)
725     RESOLVEFUNC(SSL_get_peer_cert_chain)
726     RESOLVEFUNC(SSL_get_peer_certificate)
727     RESOLVEFUNC(SSL_get_verify_result)
728     RESOLVEFUNC(SSL_library_init)
729     RESOLVEFUNC(SSL_load_error_strings)
730     RESOLVEFUNC(SSL_new)
731 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
732     RESOLVEFUNC(SSL_ctrl)
733 #endif
734     RESOLVEFUNC(SSL_read)
735     RESOLVEFUNC(SSL_set_accept_state)
736     RESOLVEFUNC(SSL_set_bio)
737     RESOLVEFUNC(SSL_set_connect_state)
738     RESOLVEFUNC(SSL_shutdown)
739     RESOLVEFUNC(SSL_write)
740     RESOLVEFUNC(SSLv2_client_method)
741     RESOLVEFUNC(SSLv3_client_method)
742     RESOLVEFUNC(SSLv23_client_method)
743     RESOLVEFUNC(TLSv1_client_method)
744     RESOLVEFUNC(SSLv2_server_method)
745     RESOLVEFUNC(SSLv3_server_method)
746     RESOLVEFUNC(SSLv23_server_method)
747     RESOLVEFUNC(TLSv1_server_method)
748     RESOLVEFUNC(X509_NAME_entry_count)
749     RESOLVEFUNC(X509_NAME_get_entry)
750     RESOLVEFUNC(X509_NAME_ENTRY_get_data)
751     RESOLVEFUNC(X509_NAME_ENTRY_get_object)
752     RESOLVEFUNC(X509_PUBKEY_get)
753     RESOLVEFUNC(X509_STORE_free)
754     RESOLVEFUNC(X509_STORE_new)
755     RESOLVEFUNC(X509_STORE_add_cert)
756     RESOLVEFUNC(X509_STORE_CTX_free)
757     RESOLVEFUNC(X509_STORE_CTX_init)
758     RESOLVEFUNC(X509_STORE_CTX_new)
759     RESOLVEFUNC(X509_STORE_CTX_set_purpose)
760     RESOLVEFUNC(X509_cmp)
761 #ifndef SSLEAY_MACROS
762     RESOLVEFUNC(X509_dup)
763 #endif
764     RESOLVEFUNC(X509_EXTENSION_get_object)
765     RESOLVEFUNC(X509_free)
766     RESOLVEFUNC(X509_get_ext)
767     RESOLVEFUNC(X509_get_ext_count)
768     RESOLVEFUNC(X509_get_ext_d2i)
769     RESOLVEFUNC(X509_get_issuer_name)
770     RESOLVEFUNC(X509_get_subject_name)
771     RESOLVEFUNC(X509_verify_cert)
772     RESOLVEFUNC(d2i_X509)
773     RESOLVEFUNC(i2d_X509)
774 #ifdef SSLEAY_MACROS
775     RESOLVEFUNC(i2d_DSAPrivateKey)
776     RESOLVEFUNC(i2d_RSAPrivateKey)
777     RESOLVEFUNC(d2i_DSAPrivateKey)
778     RESOLVEFUNC(d2i_RSAPrivateKey)
779 #endif
780     RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf)
781     RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
782     RESOLVEFUNC(SSL_CTX_load_verify_locations)
783     RESOLVEFUNC(SSLeay)
784 #endif // Q_OS_SYMBIAN
785     symbolsResolved = true;
786     delete libs.first;
787     delete libs.second;
788     return true;
789 }
790 #endif // QT_NO_LIBRARY
791
792 #else // !defined QT_LINKED_OPENSSL
793
794 bool q_resolveOpenSslSymbols()
795 {
796 #ifdef QT_NO_OPENSSL
797     return false;
798 #endif
799     return true;
800 }
801 #endif // !defined QT_LINKED_OPENSSL
802
803 //==============================================================================
804 // contributed by Jay Case of Sarvega, Inc.; http://sarvega.com/
805 // Based on X509_cmp_time() for intitial buffer hacking.
806 //==============================================================================
807 QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime)
808 {
809     size_t lTimeLength = aTime->length;
810     char *pString = (char *) aTime->data;
811
812     if (aTime->type == V_ASN1_UTCTIME) {
813
814         char lBuffer[24];
815         char *pBuffer = lBuffer;
816
817         if ((lTimeLength < 11) || (lTimeLength > 17))
818             return QDateTime();
819
820         memcpy(pBuffer, pString, 10);
821         pBuffer += 10;
822         pString += 10;
823
824         if ((*pString == 'Z') || (*pString == '-') || (*pString == '+')) {
825             *pBuffer++ = '0';
826             *pBuffer++ = '0';
827         } else {
828             *pBuffer++ = *pString++;
829             *pBuffer++ = *pString++;
830             // Skip any fractional seconds...
831             if (*pString == '.') {
832                 pString++;
833                 while ((*pString >= '0') && (*pString <= '9'))
834                     pString++;
835             }
836         }
837
838         *pBuffer++ = 'Z';
839         *pBuffer++ = '\0';
840
841         time_t lSecondsFromUCT;
842         if (*pString == 'Z') {
843             lSecondsFromUCT = 0;
844         } else {
845             if ((*pString != '+') && (*pString != '-'))
846                 return QDateTime();
847
848             lSecondsFromUCT = ((pString[1] - '0') * 10 + (pString[2] - '0')) * 60;
849             lSecondsFromUCT += (pString[3] - '0') * 10 + (pString[4] - '0');
850             lSecondsFromUCT *= 60;
851             if (*pString == '-')
852                 lSecondsFromUCT = -lSecondsFromUCT;
853         }
854
855         tm lTime;
856         lTime.tm_sec = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
857         lTime.tm_min = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
858         lTime.tm_hour = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
859         lTime.tm_mday = ((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0');
860         lTime.tm_mon = (((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0')) - 1;
861         lTime.tm_year = ((lBuffer[0] - '0') * 10) + (lBuffer[1] - '0');
862         if (lTime.tm_year < 50)
863             lTime.tm_year += 100; // RFC 2459
864
865         QDate resDate(lTime.tm_year + 1900, lTime.tm_mon + 1, lTime.tm_mday);
866         QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec);
867
868         QDateTime result(resDate, resTime, Qt::UTC);
869         result = result.addSecs(lSecondsFromUCT);
870         return result;
871
872     } else if (aTime->type == V_ASN1_GENERALIZEDTIME) {
873
874         if (lTimeLength < 15)
875             return QDateTime(); // hopefully never triggered
876
877         // generalized time is always YYYYMMDDHHMMSSZ (RFC 2459, section 4.1.2.5.2)
878         tm lTime;
879         lTime.tm_sec = ((pString[12] - '0') * 10) + (pString[13] - '0');
880         lTime.tm_min = ((pString[10] - '0') * 10) + (pString[11] - '0');
881         lTime.tm_hour = ((pString[8] - '0') * 10) + (pString[9] - '0');
882         lTime.tm_mday = ((pString[6] - '0') * 10) + (pString[7] - '0');
883         lTime.tm_mon = (((pString[4] - '0') * 10) + (pString[5] - '0'));
884         lTime.tm_year = ((pString[0] - '0') * 1000) + ((pString[1] - '0') * 100) +
885                         ((pString[2] - '0') * 10) + (pString[3] - '0');
886
887         QDate resDate(lTime.tm_year, lTime.tm_mon, lTime.tm_mday);
888         QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec);
889
890         QDateTime result(resDate, resTime, Qt::UTC);
891         return result;
892
893     } else {
894         qWarning("unsupported date format detected");
895         return QDateTime();
896     }
897
898 }
899
900 QT_END_NAMESPACE