Add the ability to convert a certificate to text
[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 DEFINEFUNC2(void, X509_print, BIO *a, a, X509 *b, b, return, DUMMYARG);
245 DEFINEFUNC(ASN1_OBJECT *, X509_EXTENSION_get_object, X509_EXTENSION *a, a, return 0, return)
246 DEFINEFUNC(void, X509_free, X509 *a, a, return, DUMMYARG)
247 DEFINEFUNC2(X509_EXTENSION *, X509_get_ext, X509 *a, a, int b, b, return 0, return)
248 DEFINEFUNC(int, X509_get_ext_count, X509 *a, a, return 0, return)
249 DEFINEFUNC4(void *, X509_get_ext_d2i, X509 *a, a, int b, b, int *c, c, int *d, d, return 0, return)
250 DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return 0, return)
251 DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return 0, return)
252 DEFINEFUNC(int, X509_verify_cert, X509_STORE_CTX *a, a, return -1, return)
253 DEFINEFUNC(int, X509_NAME_entry_count, X509_NAME *a, a, return 0, return)
254 DEFINEFUNC2(X509_NAME_ENTRY *, X509_NAME_get_entry, X509_NAME *a, a, int b, b, return 0, return)
255 DEFINEFUNC(ASN1_STRING *, X509_NAME_ENTRY_get_data, X509_NAME_ENTRY *a, a, return 0, return)
256 DEFINEFUNC(ASN1_OBJECT *, X509_NAME_ENTRY_get_object, X509_NAME_ENTRY *a, a, return 0, return)
257 DEFINEFUNC(EVP_PKEY *, X509_PUBKEY_get, X509_PUBKEY *a, a, return 0, return)
258 DEFINEFUNC(void, X509_STORE_free, X509_STORE *a, a, return, DUMMYARG)
259 DEFINEFUNC(X509_STORE *, X509_STORE_new, DUMMYARG, DUMMYARG, return 0, return)
260 DEFINEFUNC2(int, X509_STORE_add_cert, X509_STORE *a, a, X509 *b, b, return 0, return)
261 DEFINEFUNC(void, X509_STORE_CTX_free, X509_STORE_CTX *a, a, return, DUMMYARG)
262 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)
263 DEFINEFUNC2(int, X509_STORE_CTX_set_purpose, X509_STORE_CTX *a, a, int b, b, return -1, return)
264 DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return 0, return)
265 #ifdef SSLEAY_MACROS
266 DEFINEFUNC2(int, i2d_DSAPrivateKey, const DSA *a, a, unsigned char **b, b, return -1, return)
267 DEFINEFUNC2(int, i2d_RSAPrivateKey, const RSA *a, a, unsigned char **b, b, return -1, return)
268 DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return 0, return)
269 DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return 0, return)
270 #endif
271 DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG)
272 DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG)
273 DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return)
274 DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
275
276 #ifdef Q_OS_SYMBIAN
277 #define RESOLVEFUNC(func, ordinal, lib) \
278     if (!(_q_##func = _q_PTR_##func(lib->resolve(#ordinal)))) \
279         qWarning("QSslSocket: cannot resolve "#func);
280 #else
281 #define RESOLVEFUNC(func) \
282     if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func)))     \
283         && !(_q_##func = _q_PTR_##func(libs.second->resolve(#func)))) \
284         qWarning("QSslSocket: cannot resolve "#func);
285 #endif
286
287 #if !defined QT_LINKED_OPENSSL
288
289 #ifdef QT_NO_LIBRARY
290 bool q_resolveOpenSslSymbols()
291 {
292     qWarning("QSslSocket: unable to resolve symbols. "
293              "QT_NO_LIBRARY is defined which means runtime resolving of "
294              "libraries won't work.");
295     qWarning("Either compile Qt statically or with support for runtime resolving "
296              "of libraries.");
297     return false;
298 }
299 #else
300
301 # ifdef Q_OS_UNIX
302 static bool libGreaterThan(const QString &lhs, const QString &rhs)
303 {
304     QStringList lhsparts = lhs.split(QLatin1Char('.'));
305     QStringList rhsparts = rhs.split(QLatin1Char('.'));
306     Q_ASSERT(lhsparts.count() > 1 && rhsparts.count() > 1);
307
308     for (int i = 1; i < rhsparts.count(); ++i) {
309         if (lhsparts.count() <= i)
310             // left hand side is shorter, so it's less than rhs
311             return false;
312
313         bool ok = false;
314         int b = 0;
315         int a = lhsparts.at(i).toInt(&ok);
316         if (ok)
317             b = rhsparts.at(i).toInt(&ok);
318         if (ok) {
319             // both toInt succeeded
320             if (a == b)
321                 continue;
322             return a > b;
323         } else {
324             // compare as strings;
325             if (lhsparts.at(i) == rhsparts.at(i))
326                 continue;
327             return lhsparts.at(i) > rhsparts.at(i);
328         }
329     }
330
331     // they compared strictly equally so far
332     // lhs cannot be less than rhs
333     return true;
334 }
335
336 static QStringList findAllLibSsl()
337 {
338     QStringList paths;
339 #  ifdef Q_OS_DARWIN
340     paths = QString::fromLatin1(qgetenv("DYLD_LIBRARY_PATH"))
341             .split(QLatin1Char(':'), QString::SkipEmptyParts);
342 #  else
343     paths = QString::fromLatin1(qgetenv("LD_LIBRARY_PATH"))
344             .split(QLatin1Char(':'), QString::SkipEmptyParts);
345 #  endif
346     paths << QLatin1String("/lib") << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib");
347
348     QStringList foundSsls;
349     foreach (const QString &path, paths) {
350         QDir dir = QDir(path);
351         QStringList entryList = dir.entryList(QStringList() << QLatin1String("libssl.*"), QDir::Files);
352
353         qSort(entryList.begin(), entryList.end(), libGreaterThan);
354         foreach (const QString &entry, entryList)
355             foundSsls << path + QLatin1Char('/') + entry;
356     }
357
358     return foundSsls;
359 }
360 # endif
361
362 #ifdef Q_OS_WIN
363 static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
364 {
365     QPair<QSystemLibrary*,QSystemLibrary*> pair;
366     pair.first = 0;
367     pair.second = 0;
368
369     QSystemLibrary *ssleay32 = new QSystemLibrary(QLatin1String("ssleay32"));
370     if (!ssleay32->load(false)) {
371         // Cannot find ssleay32.dll
372         delete ssleay32;
373         return pair;
374     }
375
376     QSystemLibrary *libeay32 = new QSystemLibrary(QLatin1String("libeay32"));
377     if (!libeay32->load(false)) {
378         delete ssleay32;
379         delete libeay32;
380         return pair;
381     }
382
383     pair.first = ssleay32;
384     pair.second = libeay32;
385     return pair;
386 }
387 #else
388
389 static QPair<QLibrary*, QLibrary*> loadOpenSsl()
390 {
391     QPair<QLibrary*,QLibrary*> pair;
392     pair.first = 0;
393     pair.second = 0;
394
395 # if defined(Q_OS_SYMBIAN)
396      QLibrary *libssl = new QLibrary(QLatin1String("libssl"));
397     if (!libssl->load()) {
398         // Cannot find ssleay32.dll
399         delete libssl;
400         return pair;
401     }
402
403     QLibrary *libcrypto = new QLibrary(QLatin1String("libcrypto"));
404     if (!libcrypto->load()) {
405         delete libcrypto;
406         delete libssl;
407         return pair;
408     }
409
410     pair.first = libssl;
411     pair.second = libcrypto;
412     return pair;
413 # elif defined(Q_OS_UNIX)
414     QLibrary *&libssl = pair.first;
415     QLibrary *&libcrypto = pair.second;
416     libssl = new QLibrary;
417     libcrypto = new QLibrary;
418
419     // Try to find the libssl library on the system.
420     //
421     // Up until Qt 4.3, this only searched for the "ssl" library at version -1, that
422     // is, libssl.so on most Unix systems.  However, the .so file isn't present in
423     // user installations because it's considered a development file.
424     //
425     // The right thing to do is to load the library at the major version we know how
426     // to work with: the SHLIB_VERSION_NUMBER version (macro defined in opensslv.h)
427     //
428     // However, OpenSSL is a well-known case of binary-compatibility breakage. To
429     // avoid such problems, many system integrators and Linux distributions change
430     // the soname of the binary, letting the full version number be the soname. So
431     // we'll find libssl.so.0.9.7, libssl.so.0.9.8, etc. in the system. For that
432     // reason, we will search a few common paths (see findAllLibSsl() above) in hopes
433     // we find one that works.
434     //
435     // It is important, however, to try the canonical name and the unversioned name
436     // without going through the loop. By not specifying a path, we let the system
437     // dlopen(3) function determine it for us. This will include any DT_RUNPATH or
438     // DT_RPATH tags on our library header as well as other system-specific search
439     // paths. See the man page for dlopen(3) on your system for more information.
440
441 #ifdef Q_OS_OPENBSD
442     libcrypto->setLoadHints(QLibrary::ExportExternalSymbolsHint);
443 #endif
444 #ifdef SHLIB_VERSION_NUMBER
445     // first attempt: the canonical name is libssl.so.<SHLIB_VERSION_NUMBER>
446     libssl->setFileNameAndVersion(QLatin1String("ssl"), QLatin1String(SHLIB_VERSION_NUMBER));
447     libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String(SHLIB_VERSION_NUMBER));
448     if (libcrypto->load() && libssl->load()) {
449         // libssl.so.<SHLIB_VERSION_NUMBER> and libcrypto.so.<SHLIB_VERSION_NUMBER> found
450         return pair;
451     } else {
452         libssl->unload();
453         libcrypto->unload();
454     }
455 #endif
456
457     // second attempt: find the development files libssl.so and libcrypto.so
458     libssl->setFileNameAndVersion(QLatin1String("ssl"), -1);
459     libcrypto->setFileNameAndVersion(QLatin1String("crypto"), -1);
460     if (libcrypto->load() && libssl->load()) {
461         // libssl.so.0 and libcrypto.so.0 found
462         return pair;
463     } else {
464         libssl->unload();
465         libcrypto->unload();
466     }
467
468     // third attempt: loop on the most common library paths and find libssl
469     QStringList sslList = findAllLibSsl();
470     foreach (const QString &ssl, sslList) {
471         QString crypto = ssl;
472         crypto.replace(QLatin1String("ssl"), QLatin1String("crypto"));
473         libssl->setFileNameAndVersion(ssl, -1);
474         libcrypto->setFileNameAndVersion(crypto, -1);
475         if (libcrypto->load() && libssl->load()) {
476             // libssl.so.0 and libcrypto.so.0 found
477             return pair;
478         } else {
479             libssl->unload();
480             libcrypto->unload();
481         }
482     }
483
484     // failed to load anything
485     delete libssl;
486     delete libcrypto;
487     libssl = libcrypto = 0;
488     return pair;
489
490 # else
491     // not implemented for this platform yet
492     return pair;
493 # endif
494 }
495 #endif
496
497 bool q_resolveOpenSslSymbols()
498 {
499     static volatile bool symbolsResolved = false;
500     static volatile bool triedToResolveSymbols = false;
501 #ifndef QT_NO_THREAD
502     QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_SSL_library_init));
503 #endif
504     if (symbolsResolved)
505         return true;
506     if (triedToResolveSymbols)
507         return false;
508     triedToResolveSymbols = true;
509
510 #ifdef Q_OS_WIN
511     QPair<QSystemLibrary *, QSystemLibrary *> libs = loadOpenSslWin32();
512 #else
513     QPair<QLibrary *, QLibrary *> libs = loadOpenSsl();
514 #endif
515     if (!libs.first || !libs.second)
516         // failed to load them
517         return false;
518
519 #ifdef Q_OS_SYMBIAN
520 #ifdef SSLEAY_MACROS
521     RESOLVEFUNC(ASN1_dup, 125, libs.second )
522 #endif
523     RESOLVEFUNC(ASN1_INTEGER_get, 48, libs.second )
524     RESOLVEFUNC(ASN1_STRING_data, 71, libs.second )
525     RESOLVEFUNC(ASN1_STRING_length, 76, libs.second )
526     RESOLVEFUNC(ASN1_STRING_to_UTF8, 86, libs.second )
527     RESOLVEFUNC(BIO_ctrl, 184, libs.second )
528     RESOLVEFUNC(BIO_free, 209, libs.second )
529     RESOLVEFUNC(BIO_new, 222, libs.second )
530     RESOLVEFUNC(BIO_new_mem_buf, 230, libs.second )
531     RESOLVEFUNC(BIO_read, 244, libs.second )
532     RESOLVEFUNC(BIO_s_mem, 251, libs.second )
533     RESOLVEFUNC(BIO_write, 269, libs.second )
534     RESOLVEFUNC(BN_num_bits, 387, libs.second )
535     RESOLVEFUNC(CRYPTO_free, 469, libs.second )
536     RESOLVEFUNC(CRYPTO_num_locks, 500, libs.second )
537     RESOLVEFUNC(CRYPTO_set_id_callback, 513, libs.second )
538     RESOLVEFUNC(CRYPTO_set_locking_callback, 516, libs.second )
539     RESOLVEFUNC(DSA_free, 594, libs.second )
540     RESOLVEFUNC(ERR_error_string, 744, libs.second )
541     RESOLVEFUNC(ERR_get_error, 749, libs.second )
542     RESOLVEFUNC(EVP_des_ede3_cbc, 919, libs.second )
543     RESOLVEFUNC(EVP_PKEY_assign, 859, libs.second )
544     RESOLVEFUNC(EVP_PKEY_set1_RSA, 880, libs.second )
545     RESOLVEFUNC(EVP_PKEY_set1_DSA, 879, libs.second )
546     RESOLVEFUNC(EVP_PKEY_free, 867, libs.second )
547     RESOLVEFUNC(EVP_PKEY_get1_DSA, 869, libs.second )
548     RESOLVEFUNC(EVP_PKEY_get1_RSA, 870, libs.second )
549     RESOLVEFUNC(EVP_PKEY_new, 876, libs.second )
550     RESOLVEFUNC(EVP_PKEY_type, 882, libs.second )
551     RESOLVEFUNC(OBJ_nid2sn, 1036, libs.second )
552     RESOLVEFUNC(OBJ_obj2nid, 1037, libs.second )
553 #ifdef SSLEAY_MACROS // ### verify
554     RESOLVEFUNC(PEM_ASN1_read_bio, 1180, libs.second )
555 #else
556     RESOLVEFUNC(PEM_read_bio_DSAPrivateKey, 1219, libs.second )
557     RESOLVEFUNC(PEM_read_bio_RSAPrivateKey, 1228, libs.second )
558     RESOLVEFUNC(PEM_write_bio_DSAPrivateKey, 1260, libs.second )
559     RESOLVEFUNC(PEM_write_bio_RSAPrivateKey, 1271, libs.second )
560 #endif
561     RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY, 1220, libs.second )
562     RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY, 1230, libs.second )
563     RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY, 1261, libs.second )
564     RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY, 1273, libs.second )
565     RESOLVEFUNC(RAND_seed, 1426, libs.second )
566     RESOLVEFUNC(RAND_status, 1429, libs.second )
567     RESOLVEFUNC(RSA_free, 1450, libs.second )
568     RESOLVEFUNC(sk_free, 2571, libs.second )
569     RESOLVEFUNC(sk_num, 2576, libs.second )
570     RESOLVEFUNC(sk_pop_free, 2578, libs.second )    
571     RESOLVEFUNC(sk_value, 2585, libs.second )
572     RESOLVEFUNC(SSL_CIPHER_description, 11, libs.first )
573     RESOLVEFUNC(SSL_CTX_check_private_key, 21, libs.first )
574     RESOLVEFUNC(SSL_CTX_ctrl, 22, libs.first )
575     RESOLVEFUNC(SSL_CTX_free, 24, libs.first )
576     RESOLVEFUNC(SSL_CTX_new, 35, libs.first )
577     RESOLVEFUNC(SSL_CTX_set_cipher_list, 40, libs.first )
578     RESOLVEFUNC(SSL_CTX_set_default_verify_paths, 44, libs.first )
579     RESOLVEFUNC(SSL_CTX_set_verify, 56, libs.first )
580     RESOLVEFUNC(SSL_CTX_set_verify_depth, 57, libs.first )
581     RESOLVEFUNC(SSL_CTX_use_certificate, 64, libs.first )
582     RESOLVEFUNC(SSL_CTX_use_certificate_file, 67, libs.first )
583     RESOLVEFUNC(SSL_CTX_use_PrivateKey, 58, libs.first )
584     RESOLVEFUNC(SSL_CTX_use_RSAPrivateKey, 61, libs.first )
585     RESOLVEFUNC(SSL_CTX_use_PrivateKey_file, 60, libs.first )
586     RESOLVEFUNC(SSL_accept, 82, libs.first )
587     RESOLVEFUNC(SSL_clear, 92, libs.first )
588     RESOLVEFUNC(SSL_connect, 93, libs.first )
589     RESOLVEFUNC(SSL_free, 99, libs.first )
590     RESOLVEFUNC(SSL_get_ciphers, 104, libs.first )
591     RESOLVEFUNC(SSL_get_current_cipher, 106, libs.first )
592     RESOLVEFUNC(SSL_get_error, 110, libs.first )
593     RESOLVEFUNC(SSL_get_peer_cert_chain, 117, libs.first )
594     RESOLVEFUNC(SSL_get_peer_certificate, 118, libs.first )
595     RESOLVEFUNC(SSL_get_verify_result, 132, libs.first )
596     RESOLVEFUNC(SSL_library_init, 137, libs.first )
597     RESOLVEFUNC(SSL_load_error_strings, 139, libs.first )
598     RESOLVEFUNC(SSL_new, 140, libs.first )
599 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
600     RESOLVEFUNC(SSL_ctrl, 95, libs.first )
601 #endif
602     RESOLVEFUNC(SSL_read, 143, libs.first )
603     RESOLVEFUNC(SSL_set_accept_state, 148, libs.first )
604     RESOLVEFUNC(SSL_set_bio, 149, libs.first )
605     RESOLVEFUNC(SSL_set_connect_state, 152, libs.first )
606     RESOLVEFUNC(SSL_shutdown, 173, libs.first )
607     RESOLVEFUNC(SSL_write, 188, libs.first )
608     RESOLVEFUNC(SSLv2_client_method, 192, libs.first )
609     RESOLVEFUNC(SSLv3_client_method, 195, libs.first )
610     RESOLVEFUNC(SSLv23_client_method, 189, libs.first )
611     RESOLVEFUNC(TLSv1_client_method, 198, libs.first )
612     RESOLVEFUNC(SSLv2_server_method, 194, libs.first )
613     RESOLVEFUNC(SSLv3_server_method, 197, libs.first )
614     RESOLVEFUNC(SSLv23_server_method, 191, libs.first )
615     RESOLVEFUNC(TLSv1_server_method, 200, libs.first )
616     RESOLVEFUNC(SSL_CTX_load_verify_locations, 34, libs.first )
617     RESOLVEFUNC(X509_NAME_entry_count, 1821, libs.second )
618     RESOLVEFUNC(X509_NAME_get_entry, 1823, libs.second )
619     RESOLVEFUNC(X509_NAME_ENTRY_get_data, 1808, libs.second )
620     RESOLVEFUNC(X509_NAME_ENTRY_get_object, 1809, libs.second )
621     RESOLVEFUNC(X509_PUBKEY_get, 1844, libs.second )
622     RESOLVEFUNC(X509_STORE_free, 1939, libs.second )
623     RESOLVEFUNC(X509_STORE_new, 1942, libs.second )
624     RESOLVEFUNC(X509_STORE_add_cert, 1936, libs.second )
625     RESOLVEFUNC(X509_STORE_CTX_free, 1907, libs.second )
626     RESOLVEFUNC(X509_STORE_CTX_init, 1919, libs.second )
627     RESOLVEFUNC(X509_STORE_CTX_new, 1920, libs.second )
628     RESOLVEFUNC(X509_STORE_CTX_set_purpose, 1931, libs.second )
629     RESOLVEFUNC(X509_cmp, 1992, libs.second )
630 #ifndef SSLEAY_MACROS
631     RESOLVEFUNC(X509_dup, 1997, libs.second )
632 #endif
633     RESOLVEFUNC(X509_EXTENSION_get_object, 1785, libs.second )
634     RESOLVEFUNC(X509_free, 2001, libs.second )
635     RESOLVEFUNC(X509_get_ext, 2012, libs.second )
636     RESOLVEFUNC(X509_get_ext_count, 2016, libs.second )
637     RESOLVEFUNC(X509_get_ext_d2i, 2017, libs.second )
638     RESOLVEFUNC(X509_get_issuer_name, 2018, libs.second )
639     RESOLVEFUNC(X509_get_subject_name, 2022, libs.second )
640     RESOLVEFUNC(X509_verify_cert, 2069, libs.second )
641     RESOLVEFUNC(d2i_X509, 2309, libs.second )
642     RESOLVEFUNC(i2d_X509, 2489, libs.second )
643 #ifdef SSLEAY_MACROS
644     RESOLVEFUNC(i2d_DSAPrivateKey, 2395, libs.second )
645     RESOLVEFUNC(i2d_RSAPrivateKey, 2476, libs.second )
646     RESOLVEFUNC(d2i_DSAPrivateKey, 2220, libs.second )
647     RESOLVEFUNC(d2i_RSAPrivateKey, 2296, libs.second )
648 #endif
649     RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf, 1153, libs.second )
650     RESOLVEFUNC(OPENSSL_add_all_algorithms_conf, 1152, libs.second )
651     RESOLVEFUNC(SSLeay, 1504, libs.second )
652 #else // Q_OS_SYMBIAN
653 #ifdef SSLEAY_MACROS
654     RESOLVEFUNC(ASN1_dup)
655 #endif
656     RESOLVEFUNC(ASN1_INTEGER_get)
657     RESOLVEFUNC(ASN1_STRING_data)
658     RESOLVEFUNC(ASN1_STRING_length)
659     RESOLVEFUNC(ASN1_STRING_to_UTF8)
660     RESOLVEFUNC(BIO_ctrl)
661     RESOLVEFUNC(BIO_free)
662     RESOLVEFUNC(BIO_new)
663     RESOLVEFUNC(BIO_new_mem_buf)
664     RESOLVEFUNC(BIO_read)
665     RESOLVEFUNC(BIO_s_mem)
666     RESOLVEFUNC(BIO_write)
667     RESOLVEFUNC(BN_num_bits)
668     RESOLVEFUNC(CRYPTO_free)
669     RESOLVEFUNC(CRYPTO_num_locks)
670     RESOLVEFUNC(CRYPTO_set_id_callback)
671     RESOLVEFUNC(CRYPTO_set_locking_callback)
672     RESOLVEFUNC(DSA_free)
673     RESOLVEFUNC(ERR_error_string)
674     RESOLVEFUNC(ERR_get_error)
675     RESOLVEFUNC(EVP_des_ede3_cbc)
676     RESOLVEFUNC(EVP_PKEY_assign)
677     RESOLVEFUNC(EVP_PKEY_set1_RSA)
678     RESOLVEFUNC(EVP_PKEY_set1_DSA)
679     RESOLVEFUNC(EVP_PKEY_free)
680     RESOLVEFUNC(EVP_PKEY_get1_DSA)
681     RESOLVEFUNC(EVP_PKEY_get1_RSA)
682     RESOLVEFUNC(EVP_PKEY_new)
683     RESOLVEFUNC(EVP_PKEY_type)
684     RESOLVEFUNC(OBJ_nid2sn)
685     RESOLVEFUNC(OBJ_obj2nid)
686 #ifdef SSLEAY_MACROS // ### verify
687     RESOLVEFUNC(PEM_ASN1_read_bio)
688 #else
689     RESOLVEFUNC(PEM_read_bio_DSAPrivateKey)
690     RESOLVEFUNC(PEM_read_bio_RSAPrivateKey)
691     RESOLVEFUNC(PEM_write_bio_DSAPrivateKey)
692     RESOLVEFUNC(PEM_write_bio_RSAPrivateKey)
693 #endif
694     RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY)
695     RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY)
696     RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY)
697     RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY)
698     RESOLVEFUNC(RAND_seed)
699     RESOLVEFUNC(RAND_status)
700     RESOLVEFUNC(RSA_free)
701     RESOLVEFUNC(sk_free)
702     RESOLVEFUNC(sk_num)
703     RESOLVEFUNC(sk_pop_free)
704     RESOLVEFUNC(sk_value)
705     RESOLVEFUNC(SSL_CIPHER_description)
706     RESOLVEFUNC(SSL_CTX_check_private_key)
707     RESOLVEFUNC(SSL_CTX_ctrl)
708     RESOLVEFUNC(SSL_CTX_free)
709     RESOLVEFUNC(SSL_CTX_new)
710     RESOLVEFUNC(SSL_CTX_set_cipher_list)
711     RESOLVEFUNC(SSL_CTX_set_default_verify_paths)
712     RESOLVEFUNC(SSL_CTX_set_verify)
713     RESOLVEFUNC(SSL_CTX_set_verify_depth)
714     RESOLVEFUNC(SSL_CTX_use_certificate)
715     RESOLVEFUNC(SSL_CTX_use_certificate_file)
716     RESOLVEFUNC(SSL_CTX_use_PrivateKey)
717     RESOLVEFUNC(SSL_CTX_use_RSAPrivateKey)
718     RESOLVEFUNC(SSL_CTX_use_PrivateKey_file)
719     RESOLVEFUNC(SSL_accept)
720     RESOLVEFUNC(SSL_clear)
721     RESOLVEFUNC(SSL_connect)
722     RESOLVEFUNC(SSL_free)
723     RESOLVEFUNC(SSL_get_ciphers)
724     RESOLVEFUNC(SSL_get_current_cipher)
725     RESOLVEFUNC(SSL_get_error)
726     RESOLVEFUNC(SSL_get_peer_cert_chain)
727     RESOLVEFUNC(SSL_get_peer_certificate)
728     RESOLVEFUNC(SSL_get_verify_result)
729     RESOLVEFUNC(SSL_library_init)
730     RESOLVEFUNC(SSL_load_error_strings)
731     RESOLVEFUNC(SSL_new)
732 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
733     RESOLVEFUNC(SSL_ctrl)
734 #endif
735     RESOLVEFUNC(SSL_read)
736     RESOLVEFUNC(SSL_set_accept_state)
737     RESOLVEFUNC(SSL_set_bio)
738     RESOLVEFUNC(SSL_set_connect_state)
739     RESOLVEFUNC(SSL_shutdown)
740     RESOLVEFUNC(SSL_write)
741     RESOLVEFUNC(SSLv2_client_method)
742     RESOLVEFUNC(SSLv3_client_method)
743     RESOLVEFUNC(SSLv23_client_method)
744     RESOLVEFUNC(TLSv1_client_method)
745     RESOLVEFUNC(SSLv2_server_method)
746     RESOLVEFUNC(SSLv3_server_method)
747     RESOLVEFUNC(SSLv23_server_method)
748     RESOLVEFUNC(TLSv1_server_method)
749     RESOLVEFUNC(X509_NAME_entry_count)
750     RESOLVEFUNC(X509_NAME_get_entry)
751     RESOLVEFUNC(X509_NAME_ENTRY_get_data)
752     RESOLVEFUNC(X509_NAME_ENTRY_get_object)
753     RESOLVEFUNC(X509_PUBKEY_get)
754     RESOLVEFUNC(X509_STORE_free)
755     RESOLVEFUNC(X509_STORE_new)
756     RESOLVEFUNC(X509_STORE_add_cert)
757     RESOLVEFUNC(X509_STORE_CTX_free)
758     RESOLVEFUNC(X509_STORE_CTX_init)
759     RESOLVEFUNC(X509_STORE_CTX_new)
760     RESOLVEFUNC(X509_STORE_CTX_set_purpose)
761     RESOLVEFUNC(X509_cmp)
762 #ifndef SSLEAY_MACROS
763     RESOLVEFUNC(X509_dup)
764 #endif
765     RESOLVEFUNC(X509_print)
766     RESOLVEFUNC(X509_EXTENSION_get_object)
767     RESOLVEFUNC(X509_free)
768     RESOLVEFUNC(X509_get_ext)
769     RESOLVEFUNC(X509_get_ext_count)
770     RESOLVEFUNC(X509_get_ext_d2i)
771     RESOLVEFUNC(X509_get_issuer_name)
772     RESOLVEFUNC(X509_get_subject_name)
773     RESOLVEFUNC(X509_verify_cert)
774     RESOLVEFUNC(d2i_X509)
775     RESOLVEFUNC(i2d_X509)
776 #ifdef SSLEAY_MACROS
777     RESOLVEFUNC(i2d_DSAPrivateKey)
778     RESOLVEFUNC(i2d_RSAPrivateKey)
779     RESOLVEFUNC(d2i_DSAPrivateKey)
780     RESOLVEFUNC(d2i_RSAPrivateKey)
781 #endif
782     RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf)
783     RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
784     RESOLVEFUNC(SSL_CTX_load_verify_locations)
785     RESOLVEFUNC(SSLeay)
786 #endif // Q_OS_SYMBIAN
787     symbolsResolved = true;
788     delete libs.first;
789     delete libs.second;
790     return true;
791 }
792 #endif // QT_NO_LIBRARY
793
794 #else // !defined QT_LINKED_OPENSSL
795
796 bool q_resolveOpenSslSymbols()
797 {
798 #ifdef QT_NO_OPENSSL
799     return false;
800 #endif
801     return true;
802 }
803 #endif // !defined QT_LINKED_OPENSSL
804
805 //==============================================================================
806 // contributed by Jay Case of Sarvega, Inc.; http://sarvega.com/
807 // Based on X509_cmp_time() for intitial buffer hacking.
808 //==============================================================================
809 QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime)
810 {
811     size_t lTimeLength = aTime->length;
812     char *pString = (char *) aTime->data;
813
814     if (aTime->type == V_ASN1_UTCTIME) {
815
816         char lBuffer[24];
817         char *pBuffer = lBuffer;
818
819         if ((lTimeLength < 11) || (lTimeLength > 17))
820             return QDateTime();
821
822         memcpy(pBuffer, pString, 10);
823         pBuffer += 10;
824         pString += 10;
825
826         if ((*pString == 'Z') || (*pString == '-') || (*pString == '+')) {
827             *pBuffer++ = '0';
828             *pBuffer++ = '0';
829         } else {
830             *pBuffer++ = *pString++;
831             *pBuffer++ = *pString++;
832             // Skip any fractional seconds...
833             if (*pString == '.') {
834                 pString++;
835                 while ((*pString >= '0') && (*pString <= '9'))
836                     pString++;
837             }
838         }
839
840         *pBuffer++ = 'Z';
841         *pBuffer++ = '\0';
842
843         time_t lSecondsFromUCT;
844         if (*pString == 'Z') {
845             lSecondsFromUCT = 0;
846         } else {
847             if ((*pString != '+') && (*pString != '-'))
848                 return QDateTime();
849
850             lSecondsFromUCT = ((pString[1] - '0') * 10 + (pString[2] - '0')) * 60;
851             lSecondsFromUCT += (pString[3] - '0') * 10 + (pString[4] - '0');
852             lSecondsFromUCT *= 60;
853             if (*pString == '-')
854                 lSecondsFromUCT = -lSecondsFromUCT;
855         }
856
857         tm lTime;
858         lTime.tm_sec = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
859         lTime.tm_min = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
860         lTime.tm_hour = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
861         lTime.tm_mday = ((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0');
862         lTime.tm_mon = (((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0')) - 1;
863         lTime.tm_year = ((lBuffer[0] - '0') * 10) + (lBuffer[1] - '0');
864         if (lTime.tm_year < 50)
865             lTime.tm_year += 100; // RFC 2459
866
867         QDate resDate(lTime.tm_year + 1900, lTime.tm_mon + 1, lTime.tm_mday);
868         QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec);
869
870         QDateTime result(resDate, resTime, Qt::UTC);
871         result = result.addSecs(lSecondsFromUCT);
872         return result;
873
874     } else if (aTime->type == V_ASN1_GENERALIZEDTIME) {
875
876         if (lTimeLength < 15)
877             return QDateTime(); // hopefully never triggered
878
879         // generalized time is always YYYYMMDDHHMMSSZ (RFC 2459, section 4.1.2.5.2)
880         tm lTime;
881         lTime.tm_sec = ((pString[12] - '0') * 10) + (pString[13] - '0');
882         lTime.tm_min = ((pString[10] - '0') * 10) + (pString[11] - '0');
883         lTime.tm_hour = ((pString[8] - '0') * 10) + (pString[9] - '0');
884         lTime.tm_mday = ((pString[6] - '0') * 10) + (pString[7] - '0');
885         lTime.tm_mon = (((pString[4] - '0') * 10) + (pString[5] - '0'));
886         lTime.tm_year = ((pString[0] - '0') * 1000) + ((pString[1] - '0') * 100) +
887                         ((pString[2] - '0') * 10) + (pString[3] - '0');
888
889         QDate resDate(lTime.tm_year, lTime.tm_mon, lTime.tm_mday);
890         QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec);
891
892         QDateTime result(resDate, resTime, Qt::UTC);
893         return result;
894
895     } else {
896         qWarning("unsupported date format detected");
897         return QDateTime();
898     }
899
900 }
901
902 QT_END_NAMESPACE