Mercurial > trustbridge
comparison ui/sslconnection_curl.cpp @ 999:daa9448b64f5
(issue90) Use certificate pinning and forced ciphersuites for curl
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 01 Sep 2014 19:49:54 +0200 |
parents | 6a3d284b9c16 |
children | 7dff5c0c569c |
comparison
equal
deleted
inserted
replaced
998:0570b1e562c2 | 999:daa9448b64f5 |
---|---|
5 * and comes with ABSOLUTELY NO WARRANTY! | 5 * and comes with ABSOLUTELY NO WARRANTY! |
6 * See LICENSE.txt for details. | 6 * See LICENSE.txt for details. |
7 */ | 7 */ |
8 | 8 |
9 #include "sslconnection_curl.h" | 9 #include "sslconnection_curl.h" |
10 | |
11 #include <polarssl/ssl.h> | |
10 #include <QSaveFile> | 12 #include <QSaveFile> |
11 | 13 |
12 #define CONNECTION_DEBUG | 14 #define CONNECTION_DEBUG |
13 | 15 |
14 SSLConnectionCurl::SSLConnectionCurl(const QString& url, | 16 SSLConnectionCurl::SSLConnectionCurl(const QString& url, |
22 if (!mCurl) { | 24 if (!mCurl) { |
23 qDebug() << "Failed to initialize curl"; | 25 qDebug() << "Failed to initialize curl"; |
24 return; | 26 return; |
25 } | 27 } |
26 | 28 |
29 #ifdef RELEASE_BUILD | |
27 if (curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, 1L) != CURLE_OK) { | 30 if (curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, 1L) != CURLE_OK) { |
31 #else | |
32 /* For testing we do not have to trust the issuer. This should not | |
33 * be dangerous as we pin the peer certificate directly. */ | |
34 if (curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, 0L) != CURLE_OK) { | |
35 #endif | |
28 /* Should be default anyway */ | 36 /* Should be default anyway */ |
29 qDebug() << "Setting verifypeer failed"; | 37 qDebug() << "Setting verifypeer failed"; |
30 return; | 38 return; |
31 } | 39 } |
32 | 40 |
41 #ifdef RELEASE_BUILD | |
42 if (curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYHOST, 1L) != CURLE_OK) { | |
43 #else | |
44 /* For testing we do not have to trust host. This should not | |
45 * be dangerous as we pin the peer certificate directly. */ | |
46 if (curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYHOST, 0L) != CURLE_OK) { | |
47 #endif | |
48 /* Should be default anyway */ | |
49 qDebug() << "Setting verifypeer failed"; | |
50 return; | |
51 } | |
52 | |
33 if (curl_easy_setopt(mCurl, CURLOPT_ERRORBUFFER, mErrBuf) != CURLE_OK) { | 53 if (curl_easy_setopt(mCurl, CURLOPT_ERRORBUFFER, mErrBuf) != CURLE_OK) { |
34 qDebug() << "Setting errorbuf failed"; | 54 qDebug() << "Setting errorbuf failed"; |
35 return; | 55 return; |
36 } | 56 } |
57 | |
58 #ifdef RELEASE_BUILD | |
59 if (curl_easy_setopt(mCurl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2) != CURLE_OK) { | |
60 qDebug() << "Setting ssl version failed."; | |
61 return; | |
62 } | |
63 #endif | |
37 | 64 |
38 mCertFile.open(); | 65 mCertFile.open(); |
39 if (mCertFile.write(mPinnedCert) != mPinnedCert.size()) { | 66 if (mCertFile.write(mPinnedCert) != mPinnedCert.size()) { |
40 qDebug() << "Failed to write temporary certificate"; | 67 qDebug() << "Failed to write temporary certificate"; |
41 return; | 68 return; |
42 } | 69 } |
43 mCertFile.close(); | 70 mCertFile.close(); |
44 | 71 |
45 if (curl_easy_setopt(mCurl, CURLOPT_CAINFO, | 72 if (curl_easy_setopt(mCurl, CURLOPT_CAINFO, |
46 mCertFile.fileName().toUtf8().constData()) != CURLE_OK) { | 73 mCertFile.fileName().toUtf8().constData()) != CURLE_OK) { |
47 qDebug() << "Failed to write temporary certificate"; | 74 qDebug() << "Failed to set ca certificate"; |
48 return; | 75 return; |
49 } | 76 } |
50 | 77 |
78 /* If the build fails here maybe you probably forgot to apply the | |
79 * trustbridge patches to curl */ | |
80 if (curl_easy_setopt(mCurl, CURLOPT_PEERCERT, | |
81 mCertFile.fileName().toUtf8().constData()) != CURLE_OK) { | |
82 qDebug() << "Failed set peer certificate."; | |
83 return; | |
84 } | |
51 mInitialized = true; | 85 mInitialized = true; |
52 | 86 |
53 #ifdef CONNECTION_DEBUG | 87 #ifdef CONNECTION_DEBUG |
54 curl_easy_setopt(mCurl, CURLOPT_VERBOSE, 1L); | 88 curl_easy_setopt(mCurl, CURLOPT_VERBOSE, 1L); |
55 #endif | 89 #endif |
80 retval = curl_easy_perform(mCurl); | 114 retval = curl_easy_perform(mCurl); |
81 if (retval != CURLE_OK) { | 115 if (retval != CURLE_OK) { |
82 qDebug() << "Failed to connect: " << mErrBuf << " retval: " << retval; | 116 qDebug() << "Failed to connect: " << mErrBuf << " retval: " << retval; |
83 if (retval == CURLE_PEER_FAILED_VERIFICATION) { | 117 if (retval == CURLE_PEER_FAILED_VERIFICATION) { |
84 mErrorState = InvalidCertificate; | 118 mErrorState = InvalidCertificate; |
119 return -1; | |
120 } | |
121 if (retval == CURLE_SSL_CONNECT_ERROR) { | |
122 mErrorState = SSLHandshakeFailed; | |
85 return -1; | 123 return -1; |
86 } | 124 } |
87 | 125 |
88 mErrorState = NoConnection; | 126 mErrorState = NoConnection; |
89 return -1; | 127 return -1; |
224 return; | 262 return; |
225 } | 263 } |
226 } | 264 } |
227 | 265 |
228 void SSLConnectionCurl::setCiphersuites(int ciphers[]) { | 266 void SSLConnectionCurl::setCiphersuites(int ciphers[]) { |
229 qDebug() << "Set ciphersuites not supported."; | 267 QStringList cipher_list; |
230 } | 268 for (int i = 0; ciphers[i] != 0; i++) { |
269 cipher_list << ssl_get_ciphersuite_name(ciphers[i]); | |
270 } | |
271 | |
272 if (curl_easy_setopt(mCurl, CURLOPT_SSL_CIPHER_LIST, | |
273 cipher_list.join(":").toLatin1().constData()) != CURLE_OK) { | |
274 qDebug() << "Failed to set cipher list"; | |
275 return; | |
276 } | |
277 } |