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

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

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 27.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtNetwork module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department 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(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return 0, return)
98DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return)
99DEFINEFUNC4(long, BIO_ctrl, BIO *a, a, int b, b, long c, c, void *d, d, return -1, return)
100DEFINEFUNC(int, BIO_free, BIO *a, a, return 0, return)
101DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return 0, return)
102DEFINEFUNC2(BIO *, BIO_new_mem_buf, void *a, a, int b, b, return 0, return)
103DEFINEFUNC3(int, BIO_read, BIO *a, a, void *b, b, int c, c, return -1, return)
104DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return)
105DEFINEFUNC3(int, BIO_write, BIO *a, a, const void *b, b, int c, c, return -1, return)
106DEFINEFUNC(int, BN_num_bits, const BIGNUM *a, a, return 0, return)
107DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return)
108DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG)
109DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG)
110DEFINEFUNC(void, CRYPTO_free, void *a, a, return, DUMMYARG)
111DEFINEFUNC(void, DSA_free, DSA *a, a, return, DUMMYARG)
112#if OPENSSL_VERSION_NUMBER < 0x00908000L
113DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, unsigned char **b, b, long c, c, return 0, return)
114#else // 0.9.8 broke SC and BC by changing this signature.
115DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, const unsigned char **b, b, long c, c, return 0, return)
116#endif
117DEFINEFUNC2(char *, ERR_error_string, unsigned long a, a, char *b, b, return 0, return)
118DEFINEFUNC(unsigned long, ERR_get_error, DUMMYARG, DUMMYARG, return 0, return)
119DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return 0, return)
120DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return)
121DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG)
122DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return 0, return)
123DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return 0, return)
124DEFINEFUNC(EVP_PKEY *, EVP_PKEY_new, DUMMYARG, DUMMYARG, return 0, return)
125DEFINEFUNC(int, EVP_PKEY_type, int a, a, return NID_undef, return)
126DEFINEFUNC2(int, i2d_X509, X509 *a, a, unsigned char **b, b, return -1, return)
127DEFINEFUNC(const char *, OBJ_nid2sn, int a, a, return 0, return)
128DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return)
129#ifdef SSLEAY_MACROS
130DEFINEFUNC6(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)
131DEFINEFUNC6(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)
132#else
133DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
134DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
135DEFINEFUNC7(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)
136DEFINEFUNC7(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)
137#endif
138DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
139DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
140DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, return)
141DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return)
142DEFINEFUNC2(void, RAND_seed, const void *a, a, int b, b, return, DUMMYARG)
143DEFINEFUNC(int, RAND_status, void, DUMMYARG, return -1, return)
144DEFINEFUNC(void, RSA_free, RSA *a, a, return, DUMMYARG)
145DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG)
146DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return)
147DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return 0, return)
148DEFINEFUNC(int, SSL_accept, SSL *a, a, return -1, return)
149DEFINEFUNC(int, SSL_clear, SSL *a, a, return -1, return)
150DEFINEFUNC3(char *, SSL_CIPHER_description, SSL_CIPHER *a, a, char *b, b, int c, c, return 0, return)
151DEFINEFUNC(int, SSL_connect, SSL *a, a, return -1, return)
152#if OPENSSL_VERSION_NUMBER >= 0x00908000L
153// 0.9.8 broke SC and BC by changing this function's signature.
154DEFINEFUNC(int, SSL_CTX_check_private_key, const SSL_CTX *a, a, return -1, return)
155#else
156DEFINEFUNC(int, SSL_CTX_check_private_key, SSL_CTX *a, a, return -1, return)
157#endif
158DEFINEFUNC4(long, SSL_CTX_ctrl, SSL_CTX *a, a, int b, b, long c, c, void *d, d, return -1, return)
159DEFINEFUNC(void, SSL_CTX_free, SSL_CTX *a, a, return, DUMMYARG)
160DEFINEFUNC(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a, a, return 0, return)
161DEFINEFUNC2(int, SSL_CTX_set_cipher_list, SSL_CTX *a, a, const char *b, b, return -1, return)
162DEFINEFUNC(int, SSL_CTX_set_default_verify_paths, SSL_CTX *a, a, return -1, return)
163DEFINEFUNC3(void, SSL_CTX_set_verify, SSL_CTX *a, a, int b, b, int (*c)(int, X509_STORE_CTX *), c, return, DUMMYARG)
164DEFINEFUNC2(void, SSL_CTX_set_verify_depth, SSL_CTX *a, a, int b, b, return, DUMMYARG)
165DEFINEFUNC2(int, SSL_CTX_use_certificate, SSL_CTX *a, a, X509 *b, b, return -1, return)
166DEFINEFUNC3(int, SSL_CTX_use_certificate_file, SSL_CTX *a, a, const char *b, b, int c, c, return -1, return)
167DEFINEFUNC2(int, SSL_CTX_use_PrivateKey, SSL_CTX *a, a, EVP_PKEY *b, b, return -1, return)
168DEFINEFUNC2(int, SSL_CTX_use_RSAPrivateKey, SSL_CTX *a, a, RSA *b, b, return -1, return)
169DEFINEFUNC3(int, SSL_CTX_use_PrivateKey_file, SSL_CTX *a, a, const char *b, b, int c, c, return -1, return)
170DEFINEFUNC(void, SSL_free, SSL *a, a, return, DUMMYARG)
171#if OPENSSL_VERSION_NUMBER >= 0x00908000L
172// 0.9.8 broke SC and BC by changing this function's signature.
173DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, const SSL *a, a, return 0, return)
174#else
175DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, SSL *a, a, return 0, return)
176#endif
177DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
178DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
179DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return 0, return)
180DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return 0, return)
181#if OPENSSL_VERSION_NUMBER >= 0x00908000L
182// 0.9.8 broke SC and BC by changing this function's signature.
183DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
184#else
185DEFINEFUNC(long, SSL_get_verify_result, SSL *a, a, return -1, return)
186#endif
187DEFINEFUNC(int, SSL_library_init, void, DUMMYARG, return -1, return)
188DEFINEFUNC(void, SSL_load_error_strings, void, DUMMYARG, return, DUMMYARG)
189DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return 0, return)
190DEFINEFUNC3(int, SSL_read, SSL *a, a, void *b, b, int c, c, return -1, return)
191DEFINEFUNC3(void, SSL_set_bio, SSL *a, a, BIO *b, b, BIO *c, c, return, DUMMYARG)
192DEFINEFUNC(void, SSL_set_accept_state, SSL *a, a, return, DUMMYARG)
193DEFINEFUNC(void, SSL_set_connect_state, SSL *a, a, return, DUMMYARG)
194DEFINEFUNC(int, SSL_shutdown, SSL *a, a, return -1, return)
195DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
196DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
197DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
198DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
199DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
200DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
201DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
202DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
203DEFINEFUNC3(int, SSL_write, SSL *a, a, const void *b, b, int c, c, return -1, return)
204DEFINEFUNC2(int, X509_cmp, X509 *a, a, X509 *b, b, return -1, return)
205#ifndef SSLEAY_MACROS
206DEFINEFUNC(X509 *, X509_dup, X509 *a, a, return 0, return)
207#endif
208DEFINEFUNC(ASN1_OBJECT *, X509_EXTENSION_get_object, X509_EXTENSION *a, a, return 0, return)
209DEFINEFUNC(void, X509_free, X509 *a, a, return, DUMMYARG)
210DEFINEFUNC2(X509_EXTENSION *, X509_get_ext, X509 *a, a, int b, b, return 0, return)
211DEFINEFUNC(int, X509_get_ext_count, X509 *a, a, return 0, return)
212DEFINEFUNC4(void *, X509_get_ext_d2i, X509 *a, a, int b, b, int *c, c, int *d, d, return 0, return)
213DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return 0, return)
214DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return 0, return)
215DEFINEFUNC(int, X509_verify_cert, X509_STORE_CTX *a, a, return -1, return)
216DEFINEFUNC3(char *, X509_NAME_oneline, X509_NAME *a, a, char *b, b, int c, c, return 0, return)
217DEFINEFUNC(EVP_PKEY *, X509_PUBKEY_get, X509_PUBKEY *a, a, return 0, return)
218DEFINEFUNC(void, X509_STORE_free, X509_STORE *a, a, return, DUMMYARG)
219DEFINEFUNC(X509_STORE *, X509_STORE_new, DUMMYARG, DUMMYARG, return 0, return)
220DEFINEFUNC2(int, X509_STORE_add_cert, X509_STORE *a, a, X509 *b, b, return 0, return)
221DEFINEFUNC(void, X509_STORE_CTX_free, X509_STORE_CTX *a, a, return, DUMMYARG)
222DEFINEFUNC4(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)
223DEFINEFUNC2(int, X509_STORE_CTX_set_purpose, X509_STORE_CTX *a, a, int b, b, return -1, return)
224DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return 0, return)
225#ifdef SSLEAY_MACROS
226DEFINEFUNC2(int, i2d_DSAPrivateKey, const DSA *a, a, unsigned char **b, b, return -1, return)
227DEFINEFUNC2(int, i2d_RSAPrivateKey, const RSA *a, a, unsigned char **b, b, return -1, return)
228DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return 0, return)
229DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return 0, return)
230#endif
231DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG)
232DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG)
233
234#define RESOLVEFUNC(func) \
235 if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \
236 && !(_q_##func = _q_PTR_##func(libs.second->resolve(#func)))) \
237 qWarning("QSslSocket: cannot resolve "#func);
238
239#if !defined QT_LINKED_OPENSSL
240
241#ifdef QT_NO_LIBRARY
242bool q_resolveOpenSslSymbols()
243{
244 qWarning("QSslSocket: unable to resolve symbols. "
245 "QT_NO_LIBRARY is defined which means runtime resolving of "
246 "libraries won't work.");
247 qWarning("Either compile Qt statically or with support for runtime resolving "
248 "of libraries.");
249 return false;
250}
251#else
252
253# ifdef Q_OS_UNIX
254static bool libGreaterThan(const QString &lhs, const QString &rhs)
255{
256 QStringList lhsparts = lhs.split(QLatin1Char('.'));
257 QStringList rhsparts = rhs.split(QLatin1Char('.'));
258 Q_ASSERT(lhsparts.count() > 1 && rhsparts.count() > 1);
259
260 for (int i = 1; i < rhsparts.count(); ++i) {
261 if (lhsparts.count() <= i)
262 // left hand side is shorter, so it's less than rhs
263 return false;
264
265 bool ok = false;
266 int b = 0;
267 int a = lhsparts.at(i).toInt(&ok);
268 if (ok)
269 b = rhsparts.at(i).toInt(&ok);
270 if (ok) {
271 // both toInt succeeded
272 if (a == b)
273 continue;
274 return a > b;
275 } else {
276 // compare as strings;
277 if (lhsparts.at(i) == rhsparts.at(i))
278 continue;
279 return lhsparts.at(i) > rhsparts.at(i);
280 }
281 }
282
283 // they compared strictly equally so far
284 // lhs cannot be less than rhs
285 return true;
286}
287
288static QStringList findAllLibSsl()
289{
290 QStringList paths;
291# ifdef Q_OS_DARWIN
292 paths = QString::fromLatin1(qgetenv("DYLD_LIBRARY_PATH"))
293 .split(QLatin1Char(':'), QString::SkipEmptyParts);
294# else
295 paths = QString::fromLatin1(qgetenv("LD_LIBRARY_PATH"))
296 .split(QLatin1Char(':'), QString::SkipEmptyParts);
297# endif
298 paths << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib");
299
300 QStringList foundSsls;
301 foreach (const QString &path, paths) {
302 QDir dir = QDir(path);
303 QStringList entryList = dir.entryList(QStringList() << QLatin1String("libssl.*"), QDir::Files);
304
305 qSort(entryList.begin(), entryList.end(), libGreaterThan);
306 foreach (const QString &entry, entryList)
307 foundSsls << path + QLatin1Char('/') + entry;
308 }
309
310 return foundSsls;
311}
312# endif
313
314static QPair<QLibrary*, QLibrary*> loadOpenSsl()
315{
316 QPair<QLibrary*,QLibrary*> pair;
317 pair.first = 0;
318 pair.second = 0;
319
320# ifdef Q_OS_WIN
321 QLibrary *ssleay32 = new QLibrary(QLatin1String("ssleay32"));
322 if (!ssleay32->load()) {
323 // Cannot find ssleay32.dll
324 delete ssleay32;
325 return pair;
326 }
327
328 QLibrary *libeay32 = new QLibrary(QLatin1String("libeay32"));
329 if (!libeay32->load()) {
330 delete ssleay32;
331 delete libeay32;
332 return pair;
333 }
334
335 pair.first = ssleay32;
336 pair.second = libeay32;
337 return pair;
338
339# elif defined(Q_OS_UNIX)
340 QLibrary *&libssl = pair.first;
341 QLibrary *&libcrypto = pair.second;
342 libssl = new QLibrary;
343 libcrypto = new QLibrary;
344
345 // Try to find the libssl library on the system.
346 //
347 // Up until Qt 4.3, this only searched for the "ssl" library at version -1, that
348 // is, libssl.so on most Unix systems. However, the .so file isn't present in
349 // user installations because it's considered a development file.
350 //
351 // The right thing to do is to load the library at the major version we know how
352 // to work with: the SHLIB_VERSION_NUMBER version (macro defined in opensslv.h)
353 //
354 // However, OpenSSL is a well-known case of binary-compatibility breakage. To
355 // avoid such problems, many system integrators and Linux distributions change
356 // the soname of the binary, letting the full version number be the soname. So
357 // we'll find libssl.so.0.9.7, libssl.so.0.9.8, etc. in the system. For that
358 // reason, we will search a few common paths (see findAllLibSsl() above) in hopes
359 // we find one that works.
360 //
361 // It is important, however, to try the canonical name and the unversioned name
362 // without going through the loop. By not specifying a path, we let the system
363 // dlopen(3) function determine it for us. This will include any DT_RUNPATH or
364 // DT_RPATH tags on our library header as well as other system-specific search
365 // paths. See the man page for dlopen(3) on your system for more information.
366
367#ifdef SHLIB_VERSION_NUMBER
368 // first attempt: the canonical name is libssl.so.<SHLIB_VERSION_NUMBER>
369 libssl->setFileNameAndVersion(QLatin1String("ssl"), QLatin1String(SHLIB_VERSION_NUMBER));
370 libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String(SHLIB_VERSION_NUMBER));
371 if (libssl->load() && libcrypto->load()) {
372 // libssl.so.<SHLIB_VERSION_NUMBER> and libcrypto.so.<SHLIB_VERSION_NUMBER> found
373 return pair;
374 } else {
375 libssl->unload();
376 libcrypto->unload();
377 }
378#endif
379
380 // second attempt: find the development files libssl.so and libcrypto.so
381 libssl->setFileNameAndVersion(QLatin1String("ssl"), -1);
382 libcrypto->setFileNameAndVersion(QLatin1String("crypto"), -1);
383 if (libssl->load() && libcrypto->load()) {
384 // libssl.so.0 and libcrypto.so.0 found
385 return pair;
386 } else {
387 libssl->unload();
388 libcrypto->unload();
389 }
390
391 // third attempt: loop on the most common library paths and find libssl
392 QStringList sslList = findAllLibSsl();
393 foreach (const QString &ssl, sslList) {
394 QString crypto = ssl;
395 crypto.replace(QLatin1String("ssl"), QLatin1String("crypto"));
396 libssl->setFileNameAndVersion(ssl, -1);
397 libcrypto->setFileNameAndVersion(crypto, -1);
398 if (libssl->load() && libcrypto->load()) {
399 // libssl.so.0 and libcrypto.so.0 found
400 return pair;
401 } else {
402 libssl->unload();
403 libcrypto->unload();
404 }
405 }
406
407 // failed to load anything
408 delete libssl;
409 delete libcrypto;
410 libssl = libcrypto = 0;
411 return pair;
412
413# else
414 // not implemented for this platform yet
415 return pair;
416# endif
417}
418
419bool q_resolveOpenSslSymbols()
420{
421 static volatile bool symbolsResolved = false;
422 static volatile bool triedToResolveSymbols = false;
423#ifndef QT_NO_THREAD
424 QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_SSL_library_init));
425#endif
426 if (symbolsResolved)
427 return true;
428 if (triedToResolveSymbols)
429 return false;
430 triedToResolveSymbols = true;
431
432 QPair<QLibrary *, QLibrary *> libs = loadOpenSsl();
433 if (!libs.first || !libs.second)
434 // failed to load them
435 return false;
436
437#ifdef SSLEAY_MACROS
438 RESOLVEFUNC(ASN1_dup)
439#endif
440 RESOLVEFUNC(ASN1_STRING_data)
441 RESOLVEFUNC(ASN1_STRING_length)
442 RESOLVEFUNC(BIO_ctrl)
443 RESOLVEFUNC(BIO_free)
444 RESOLVEFUNC(BIO_new)
445 RESOLVEFUNC(BIO_new_mem_buf)
446 RESOLVEFUNC(BIO_read)
447 RESOLVEFUNC(BIO_s_mem)
448 RESOLVEFUNC(BIO_write)
449 RESOLVEFUNC(BN_num_bits)
450 RESOLVEFUNC(CRYPTO_free)
451 RESOLVEFUNC(CRYPTO_num_locks)
452 RESOLVEFUNC(CRYPTO_set_id_callback)
453 RESOLVEFUNC(CRYPTO_set_locking_callback)
454 RESOLVEFUNC(DSA_free)
455 RESOLVEFUNC(ERR_error_string)
456 RESOLVEFUNC(ERR_get_error)
457 RESOLVEFUNC(EVP_des_ede3_cbc)
458 RESOLVEFUNC(EVP_PKEY_assign)
459 RESOLVEFUNC(EVP_PKEY_free)
460 RESOLVEFUNC(EVP_PKEY_get1_DSA)
461 RESOLVEFUNC(EVP_PKEY_get1_RSA)
462 RESOLVEFUNC(EVP_PKEY_new)
463 RESOLVEFUNC(EVP_PKEY_type)
464 RESOLVEFUNC(OBJ_nid2sn)
465 RESOLVEFUNC(OBJ_obj2nid)
466#ifdef SSLEAY_MACROS // ### verify
467 RESOLVEFUNC(PEM_ASN1_read_bio)
468#else
469 RESOLVEFUNC(PEM_read_bio_DSAPrivateKey)
470 RESOLVEFUNC(PEM_read_bio_RSAPrivateKey)
471 RESOLVEFUNC(PEM_write_bio_DSAPrivateKey)
472 RESOLVEFUNC(PEM_write_bio_RSAPrivateKey)
473#endif
474 RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY)
475 RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY)
476 RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY)
477 RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY)
478 RESOLVEFUNC(RAND_seed)
479 RESOLVEFUNC(RAND_status)
480 RESOLVEFUNC(RSA_free)
481 RESOLVEFUNC(sk_free)
482 RESOLVEFUNC(sk_num)
483 RESOLVEFUNC(sk_value)
484 RESOLVEFUNC(SSL_CIPHER_description)
485 RESOLVEFUNC(SSL_CTX_check_private_key)
486 RESOLVEFUNC(SSL_CTX_ctrl)
487 RESOLVEFUNC(SSL_CTX_free)
488 RESOLVEFUNC(SSL_CTX_new)
489 RESOLVEFUNC(SSL_CTX_set_cipher_list)
490 RESOLVEFUNC(SSL_CTX_set_default_verify_paths)
491 RESOLVEFUNC(SSL_CTX_set_verify)
492 RESOLVEFUNC(SSL_CTX_set_verify_depth)
493 RESOLVEFUNC(SSL_CTX_use_certificate)
494 RESOLVEFUNC(SSL_CTX_use_certificate_file)
495 RESOLVEFUNC(SSL_CTX_use_PrivateKey)
496 RESOLVEFUNC(SSL_CTX_use_RSAPrivateKey)
497 RESOLVEFUNC(SSL_CTX_use_PrivateKey_file)
498 RESOLVEFUNC(SSL_accept)
499 RESOLVEFUNC(SSL_clear)
500 RESOLVEFUNC(SSL_connect)
501 RESOLVEFUNC(SSL_free)
502 RESOLVEFUNC(SSL_get_ciphers)
503 RESOLVEFUNC(SSL_get_current_cipher)
504 RESOLVEFUNC(SSL_get_error)
505 RESOLVEFUNC(SSL_get_peer_cert_chain)
506 RESOLVEFUNC(SSL_get_peer_certificate)
507 RESOLVEFUNC(SSL_get_verify_result)
508 RESOLVEFUNC(SSL_library_init)
509 RESOLVEFUNC(SSL_load_error_strings)
510 RESOLVEFUNC(SSL_new)
511 RESOLVEFUNC(SSL_read)
512 RESOLVEFUNC(SSL_set_accept_state)
513 RESOLVEFUNC(SSL_set_bio)
514 RESOLVEFUNC(SSL_set_connect_state)
515 RESOLVEFUNC(SSL_shutdown)
516 RESOLVEFUNC(SSL_write)
517 RESOLVEFUNC(SSLv2_client_method)
518 RESOLVEFUNC(SSLv3_client_method)
519 RESOLVEFUNC(SSLv23_client_method)
520 RESOLVEFUNC(TLSv1_client_method)
521 RESOLVEFUNC(SSLv2_server_method)
522 RESOLVEFUNC(SSLv3_server_method)
523 RESOLVEFUNC(SSLv23_server_method)
524 RESOLVEFUNC(TLSv1_server_method)
525 RESOLVEFUNC(X509_NAME_oneline)
526 RESOLVEFUNC(X509_PUBKEY_get)
527 RESOLVEFUNC(X509_STORE_free)
528 RESOLVEFUNC(X509_STORE_new)
529 RESOLVEFUNC(X509_STORE_add_cert)
530 RESOLVEFUNC(X509_STORE_CTX_free)
531 RESOLVEFUNC(X509_STORE_CTX_init)
532 RESOLVEFUNC(X509_STORE_CTX_new)
533 RESOLVEFUNC(X509_STORE_CTX_set_purpose)
534 RESOLVEFUNC(X509_cmp)
535#ifndef SSLEAY_MACROS
536 RESOLVEFUNC(X509_dup)
537#endif
538 RESOLVEFUNC(X509_EXTENSION_get_object)
539 RESOLVEFUNC(X509_free)
540 RESOLVEFUNC(X509_get_ext)
541 RESOLVEFUNC(X509_get_ext_count)
542 RESOLVEFUNC(X509_get_ext_d2i)
543 RESOLVEFUNC(X509_get_issuer_name)
544 RESOLVEFUNC(X509_get_subject_name)
545 RESOLVEFUNC(X509_verify_cert)
546 RESOLVEFUNC(d2i_X509)
547 RESOLVEFUNC(i2d_X509)
548#ifdef SSLEAY_MACROS
549 RESOLVEFUNC(i2d_DSAPrivateKey)
550 RESOLVEFUNC(i2d_RSAPrivateKey)
551 RESOLVEFUNC(d2i_DSAPrivateKey)
552 RESOLVEFUNC(d2i_RSAPrivateKey)
553#endif
554 RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf)
555 RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
556 symbolsResolved = true;
557 delete libs.first;
558 delete libs.second;
559 return true;
560}
561#endif // QT_NO_LIBRARY
562
563#else // !defined QT_LINKED_OPENSSL
564
565bool q_resolveOpenSslSymbols()
566{
567#ifdef QT_NO_SSL
568 return false;
569#endif
570 return true;
571}
572#endif // !defined QT_LINKED_OPENSSL
573
574//==============================================================================
575// contributed by Jay Case of Sarvega, Inc.; http://sarvega.com/
576// Based on X509_cmp_time() for intitial buffer hacking.
577//==============================================================================
578QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime)
579{
580 char lBuffer[24];
581 char *pBuffer = lBuffer;
582
583 size_t lTimeLength = aTime->length;
584 char *pString = (char *) aTime->data;
585
586 if (aTime->type == V_ASN1_UTCTIME) {
587 if ((lTimeLength < 11) || (lTimeLength > 17))
588 return QDateTime();
589
590 memcpy(pBuffer, pString, 10);
591 pBuffer += 10;
592 pString += 10;
593 } else {
594 if (lTimeLength < 13)
595 return QDateTime();
596
597 memcpy(pBuffer, pString, 12);
598 pBuffer += 12;
599 pString += 12;
600 }
601
602 if ((*pString == 'Z') || (*pString == '-') || (*pString == '+')) {
603 *pBuffer++ = '0';
604 *pBuffer++ = '0';
605 } else {
606 *pBuffer++ = *pString++;
607 *pBuffer++ = *pString++;
608 // Skip any fractional seconds...
609 if (*pString == '.') {
610 pString++;
611 while ((*pString >= '0') && (*pString <= '9'))
612 pString++;
613 }
614 }
615
616 *pBuffer++ = 'Z';
617 *pBuffer++ = '\0';
618
619 time_t lSecondsFromUCT;
620 if (*pString == 'Z') {
621 lSecondsFromUCT = 0;
622 } else {
623 if ((*pString != '+') && (*pString != '-'))
624 return QDateTime();
625
626 lSecondsFromUCT = ((pString[1] - '0') * 10 + (pString[2] - '0')) * 60;
627 lSecondsFromUCT += (pString[3] - '0') * 10 + (pString[4] - '0');
628 lSecondsFromUCT *= 60;
629 if (*pString == '-')
630 lSecondsFromUCT = -lSecondsFromUCT;
631 }
632
633 tm lTime;
634 lTime.tm_sec = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
635 lTime.tm_min = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
636 lTime.tm_hour = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
637 lTime.tm_mday = ((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0');
638 lTime.tm_mon = (((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0')) - 1;
639 lTime.tm_year = ((lBuffer[0] - '0') * 10) + (lBuffer[1] - '0');
640 if (lTime.tm_year < 50)
641 lTime.tm_year += 100; // RFC 2459
642
643 QDate resDate(lTime.tm_year + 1900, lTime.tm_mon + 1, lTime.tm_mday);
644 QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec);
645 QDateTime result(resDate, resTime, Qt::UTC);
646 result = result.addSecs(lSecondsFromUCT);
647 return result;
648}
649
650QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.