eeae9d461fd76f529d79a77050f724d61b8c2fcf
[profile/ivi/qtbase.git] / src / network / ssl / qsslsocket_openssl_symbols.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtNetwork module of the Qt Toolkit.
7 **
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.
16 **
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.
24 **
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.
28 **
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.
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 #ifdef Q_OS_LINUX
57 #include <link.h>
58 #endif
59
60 #include <algorithm>
61
62 QT_BEGIN_NAMESPACE
63
64 /*
65     Note to maintainer:
66     -------------------
67
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.
78
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.
83
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.
88
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
95     for void functions.
96
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.
101 */
102
103 #ifdef SSLEAY_MACROS
104 DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, return 0, return)
105 #endif
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)
127 #endif
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)
145
146 DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return)
147 #ifdef SSLEAY_MACROS
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)
150 #else
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)
155 #endif
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)
170 #else
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)
175 #endif
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)
183 #else
184 DEFINEFUNC(int, SSL_CTX_check_private_key, SSL_CTX *a, a, return -1, return)
185 #endif
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)
190 #else
191 DEFINEFUNC(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a, a, return 0, return)
192 #endif
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)
206 #else
207 DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, SSL *a, a, return 0, return)
208 #endif
209 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
210 DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
211 #else
212 DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
213 #endif
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)
220 #else
221 DEFINEFUNC(long, SSL_get_verify_result, SSL *a, a, return -1, return)
222 #endif
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)
228 #endif
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)
237 #endif
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)
244 #endif
245 #ifndef OPENSSL_NO_SSL2
246 DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
247 #endif
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)
254 #endif
255 #else
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)
264 #endif
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)
269 #endif
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)
298 #ifdef SSLEAY_MACROS
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)
303 #endif
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)
309
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);
314
315 #if !defined QT_LINKED_OPENSSL
316
317 #ifdef QT_NO_LIBRARY
318 bool q_resolveOpenSslSymbols()
319 {
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 "
324              "of libraries.");
325     return false;
326 }
327 #else
328
329 # ifdef Q_OS_UNIX
330 static bool libGreaterThan(const QString &lhs, const QString &rhs)
331 {
332     QStringList lhsparts = lhs.split(QLatin1Char('.'));
333     QStringList rhsparts = rhs.split(QLatin1Char('.'));
334     Q_ASSERT(lhsparts.count() > 1 && rhsparts.count() > 1);
335
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
339             return false;
340
341         bool ok = false;
342         int b = 0;
343         int a = lhsparts.at(i).toInt(&ok);
344         if (ok)
345             b = rhsparts.at(i).toInt(&ok);
346         if (ok) {
347             // both toInt succeeded
348             if (a == b)
349                 continue;
350             return a > b;
351         } else {
352             // compare as strings;
353             if (lhsparts.at(i) == rhsparts.at(i))
354                 continue;
355             return lhsparts.at(i) > rhsparts.at(i);
356         }
357     }
358
359     // they compared strictly equally so far
360     // lhs cannot be less than rhs
361     return true;
362 }
363
364 #ifdef Q_OS_LINUX
365 static int dlIterateCallback(struct dl_phdr_info *info, size_t size, void *data)
366 {
367     if (size < sizeof (info->dlpi_addr) + sizeof (info->dlpi_name))
368         return 1;
369     QSet<QString> *paths = (QSet<QString> *)data;
370     QString path = QString::fromLocal8Bit(info->dlpi_name);
371     if (!path.isEmpty()) {
372         QFileInfo fi(path);
373         path = fi.absolutePath();
374         if (!path.isEmpty())
375             paths->insert(path);
376     }
377     return 0;
378 }
379 #endif
380
381 static QStringList libraryPathList()
382 {
383     QStringList paths;
384 #  ifdef Q_OS_DARWIN
385     paths = QString::fromLatin1(qgetenv("DYLD_LIBRARY_PATH"))
386             .split(QLatin1Char(':'), QString::SkipEmptyParts);
387 #  else
388     paths = QString::fromLatin1(qgetenv("LD_LIBRARY_PATH"))
389             .split(QLatin1Char(':'), QString::SkipEmptyParts);
390 #  endif
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");
394
395 #ifdef Q_OS_LINUX
396     // discover paths of already loaded libraries
397     QSet<QString> loadedPaths;
398     dl_iterate_phdr(dlIterateCallback, &loadedPaths);
399     paths.append(loadedPaths.toList());
400 #endif
401
402     return paths;
403 }
404
405
406 static QStringList findAllLibSsl()
407 {
408     QStringList paths = libraryPathList();
409     QStringList foundSsls;
410
411     foreach (const QString &path, paths) {
412         QDir dir(path);
413         QStringList entryList = dir.entryList(QStringList() << QLatin1String("libssl.*"), QDir::Files);
414
415         std::sort(entryList.begin(), entryList.end(), libGreaterThan);
416         foreach (const QString &entry, entryList)
417             foundSsls << path + QLatin1Char('/') + entry;
418     }
419
420     return foundSsls;
421 }
422
423 static QStringList findAllLibCrypto()
424 {
425     QStringList paths = libraryPathList();
426
427     QStringList foundCryptos;
428     foreach (const QString &path, paths) {
429         QDir dir(path);
430         QStringList entryList = dir.entryList(QStringList() << QLatin1String("libcrypto.*"), QDir::Files);
431
432         std::sort(entryList.begin(), entryList.end(), libGreaterThan);
433         foreach (const QString &entry, entryList)
434             foundCryptos << path + QLatin1Char('/') + entry;
435     }
436
437     return foundCryptos;
438 }
439 # endif
440
441 #ifdef Q_OS_WIN
442 static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
443 {
444     QPair<QSystemLibrary*,QSystemLibrary*> pair;
445     pair.first = 0;
446     pair.second = 0;
447
448     QSystemLibrary *ssleay32 = new QSystemLibrary(QLatin1String("ssleay32"));
449     if (!ssleay32->load(false)) {
450         // Cannot find ssleay32.dll
451         delete ssleay32;
452         return pair;
453     }
454
455     QSystemLibrary *libeay32 = new QSystemLibrary(QLatin1String("libeay32"));
456     if (!libeay32->load(false)) {
457         delete ssleay32;
458         delete libeay32;
459         return pair;
460     }
461
462     pair.first = ssleay32;
463     pair.second = libeay32;
464     return pair;
465 }
466 #else
467
468 static QPair<QLibrary*, QLibrary*> loadOpenSsl()
469 {
470     QPair<QLibrary*,QLibrary*> pair;
471     pair.first = 0;
472     pair.second = 0;
473
474 # if defined(Q_OS_UNIX)
475     QLibrary *&libssl = pair.first;
476     QLibrary *&libcrypto = pair.second;
477     libssl = new QLibrary;
478     libcrypto = new QLibrary;
479
480     // Try to find the libssl library on the system.
481     //
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.
485     //
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)
488     //
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.
495     //
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.
501
502 #ifdef Q_OS_OPENBSD
503     libcrypto->setLoadHints(QLibrary::ExportExternalSymbolsHint);
504 #endif
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
511         return pair;
512     } else {
513         libssl->unload();
514         libcrypto->unload();
515     }
516 #endif
517
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
523         return pair;
524     } else {
525         libssl->unload();
526         libcrypto->unload();
527     }
528
529     // third attempt: loop on the most common library paths and find libssl
530     QStringList sslList = findAllLibSsl();
531     QStringList cryptoList = findAllLibCrypto();
532
533     foreach (const QString &crypto, cryptoList) {
534         libcrypto->setFileNameAndVersion(crypto, -1);
535         if (libcrypto->load()) {
536             QFileInfo fi(crypto);
537             QString version = fi.completeSuffix();
538
539             foreach (const QString &ssl, sslList) {
540                 if (!ssl.endsWith(version))
541                     continue;
542
543                 libssl->setFileNameAndVersion(ssl, -1);
544
545                 if (libssl->load()) {
546                     // libssl.so.x and libcrypto.so.x found
547                     return pair;
548                 } else {
549                     libssl->unload();
550                 }
551             }
552         }
553         libcrypto->unload();
554     }
555
556     // failed to load anything
557     delete libssl;
558     delete libcrypto;
559     libssl = libcrypto = 0;
560     return pair;
561
562 # else
563     // not implemented for this platform yet
564     return pair;
565 # endif
566 }
567 #endif
568
569 bool q_resolveOpenSslSymbols()
570 {
571     static bool symbolsResolved = false;
572     static bool triedToResolveSymbols = false;
573 #ifndef QT_NO_THREAD
574     QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_SSL_library_init));
575 #endif
576     if (symbolsResolved)
577         return true;
578     if (triedToResolveSymbols)
579         return false;
580     triedToResolveSymbols = true;
581
582 #ifdef Q_OS_WIN
583     QPair<QSystemLibrary *, QSystemLibrary *> libs = loadOpenSslWin32();
584 #else
585     QPair<QLibrary *, QLibrary *> libs = loadOpenSsl();
586 #endif
587     if (!libs.first || !libs.second)
588         // failed to load them
589         return false;
590
591 #ifdef SSLEAY_MACROS
592     RESOLVEFUNC(ASN1_dup)
593 #endif
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)
600     RESOLVEFUNC(BIO_new)
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)
630 #else
631     RESOLVEFUNC(PEM_read_bio_DSAPrivateKey)
632     RESOLVEFUNC(PEM_read_bio_RSAPrivateKey)
633     RESOLVEFUNC(PEM_write_bio_DSAPrivateKey)
634     RESOLVEFUNC(PEM_write_bio_RSAPrivateKey)
635 #endif
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)
644     RESOLVEFUNC(sk_push)
645     RESOLVEFUNC(sk_free)
646     RESOLVEFUNC(sk_num)
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)
675     RESOLVEFUNC(SSL_new)
676 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
677     RESOLVEFUNC(SSL_ctrl)
678 #endif
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)
687 #endif
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)
694 #endif
695 #ifndef OPENSSL_NO_SSL2
696     RESOLVEFUNC(SSLv2_server_method)
697 #endif
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)
704 #endif
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)
720 #endif
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)
739 #ifdef SSLEAY_MACROS
740     RESOLVEFUNC(i2d_DSAPrivateKey)
741     RESOLVEFUNC(i2d_RSAPrivateKey)
742     RESOLVEFUNC(d2i_DSAPrivateKey)
743     RESOLVEFUNC(d2i_RSAPrivateKey)
744 #endif
745     RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf)
746     RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
747     RESOLVEFUNC(SSL_CTX_load_verify_locations)
748     RESOLVEFUNC(SSLeay)
749     RESOLVEFUNC(SSLeay_version)
750
751     symbolsResolved = true;
752     delete libs.first;
753     delete libs.second;
754     return true;
755 }
756 #endif // QT_NO_LIBRARY
757
758 #else // !defined QT_LINKED_OPENSSL
759
760 bool q_resolveOpenSslSymbols()
761 {
762 #ifdef QT_NO_OPENSSL
763     return false;
764 #endif
765     return true;
766 }
767 #endif // !defined QT_LINKED_OPENSSL
768
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)
774 {
775     size_t lTimeLength = aTime->length;
776     char *pString = (char *) aTime->data;
777
778     if (aTime->type == V_ASN1_UTCTIME) {
779
780         char lBuffer[24];
781         char *pBuffer = lBuffer;
782
783         if ((lTimeLength < 11) || (lTimeLength > 17))
784             return QDateTime();
785
786         memcpy(pBuffer, pString, 10);
787         pBuffer += 10;
788         pString += 10;
789
790         if ((*pString == 'Z') || (*pString == '-') || (*pString == '+')) {
791             *pBuffer++ = '0';
792             *pBuffer++ = '0';
793         } else {
794             *pBuffer++ = *pString++;
795             *pBuffer++ = *pString++;
796             // Skip any fractional seconds...
797             if (*pString == '.') {
798                 pString++;
799                 while ((*pString >= '0') && (*pString <= '9'))
800                     pString++;
801             }
802         }
803
804         *pBuffer++ = 'Z';
805         *pBuffer++ = '\0';
806
807         time_t lSecondsFromUCT;
808         if (*pString == 'Z') {
809             lSecondsFromUCT = 0;
810         } else {
811             if ((*pString != '+') && (*pString != '-'))
812                 return QDateTime();
813
814             lSecondsFromUCT = ((pString[1] - '0') * 10 + (pString[2] - '0')) * 60;
815             lSecondsFromUCT += (pString[3] - '0') * 10 + (pString[4] - '0');
816             lSecondsFromUCT *= 60;
817             if (*pString == '-')
818                 lSecondsFromUCT = -lSecondsFromUCT;
819         }
820
821         tm lTime;
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
830
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);
833
834         QDateTime result(resDate, resTime, Qt::UTC);
835         result = result.addSecs(lSecondsFromUCT);
836         return result;
837
838     } else if (aTime->type == V_ASN1_GENERALIZEDTIME) {
839
840         if (lTimeLength < 15)
841             return QDateTime(); // hopefully never triggered
842
843         // generalized time is always YYYYMMDDHHMMSSZ (RFC 2459, section 4.1.2.5.2)
844         tm lTime;
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');
852
853         QDate resDate(lTime.tm_year, lTime.tm_mon, lTime.tm_mday);
854         QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec);
855
856         QDateTime result(resDate, resTime, Qt::UTC);
857         return result;
858
859     } else {
860         qWarning("unsupported date format detected");
861         return QDateTime();
862     }
863
864 }
865
866 QT_END_NAMESPACE