annotate ui/sslconnection.cpp @ 45:c6125d73faf4

Move SSLConnection into it's own class
author Andre Heinecke <aheinecke@intevation.de>
date Fri, 14 Mar 2014 16:40:53 +0000
parents
children d28e2624c1d5
rev   line source
45
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
1 /* TODO: Wrap ssl_session in a class for reuse.
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
2 * see programs/ssl/ssl_client2.c for example of session reuse */
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
3 #include "sslconnection.h"
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
4
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
5 #include <QFile>
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
6 #include <QUuid>
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
7 #include <QApplication>
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
8
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
9 #define MAX_IO_TRIES 10
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
10
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
11 #ifdef CONNECTION_DEBUG
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
12 static void my_debug(void *ctx, int level, const char *str)
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
13 {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
14 fprintf((FILE *) ctx, "%s", str);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
15 fflush((FILE *) ctx);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
16 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
17 #endif
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
18
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
19 QString getErrorMsg(int ret)
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
20 {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
21 char errbuf[255];
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
22 polarssl_strerror(ret, errbuf, 255);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
23 errbuf[254] = '\0'; /* Just to be sure */
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
24 return QString::fromLatin1(errbuf);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
25 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
26
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
27 SSLConnection::SSLConnection(const QString& url,
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
28 const QByteArray& certificate):
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
29 mUrl(url),
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
30 mPinnedCert(certificate),
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
31 mInitialized(false),
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
32 mConnected(false),
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
33 mServerFD(-1),
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
34 mErrorState(NoError)
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
35 {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
36 int ret = -1;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
37
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
38 memset(&mSSL, 0, sizeof(ssl_context));
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
39
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
40 if (certificate.isEmpty()) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
41 QFile certResource(":certs/kolab.org");
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
42 certResource.open(QFile::ReadOnly);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
43 mPinnedCert = certResource.readAll();
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
44 certResource.close();
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
45 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
46
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
47 ret = init();
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
48 if (ret == 0) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
49 mInitialized = true;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
50 } else {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
51 qDebug() << "Initialization error: " + getErrorMsg(ret);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
52 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
53 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
54
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
55 int SSLConnection::init()
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
56 {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
57 int ret = -1;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
58 QUuid uuid = QUuid::createUuid();
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
59 QString personalString = QApplication::applicationName() + uuid.toString();
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
60 QByteArray personalBa = personalString.toLocal8Bit();
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
61
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
62 x509_crt_init(&mX509PinnedCert);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
63 entropy_init(&mEntropy);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
64
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
65 ret = ssl_init(&mSSL);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
66 if (ret != 0) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
67 /* The only documented error is malloc failed */
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
68 mErrorState = ErrUnknown;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
69 return ret;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
70 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
71
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
72 /*
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
73 * Initialize random generator.
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
74 * Personalisation string, does not need to be random but
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
75 * should be unique according to documentation.
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
76 *
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
77 * the ctr_drbg structure does not need to be freed explicitly.
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
78 */
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
79 ret = ctr_drbg_init(&mCtr_drbg, entropy_func, &mEntropy,
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
80 (const unsigned char*) personalBa.constData(),
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
81 personalBa.size());
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
82 if (ret != 0) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
83 ssl_free(&mSSL);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
84 mErrorState = ErrUnknown;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
85 return ret;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
86 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
87
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
88 ret = x509_crt_parse(&mX509PinnedCert,
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
89 (const unsigned char*) mPinnedCert.constData(),
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
90 mPinnedCert.size());
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
91 if (ret != 0){
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
92 ssl_free(&mSSL);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
93 mErrorState = InvalidPinnedCertificate;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
94 return ret;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
95 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
96
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
97 ssl_set_endpoint(&mSSL, SSL_IS_CLIENT);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
98 ssl_set_authmode(&mSSL, SSL_VERIFY_OPTIONAL);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
99 ssl_set_ca_chain(&mSSL, &mX509PinnedCert, NULL, NULL);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
100 ssl_set_renegotiation(&mSSL, SSL_RENEGOTIATION_DISABLED);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
101 ssl_set_rng(&mSSL, ctr_drbg_random, &mCtr_drbg);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
102 #ifdef RELEASE_BUILD
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
103 ssl_set_min_version(&mSSL, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
104 #endif
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
105
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
106 #ifdef CONNECTION_DEBUG
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
107 ssl_set_dbg(&mSSL, my_debug, stdout);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
108 #endif
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
109
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
110 return 0;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
111 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
112
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
113 SSLConnection::~SSLConnection() {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
114 if (mConnected) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
115 ssl_close_notify (&mSSL);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
116 if (mServerFD != -1) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
117 net_close(mServerFD);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
118 mServerFD = -1;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
119 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
120 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
121 x509_crt_free(&mX509PinnedCert);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
122 entropy_free(&mEntropy);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
123 if (mInitialized) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
124 ssl_free(&mSSL);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
125 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
126 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
127
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
128 int SSLConnection::connect() {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
129 int ret = -1;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
130 const x509_crt *peerCert;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
131
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
132 if (!mInitialized) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
133 mErrorState = ErrUnknown;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
134 return -1;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
135 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
136
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
137 ret = net_connect(&mServerFD, mUrl.host().toLatin1().constData(),
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
138 mUrl.port(443));
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
139
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
140 if (ret != 0) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
141 mErrorState = NoConnection;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
142 return ret;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
143 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
144
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
145 ssl_set_bio(&mSSL, net_recv, &mServerFD,
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
146 net_send, &mServerFD);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
147
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
148 while ((ret = ssl_handshake(&mSSL)) != 0) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
149 if (ret != POLARSSL_ERR_NET_WANT_READ &&
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
150 ret != POLARSSL_ERR_NET_WANT_WRITE) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
151 qDebug() << "SSL Handshake failed: "
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
152 << getErrorMsg(ret);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
153 mErrorState = SSLHandshakeFailed;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
154 return ret;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
155 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
156 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
157
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
158 /* we might want to set the verify function
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
159 * with ssl_set_verify before to archive the
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
160 * certificate pinning. */
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
161
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
162 ret = ssl_get_verify_result(&mSSL);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
163
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
164 if (ret != 0 ) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
165 if((ret & BADCERT_EXPIRED) != 0)
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
166 qDebug() << "server certificate has expired";
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
167 if((ret & BADCERT_REVOKED) != 0)
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
168 qDebug() << "server certificate has been revoked";
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
169 if((ret & BADCERT_CN_MISMATCH) != 0)
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
170 qDebug() << "CN mismatch";
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
171 if((ret & BADCERT_NOT_TRUSTED) != 0)
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
172 qDebug() << "self-signed or not signed by a trusted CA";
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
173 ret = -1;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
174 #ifdef RELEASE_BUILD
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
175 mErrorState = InvalidCertificate;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
176 return -1;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
177 #endif
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
178 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
179
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
180 peerCert = ssl_get_peer_cert(&mSSL);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
181
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
182 if (!peerCert) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
183 mErrorState = InvalidCertificate;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
184 qDebug() << "Failed to get peer cert";
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
185 return -1;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
186 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
187
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
188 if (peerCert->raw.len == 0 ||
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
189 peerCert->raw.len != mX509PinnedCert.raw.len) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
190 mErrorState = InvalidCertificate;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
191 qDebug() << "Certificate length mismatch";
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
192 return -1;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
193 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
194
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
195 /* You can never be sure what those c++ operators do..
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
196 if (mPinnedCert != QByteArray::fromRawData(
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
197 (const char*) peerCert->raw.p,
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
198 peerCert->raw.len)) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
199 qDebug() << "Certificate content mismatch";
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
200 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
201 */
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
202
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
203 for (unsigned int i = 0; i < peerCert->raw.len; i++) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
204 if (peerCert->raw.p[i] != mX509PinnedCert.raw.p[i]) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
205 qDebug() << "Certificate content mismatch";
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
206 mErrorState = InvalidCertificate;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
207 return -1;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
208 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
209 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
210 return 0;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
211 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
212
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
213 int SSLConnection::write (const QByteArray& request)
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
214 {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
215 unsigned int tries = 0;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
216 int ret = -1;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
217
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
218 const unsigned char *buf = (const unsigned char *) request.constData();
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
219 size_t len = (size_t) request.size();
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
220
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
221 qDebug() << "Seinding request: " << request;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
222 /* According to doc for ssl_write:
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
223 *
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
224 * When this function returns POLARSSL_ERR_NET_WANT_WRITE,
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
225 * it must be called later with the same arguments,
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
226 * until it returns a positive value.
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
227 */
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
228 do {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
229 ret = ssl_write(&mSSL, buf, len);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
230 if (ret >= 0) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
231 if ((unsigned int) ret == len) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
232 return 0;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
233 } else {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
234 qDebug() << "Write failed to write everything";
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
235 return -1;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
236 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
237 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
238
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
239 if (ret != POLARSSL_ERR_NET_WANT_WRITE) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
240 return ret;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
241 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
242 tries++;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
243 net_usleep(100000); /* sleep 100ms to give the socket a chance
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
244 to clean up. */
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
245 } while (tries < MAX_IO_TRIES);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
246
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
247 return ret;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
248 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
249
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
250 QByteArray SSLConnection::read(size_t len)
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
251 {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
252 unsigned char buf[len];
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
253 QByteArray retval("");
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
254 int ret = -1;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
255
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
256 do {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
257 memset (buf, 0, sizeof(buf));
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
258 ret = ssl_read(&mSSL, buf, len);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
259 if (ret == 0 ||
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
260 ret == POLARSSL_ERR_SSL_CONN_EOF) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
261 /* EOF */
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
262 return retval;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
263 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
264 if (ret <= 0) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
265 qDebug() << "Read failed: " << getErrorMsg(ret);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
266 return QByteArray();
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
267 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
268 if (len < (len - (unsigned int) ret)) {
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
269 /* Should never happen if ssl_read behaves */
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
270 qDebug() << "integer overflow in polarSSLRead";
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
271 return QByteArray();
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
272 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
273 len -= (unsigned int) ret;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
274 retval.append((const char *)buf, len);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
275 } while (len > 0);
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
276
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
277 return retval;
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
278 }
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
279

http://wald.intevation.org/projects/trustbridge/