small restructuring
[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 "conf.h"
32 #include "log.h"
33 #include "ssl.h"
34
35 #include <stdlib.h>
36 #include <fcntl.h>
37
38 #include <polarssl/config.h>
39 #include <polarssl/havege.h>
40 #include <polarssl/certs.h>
41 #include <polarssl/x509.h>
42 #include <polarssl/ssl.h>
43 #include <polarssl/net.h>
44
45 #ifdef POLARSSL_API_V1_2_ABOVE
46 int ciphers[] =
47 {
48     TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
49     TLS_RSA_WITH_AES_256_CBC_SHA,
50     TLS_RSA_WITH_AES_128_CBC_SHA,
51     0
52 };
53 #else
54 int ciphers[] =
55 {
56     SSL_EDH_RSA_AES_256_SHA,
57     SSL_RSA_AES_256_SHA,
58     SSL_RSA_AES_128_SHA,
59     0
60 };
61 #endif
62
63 #ifdef POLARSSL_API_V1_3_ABOVE
64 static x509_crt certificate;
65 static inline int x509parse_keyfile(rsa_context *rsa, const char *path,
66                                     const char *pwd)
67 {
68     int ret;
69     pk_context pk;
70
71     pk_init(&pk);
72     ret = pk_parse_keyfile(&pk, path, pwd);
73     if (ret == 0 && !pk_can_do( &pk, POLARSSL_PK_RSA))
74         ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
75     if (ret == 0)
76         rsa_copy(rsa, pk_rsa(pk));
77     else
78         rsa_free(rsa);
79     pk_free(&pk);
80     return ret;
81 }
82 #else
83 static x509_cert certificate;
84 #endif
85
86 static rsa_context key;
87 bool_t builtInTestCertificate;
88
89 #ifdef USE_POLARSSL_HAVEGE
90 havege_state hs;
91 #else
92 int urandom_fd;
93 #endif
94
95 /* DH prime */
96 char *my_dhm_P =
97         "9CE85640903BF123906947FEDE767261" \
98         "D9B4A973EB8F7D984A8C656E2BCC161C" \
99         "183D4CA471BA78225F940F16D1D99CA3" \
100         "E66152CC68EDCE1311A390F307741835" \
101         "44FF6AB553EC7073AD0CB608F2A3B480" \
102         "19E6C02BCED40BD30E91BB2469089670" \
103         "DEF409C08E8AC24D1732A6128D2220DC53";
104 char *my_dhm_G = "4";
105
106 #ifdef USE_POLARSSL_TESTCERT
107 static void initTestCert()
108 {
109         int rc;
110         builtInTestCertificate = true;
111 #ifdef POLARSSL_API_V1_3_ABOVE
112         rc = x509_crt_parse_rsa(&certificate, (unsigned char *)test_srv_crt,
113                 strlen(test_srv_crt));
114 #else
115         rc = x509parse_crt(&certificate, (unsigned char *)test_srv_crt,
116                 strlen(test_srv_crt));
117 #endif
118         if (rc != 0)
119                 Log_fatal("Could not parse built-in test certificate");
120 }
121
122 static void initTestKey()
123 {
124         int rc;
125
126         rc = x509parse_key_rsa(&key, (unsigned char *)test_srv_key,
127                                strlen(test_srv_key), NULL, 0);
128         if (rc != 0)
129                 Log_fatal("Could not parse built-in test RSA key");
130 }
131 #endif
132
133 /*
134  * How to generate a self-signed cert with openssl:
135  * openssl genrsa 1024 > host.key
136  * openssl req -new -x509 -nodes -sha1 -days 365 -key host.key > host.cert
137  */
138 static void initCert()
139 {
140         int rc;
141         char *crtfile = (char *)getStrConf(CERTIFICATE);
142
143         if (crtfile == NULL) {
144 #ifdef USE_POLARSSL_TESTCERT
145                 Log_warn("No certificate file specified. Falling back to test certificate.");
146                 initTestCert();
147 #else
148                 Log_fatal("No certificate file specified");
149 #endif
150                 return;
151         }
152 #ifdef POLARSSL_API_V1_3_ABOVE
153         rc = x509_crt_parse_file(&certificate, crtfile);
154 #else
155         rc = x509parse_crtfile(&certificate, crtfile);
156 #endif
157         if (rc != 0) {
158 #ifdef USE_POLARSSL_TESTCERT
159                 Log_warn("Could not read certificate file '%s'. Falling back to test certificate.", crtfile);
160                 initTestCert();
161 #else
162                 Log_fatal("Could not read certificate file '%s'", crtfile);
163 #endif
164                 return;
165         }
166 }
167
168 static void initKey()
169 {
170         int rc;
171         char *keyfile = (char *)getStrConf(KEY);
172
173         if (keyfile == NULL)
174                 Log_fatal("No key file specified");
175         rc = x509parse_keyfile(&key, keyfile, NULL);
176         if (rc != 0)
177                 Log_fatal("Could not read RSA key file %s", keyfile);
178 }
179
180 #ifndef USE_POLARSSL_HAVEGE
181 int urandom_bytes(void *ctx, unsigned char *dest, size_t len)
182 {
183         int cur;
184
185         while (len) {
186                 cur = read(urandom_fd, dest, len);
187                 if (cur < 0)
188                         continue;
189                 len -= cur;
190         }
191         return 0;
192 }
193 #endif
194
195 #define DEBUG_LEVEL 0
196 static void pssl_debug(void *ctx, int level, const char *str)
197 {
198     if (level <= DEBUG_LEVEL)
199                 Log_info("PolarSSL [level %d]: %s", level, str);
200 }
201
202 void SSLi_init(void)
203 {
204         char verstring[12];
205
206         initCert();
207 #ifdef USE_POLARSSL_TESTCERT
208         if (builtInTestCertificate) {
209                 Log_warn("*** Using built-in test certificate and RSA key ***");
210                 Log_warn("*** This is not secure! Please use a CA-signed certificate or create a key and self-signed certificate ***");
211                 initTestKey();
212         }
213         else
214                 initKey();
215 #else
216         initKey();
217 #endif
218
219         /* Initialize random number generator */
220 #ifdef USE_POLARSSL_HAVEGE
221     havege_init(&hs);
222 #else
223     urandom_fd = open("/dev/urandom", O_RDONLY);
224     if (urandom_fd < 0)
225             Log_fatal("Cannot open /dev/urandom");
226 #endif
227
228     version_get_string(verstring);
229     Log_info("PolarSSL library version %s initialized", verstring);
230 }
231
232 void SSLi_deinit(void)
233 {
234 #ifdef POLARSSL_API_V1_3_ABOVE
235         x509_crt_free(&certificate);
236 #else
237         x509_free(&certificate);
238 #endif
239         rsa_free(&key);
240 }
241
242 /* Create SHA1 of last certificate in the peer's chain. */
243 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
244 {
245 #ifdef POLARSSL_API_V1_3_ABOVE
246         x509_crt const *cert;
247 #else
248         x509_cert const *cert;
249 #endif
250 #ifdef POLARSSL_API_V1_2_ABOVE
251         cert = ssl_get_peer_cert(ssl);
252 #else
253         cert = ssl->peer_cert;
254 #endif
255         if (!cert) {
256                 return false;
257         }
258         sha1(cert->raw.p, cert->raw.len, hash);
259         return true;
260 }
261
262 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
263 {
264         ssl_context *ssl;
265         ssl_session *ssn;
266         int rc;
267
268         ssl = malloc(sizeof(ssl_context));
269         ssn = malloc(sizeof(ssl_session));
270         if (!ssl || !ssn)
271                 Log_fatal("Out of memory");
272         memset(ssl, 0, sizeof(ssl_context));
273         memset(ssn, 0, sizeof(ssl_session));
274
275         rc = ssl_init(ssl);
276         if (rc != 0 )
277                 Log_fatal("Failed to initialize: %d", rc);
278
279         ssl_set_endpoint(ssl, SSL_IS_SERVER);
280         ssl_set_authmode(ssl, SSL_VERIFY_OPTIONAL);
281
282 #ifdef USE_POLARSSL_HAVEGE
283         ssl_set_rng(ssl, HAVEGE_RAND, &hs);
284 #else
285         ssl_set_rng(ssl, urandom_bytes, NULL);
286 #endif
287
288         ssl_set_dbg(ssl, pssl_debug, NULL);
289         ssl_set_bio(ssl, net_recv, fd, net_send, fd);
290
291         ssl_set_ciphersuites(ssl, ciphers);
292
293 #ifdef POLARSSL_API_V1_2_ABOVE
294     ssl_set_session(ssl, ssn);
295 #else
296     ssl_set_session(ssl, 0, 0, ssn);
297 #endif
298
299     ssl_set_ca_chain(ssl, &certificate, NULL, NULL);
300 #ifdef POLARSSL_API_V1_3_ABOVE
301         ssl_set_own_cert_rsa(ssl, &certificate, &key);
302 #else
303         ssl_set_own_cert(ssl, &certificate, &key);
304 #endif
305         ssl_set_dh_param(ssl, my_dhm_P, my_dhm_G);
306
307         return ssl;
308 }
309
310 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
311 {
312         int rc;
313
314         rc = ssl_handshake(ssl);
315         if (rc != 0) {
316                 if (rc == POLARSSL_ERR_NET_WANT_READ || rc == POLARSSL_ERR_NET_WANT_WRITE) {
317                         return 0;
318                 } else if (rc == POLARSSL_ERR_X509_CERT_VERIFY_FAILED) { /* Allow this (selfsigned etc) */
319                         return 0;
320                 } else {
321                         Log_warn("SSL handshake failed: %d", rc);
322                         return -1;
323                 }
324         }
325         *SSLready = true;
326         return 0;
327 }
328
329 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
330 {
331         int rc;
332
333         rc = ssl_read(ssl, buf, len);
334         if (rc == POLARSSL_ERR_NET_WANT_READ)
335                 return SSLI_ERROR_WANT_READ;
336         return rc;
337 }
338
339 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
340 {
341         int rc;
342
343         rc = ssl_write(ssl, buf, len);
344         if (rc == POLARSSL_ERR_NET_WANT_WRITE)
345                 return SSLI_ERROR_WANT_WRITE;
346         return rc;
347 }
348
349 int SSLi_get_error(SSL_handle_t *ssl, int code)
350 {
351         return code;
352 }
353
354 bool_t SSLi_data_pending(SSL_handle_t *ssl)
355 {
356         return ssl_get_bytes_avail(ssl) > 0;
357 }
358
359 void SSLi_shutdown(SSL_handle_t *ssl)
360 {
361         ssl_close_notify(ssl);
362 }
363
364 void SSLi_free(SSL_handle_t *ssl)
365 {
366         Log_debug("SSLi_free");
367 #if (POLARSSL_VERSION_MINOR <= 2 && POLARSSL_VERSION_PATCH < 6)
368         free(ssl->session); /* Workaround for memory leak in PolarSSL < 1.2.6 */
369         ssl->session = NULL;
370 #endif
371         ssl_free(ssl);
372         free(ssl);
373 }
374