source: trunk/src/network/ssl/qsslsocket_openssl_symbols.cpp@ 646

Last change on this file since 646 was 561, checked in by Dmitry A. Kuminov, 16 years ago

trunk: Merged in qt 4.6.1 sources.

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