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