1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtNetwork module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
43 #include "qsslsocket_openssl_symbols_p.h"
46 # include <private/qsystemlibrary_p.h>
48 # include <QtCore/qlibrary.h>
50 #include <QtCore/qmutex.h>
51 #include <private/qmutexpool_p.h>
52 #include <QtCore/qdatetime.h>
53 #if defined(Q_OS_UNIX)
54 #include <QtCore/qdir.h>
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.
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.
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.
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
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.
99 DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, return 0, return)
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)
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)
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)
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)
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)
159 DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG)
160 DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return 0, return)
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)
170 DEFINEFUNC(int, SSL_CTX_check_private_key, SSL_CTX *a, a, return -1, return)
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)
177 DEFINEFUNC(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a, a, return 0, return)
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)
193 DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, SSL *a, a, return 0, return)
195 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
196 DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
198 DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
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)
207 DEFINEFUNC(long, SSL_get_verify_result, SSL *a, a, return -1, return)
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)
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)
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)
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)
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)
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)
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)
277 #define RESOLVEFUNC(func, ordinal, lib) \
278 if (!(_q_##func = _q_PTR_##func(lib->resolve(#ordinal)))) \
279 qWarning("QSslSocket: cannot resolve "#func);
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);
287 #if !defined QT_LINKED_OPENSSL
290 bool q_resolveOpenSslSymbols()
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 "
302 static bool libGreaterThan(const QString &lhs, const QString &rhs)
304 QStringList lhsparts = lhs.split(QLatin1Char('.'));
305 QStringList rhsparts = rhs.split(QLatin1Char('.'));
306 Q_ASSERT(lhsparts.count() > 1 && rhsparts.count() > 1);
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
315 int a = lhsparts.at(i).toInt(&ok);
317 b = rhsparts.at(i).toInt(&ok);
319 // both toInt succeeded
324 // compare as strings;
325 if (lhsparts.at(i) == rhsparts.at(i))
327 return lhsparts.at(i) > rhsparts.at(i);
331 // they compared strictly equally so far
332 // lhs cannot be less than rhs
336 static QStringList findAllLibSsl()
340 paths = QString::fromLatin1(qgetenv("DYLD_LIBRARY_PATH"))
341 .split(QLatin1Char(':'), QString::SkipEmptyParts);
343 paths = QString::fromLatin1(qgetenv("LD_LIBRARY_PATH"))
344 .split(QLatin1Char(':'), QString::SkipEmptyParts);
346 paths << QLatin1String("/lib") << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib");
348 QStringList foundSsls;
349 foreach (const QString &path, paths) {
350 QDir dir = QDir(path);
351 QStringList entryList = dir.entryList(QStringList() << QLatin1String("libssl.*"), QDir::Files);
353 qSort(entryList.begin(), entryList.end(), libGreaterThan);
354 foreach (const QString &entry, entryList)
355 foundSsls << path + QLatin1Char('/') + entry;
363 static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
365 QPair<QSystemLibrary*,QSystemLibrary*> pair;
369 QSystemLibrary *ssleay32 = new QSystemLibrary(QLatin1String("ssleay32"));
370 if (!ssleay32->load(false)) {
371 // Cannot find ssleay32.dll
376 QSystemLibrary *libeay32 = new QSystemLibrary(QLatin1String("libeay32"));
377 if (!libeay32->load(false)) {
383 pair.first = ssleay32;
384 pair.second = libeay32;
389 static QPair<QLibrary*, QLibrary*> loadOpenSsl()
391 QPair<QLibrary*,QLibrary*> pair;
395 # if defined(Q_OS_SYMBIAN)
396 QLibrary *libssl = new QLibrary(QLatin1String("libssl"));
397 if (!libssl->load()) {
398 // Cannot find ssleay32.dll
403 QLibrary *libcrypto = new QLibrary(QLatin1String("libcrypto"));
404 if (!libcrypto->load()) {
411 pair.second = libcrypto;
413 # elif defined(Q_OS_UNIX)
414 QLibrary *&libssl = pair.first;
415 QLibrary *&libcrypto = pair.second;
416 libssl = new QLibrary;
417 libcrypto = new QLibrary;
419 // Try to find the libssl library on the system.
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.
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)
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.
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.
442 libcrypto->setLoadHints(QLibrary::ExportExternalSymbolsHint);
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
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
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
484 // failed to load anything
487 libssl = libcrypto = 0;
491 // not implemented for this platform yet
497 bool q_resolveOpenSslSymbols()
499 static volatile bool symbolsResolved = false;
500 static volatile bool triedToResolveSymbols = false;
502 QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_SSL_library_init));
506 if (triedToResolveSymbols)
508 triedToResolveSymbols = true;
511 QPair<QSystemLibrary *, QSystemLibrary *> libs = loadOpenSslWin32();
513 QPair<QLibrary *, QLibrary *> libs = loadOpenSsl();
515 if (!libs.first || !libs.second)
516 // failed to load them
521 RESOLVEFUNC(ASN1_dup, 125, libs.second )
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 )
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 )
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 )
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 )
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 )
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 )
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
654 RESOLVEFUNC(ASN1_dup)
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)
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)
689 RESOLVEFUNC(PEM_read_bio_DSAPrivateKey)
690 RESOLVEFUNC(PEM_read_bio_RSAPrivateKey)
691 RESOLVEFUNC(PEM_write_bio_DSAPrivateKey)
692 RESOLVEFUNC(PEM_write_bio_RSAPrivateKey)
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)
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)
732 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
733 RESOLVEFUNC(SSL_ctrl)
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)
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)
777 RESOLVEFUNC(i2d_DSAPrivateKey)
778 RESOLVEFUNC(i2d_RSAPrivateKey)
779 RESOLVEFUNC(d2i_DSAPrivateKey)
780 RESOLVEFUNC(d2i_RSAPrivateKey)
782 RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf)
783 RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
784 RESOLVEFUNC(SSL_CTX_load_verify_locations)
786 #endif // Q_OS_SYMBIAN
787 symbolsResolved = true;
792 #endif // QT_NO_LIBRARY
794 #else // !defined QT_LINKED_OPENSSL
796 bool q_resolveOpenSslSymbols()
803 #endif // !defined QT_LINKED_OPENSSL
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)
811 size_t lTimeLength = aTime->length;
812 char *pString = (char *) aTime->data;
814 if (aTime->type == V_ASN1_UTCTIME) {
817 char *pBuffer = lBuffer;
819 if ((lTimeLength < 11) || (lTimeLength > 17))
822 memcpy(pBuffer, pString, 10);
826 if ((*pString == 'Z') || (*pString == '-') || (*pString == '+')) {
830 *pBuffer++ = *pString++;
831 *pBuffer++ = *pString++;
832 // Skip any fractional seconds...
833 if (*pString == '.') {
835 while ((*pString >= '0') && (*pString <= '9'))
843 time_t lSecondsFromUCT;
844 if (*pString == 'Z') {
847 if ((*pString != '+') && (*pString != '-'))
850 lSecondsFromUCT = ((pString[1] - '0') * 10 + (pString[2] - '0')) * 60;
851 lSecondsFromUCT += (pString[3] - '0') * 10 + (pString[4] - '0');
852 lSecondsFromUCT *= 60;
854 lSecondsFromUCT = -lSecondsFromUCT;
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
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);
870 QDateTime result(resDate, resTime, Qt::UTC);
871 result = result.addSecs(lSecondsFromUCT);
874 } else if (aTime->type == V_ASN1_GENERALIZEDTIME) {
876 if (lTimeLength < 15)
877 return QDateTime(); // hopefully never triggered
879 // generalized time is always YYYYMMDDHHMMSSZ (RFC 2459, section 4.1.2.5.2)
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');
889 QDate resDate(lTime.tm_year, lTime.tm_mon, lTime.tm_mday);
890 QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec);
892 QDateTime result(resDate, resTime, Qt::UTC);
896 qWarning("unsupported date format detected");