b553f796cee0e2c73f6451838268eb54cf4af3c0
[umurmur.git] / src / ssli_polarssl.c
1 /* Copyright (C) 2009-2014, Martin Johansson <martin@fatbob.nu>
2    Copyright (C) 2005-2014, Thorvald Natvig <thorvald@natvig.com>
3
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9
10    - Redistributions of source code must retain the above copyright notice,
11      this list of conditions and the following disclaimer.
12    - Redistributions in binary form must reproduce the above copyright notice,
13      this list of conditions and the following disclaimer in the documentation
14      and/or other materials provided with the distribution.
15    - Neither the name of the Developers nor the names of its contributors may
16      be used to endorse or promote products derived from this software without
17      specific prior written permission.
18
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 #include <string.h>
32 #include <stdlib.h>
33 #include <fcntl.h>
34
35 #include "conf.h"
36 #include "log.h"
37 #include "ssl.h"
38
39 /*
40  * PolarSSL interface
41  */
42
43 #include <polarssl/config.h>
44 #include <polarssl/havege.h>
45 #include <polarssl/certs.h>
46 #include <polarssl/x509.h>
47 #include <polarssl/ssl.h>
48 #include <polarssl/net.h>
49
50 #ifdef POLARSSL_API_V1_2_ABOVE
51 int ciphers[] =
52 {
53     TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
54     TLS_RSA_WITH_AES_256_CBC_SHA,
55     TLS_RSA_WITH_AES_128_CBC_SHA,
56     0
57 };
58 #else
59 int ciphers[] =
60 {
61     SSL_EDH_RSA_AES_256_SHA,
62     SSL_RSA_AES_256_SHA,
63     SSL_RSA_AES_128_SHA,
64     0
65 };
66 #endif
67
68 #ifdef POLARSSL_API_V1_3_ABOVE
69 static x509_crt certificate;
70 static inline int x509parse_keyfile(rsa_context *rsa, const char *path,
71                                     const char *pwd)
72 {
73     int ret;
74     pk_context pk;
75
76     pk_init(&pk);
77     ret = pk_parse_keyfile(&pk, path, pwd);
78     if (ret == 0 && !pk_can_do( &pk, POLARSSL_PK_RSA))
79         ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
80     if (ret == 0)
81         rsa_copy(rsa, pk_rsa(pk));
82     else
83         rsa_free(rsa);
84     pk_free(&pk);
85     return ret;
86 }
87 #else
88 static x509_cert certificate;
89 #endif
90
91 static rsa_context key;
92 bool_t builtInTestCertificate;
93
94 #ifdef USE_POLARSSL_HAVEGE
95 havege_state hs;
96 #else
97 int urandom_fd;
98 #endif
99
100 /* DH prime */
101 char *my_dhm_P =
102         "9CE85640903BF123906947FEDE767261" \
103         "D9B4A973EB8F7D984A8C656E2BCC161C" \
104         "183D4CA471BA78225F940F16D1D99CA3" \
105         "E66152CC68EDCE1311A390F307741835" \
106         "44FF6AB553EC7073AD0CB608F2A3B480" \
107         "19E6C02BCED40BD30E91BB2469089670" \
108         "DEF409C08E8AC24D1732A6128D2220DC53";
109 char *my_dhm_G = "4";
110
111 #ifdef USE_POLARSSL_TESTCERT
112 static void initTestCert()
113 {
114         int rc;
115         builtInTestCertificate = true;
116 #ifdef POLARSSL_API_V1_3_ABOVE
117         rc = x509_crt_parse_rsa(&certificate, (unsigned char *)test_srv_crt,
118                 strlen(test_srv_crt));
119 #else
120         rc = x509parse_crt(&certificate, (unsigned char *)test_srv_crt,
121                 strlen(test_srv_crt));
122 #endif
123         if (rc != 0)
124                 Log_fatal("Could not parse built-in test certificate");
125 }
126
127 static void initTestKey()
128 {
129         int rc;
130
131         rc = x509parse_key_rsa(&key, (unsigned char *)test_srv_key,
132                                strlen(test_srv_key), NULL, 0);
133         if (rc != 0)
134                 Log_fatal("Could not parse built-in test RSA key");
135 }
136 #endif
137
138 /*
139  * How to generate a self-signed cert with openssl:
140  * openssl genrsa 1024 > host.key
141  * openssl req -new -x509 -nodes -sha1 -days 365 -key host.key > host.cert
142  */
143 static void initCert()
144 {
145         int rc;
146         char *crtfile = (char *)getStrConf(CERTIFICATE);
147
148         if (crtfile == NULL) {
149 #ifdef USE_POLARSSL_TESTCERT
150                 Log_warn("No certificate file specified. Falling back to test certificate.");
151                 initTestCert();
152 #else
153                 Log_fatal("No certificate file specified");
154 #endif
155                 return;
156         }
157 #ifdef POLARSSL_API_V1_3_ABOVE
158         rc = x509_crt_parse_file(&certificate, crtfile);
159 #else
160         rc = x509parse_crtfile(&certificate, crtfile);
161 #endif
162         if (rc != 0) {
163 #ifdef USE_POLARSSL_TESTCERT
164                 Log_warn("Could not read certificate file '%s'. Falling back to test certificate.", crtfile);
165                 initTestCert();
166 #else
167                 Log_fatal("Could not read certificate file '%s'", crtfile);
168 #endif
169                 return;
170         }
171 }
172
173 static void initKey()
174 {
175         int rc;
176         char *keyfile = (char *)getStrConf(KEY);
177
178         if (keyfile == NULL)
179                 Log_fatal("No key file specified");
180         rc = x509parse_keyfile(&key, keyfile, NULL);
181         if (rc != 0)
182                 Log_fatal("Could not read RSA key file %s", keyfile);
183 }
184
185 #ifndef USE_POLARSSL_HAVEGE
186 int urandom_bytes(void *ctx, unsigned char *dest, size_t len)
187 {
188         int cur;
189
190         while (len) {
191                 cur = read(urandom_fd, dest, len);
192                 if (cur < 0)
193                         continue;
194                 len -= cur;
195         }
196         return 0;
197 }
198 #endif
199
200 #define DEBUG_LEVEL 0
201 static void pssl_debug(void *ctx, int level, const char *str)
202 {
203     if (level <= DEBUG_LEVEL)
204                 Log_info("PolarSSL [level %d]: %s", level, str);
205 }
206
207 void SSLi_init(void)
208 {
209         char verstring[12];
210
211         initCert();
212 #ifdef USE_POLARSSL_TESTCERT
213         if (builtInTestCertificate) {
214                 Log_warn("*** Using built-in test certificate and RSA key ***");
215                 Log_warn("*** This is not secure! Please use a CA-signed certificate or create a key and self-signed certificate ***");
216                 initTestKey();
217         }
218         else
219                 initKey();
220 #else
221         initKey();
222 #endif
223
224         /* Initialize random number generator */
225 #ifdef USE_POLARSSL_HAVEGE
226     havege_init(&hs);
227 #else
228     urandom_fd = open("/dev/urandom", O_RDONLY);
229     if (urandom_fd < 0)
230             Log_fatal("Cannot open /dev/urandom");
231 #endif
232
233     version_get_string(verstring);
234     Log_info("PolarSSL library version %s initialized", verstring);
235 }
236
237 void SSLi_deinit(void)
238 {
239 #ifdef POLARSSL_API_V1_3_ABOVE
240         x509_crt_free(&certificate);
241 #else
242         x509_free(&certificate);
243 #endif
244         rsa_free(&key);
245 }
246
247 /* Create SHA1 of last certificate in the peer's chain. */
248 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
249 {
250 #ifdef POLARSSL_API_V1_3_ABOVE
251         x509_crt const *cert;
252 #else
253         x509_cert const *cert;
254 #endif
255 #ifdef POLARSSL_API_V1_2_ABOVE
256         cert = ssl_get_peer_cert(ssl);
257 #else
258         cert = ssl->peer_cert;
259 #endif
260         if (!cert) {
261                 return false;
262         }
263         sha1(cert->raw.p, cert->raw.len, hash);
264         return true;
265 }
266
267 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
268 {
269         ssl_context *ssl;
270         ssl_session *ssn;
271         int rc;
272
273         ssl = malloc(sizeof(ssl_context));
274         ssn = malloc(sizeof(ssl_session));
275         if (!ssl || !ssn)
276                 Log_fatal("Out of memory");
277         memset(ssl, 0, sizeof(ssl_context));
278         memset(ssn, 0, sizeof(ssl_session));
279
280         rc = ssl_init(ssl);
281         if (rc != 0 )
282                 Log_fatal("Failed to initialize: %d", rc);
283
284         ssl_set_endpoint(ssl, SSL_IS_SERVER);
285         ssl_set_authmode(ssl, SSL_VERIFY_OPTIONAL);
286
287 #ifdef USE_POLARSSL_HAVEGE
288         ssl_set_rng(ssl, HAVEGE_RAND, &hs);
289 #else
290         ssl_set_rng(ssl, urandom_bytes, NULL);
291 #endif
292
293         ssl_set_dbg(ssl, pssl_debug, NULL);
294         ssl_set_bio(ssl, net_recv, fd, net_send, fd);
295
296         ssl_set_ciphersuites(ssl, ciphers);
297
298 #ifdef POLARSSL_API_V1_2_ABOVE
299     ssl_set_session(ssl, ssn);
300 #else
301     ssl_set_session(ssl, 0, 0, ssn);
302 #endif
303
304     ssl_set_ca_chain(ssl, &certificate, NULL, NULL);
305 #ifdef POLARSSL_API_V1_3_ABOVE
306         ssl_set_own_cert_rsa(ssl, &certificate, &key);
307 #else
308         ssl_set_own_cert(ssl, &certificate, &key);
309 #endif
310         ssl_set_dh_param(ssl, my_dhm_P, my_dhm_G);
311
312         return ssl;
313 }
314
315 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
316 {
317         int rc;
318
319         rc = ssl_handshake(ssl);
320         if (rc != 0) {
321                 if (rc == POLARSSL_ERR_NET_WANT_READ || rc == POLARSSL_ERR_NET_WANT_WRITE) {
322                         return 0;
323                 } else if (rc == POLARSSL_ERR_X509_CERT_VERIFY_FAILED) { /* Allow this (selfsigned etc) */
324                         return 0;
325                 } else {
326                         Log_warn("SSL handshake failed: %d", rc);
327                         return -1;
328                 }
329         }
330         *SSLready = true;
331         return 0;
332 }
333
334 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
335 {
336         int rc;
337
338         rc = ssl_read(ssl, buf, len);
339         if (rc == POLARSSL_ERR_NET_WANT_READ)
340                 return SSLI_ERROR_WANT_READ;
341         return rc;
342 }
343
344 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
345 {
346         int rc;
347
348         rc = ssl_write(ssl, buf, len);
349         if (rc == POLARSSL_ERR_NET_WANT_WRITE)
350                 return SSLI_ERROR_WANT_WRITE;
351         return rc;
352 }
353
354 int SSLi_get_error(SSL_handle_t *ssl, int code)
355 {
356         return code;
357 }
358
359 bool_t SSLi_data_pending(SSL_handle_t *ssl)
360 {
361         return ssl_get_bytes_avail(ssl) > 0;
362 }
363
364 void SSLi_shutdown(SSL_handle_t *ssl)
365 {
366         ssl_close_notify(ssl);
367 }
368
369 void SSLi_free(SSL_handle_t *ssl)
370 {
371         Log_debug("SSLi_free");
372 #if (POLARSSL_VERSION_MINOR <= 2 && POLARSSL_VERSION_PATCH < 6)
373         free(ssl->session); /* Workaround for memory leak in PolarSSL < 1.2.6 */
374         ssl->session = NULL;
375 #endif
376         ssl_free(ssl);
377         free(ssl);
378 }
379