Add compile-time check for POLARSSL_VERSION_FEATURES before using version_get_string().
[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 #ifdef POLARSSL_VERSION_FEATURES
229     version_get_string(verstring);
230     Log_info("PolarSSL library version %s initialized", verstring);
231 #else
232     Log_info("PolarSSL library initialized");
233 #endif
234 }
235
236 void SSLi_deinit(void)
237 {
238 #ifdef POLARSSL_API_V1_3_ABOVE
239         x509_crt_free(&certificate);
240 #else
241         x509_free(&certificate);
242 #endif
243         rsa_free(&key);
244 }
245
246 /* Create SHA1 of last certificate in the peer's chain. */
247 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
248 {
249 #ifdef POLARSSL_API_V1_3_ABOVE
250         x509_crt const *cert;
251 #else
252         x509_cert const *cert;
253 #endif
254 #ifdef POLARSSL_API_V1_2_ABOVE
255         cert = ssl_get_peer_cert(ssl);
256 #else
257         cert = ssl->peer_cert;
258 #endif
259         if (!cert) {
260                 return false;
261         }
262         sha1(cert->raw.p, cert->raw.len, hash);
263         return true;
264 }
265
266 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
267 {
268         ssl_context *ssl;
269         ssl_session *ssn;
270         int rc;
271
272         ssl = calloc(1, sizeof(ssl_context));
273         ssn = calloc(1, sizeof(ssl_session));
274         if (!ssl || !ssn)
275                 Log_fatal("Out of memory");
276
277         rc = ssl_init(ssl);
278         if (rc != 0 )
279                 Log_fatal("Failed to initialize: %d", rc);
280
281         ssl_set_endpoint(ssl, SSL_IS_SERVER);
282         ssl_set_authmode(ssl, SSL_VERIFY_OPTIONAL);
283
284 #ifdef USE_POLARSSL_HAVEGE
285         ssl_set_rng(ssl, HAVEGE_RAND, &hs);
286 #else
287         ssl_set_rng(ssl, urandom_bytes, NULL);
288 #endif
289
290         ssl_set_dbg(ssl, pssl_debug, NULL);
291         ssl_set_bio(ssl, net_recv, fd, net_send, fd);
292
293         ssl_set_ciphersuites(ssl, ciphers);
294
295 #ifdef POLARSSL_API_V1_2_ABOVE
296     ssl_set_session(ssl, ssn);
297 #else
298     ssl_set_session(ssl, 0, 0, ssn);
299 #endif
300
301     ssl_set_ca_chain(ssl, &certificate, NULL, NULL);
302 #ifdef POLARSSL_API_V1_3_ABOVE
303         ssl_set_own_cert_rsa(ssl, &certificate, &key);
304 #else
305         ssl_set_own_cert(ssl, &certificate, &key);
306 #endif
307         ssl_set_dh_param(ssl, my_dhm_P, my_dhm_G);
308
309         return ssl;
310 }
311
312 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
313 {
314         int rc;
315
316         rc = ssl_handshake(ssl);
317         if (rc != 0) {
318                 if (rc == POLARSSL_ERR_NET_WANT_READ || rc == POLARSSL_ERR_NET_WANT_WRITE) {
319                         return 0;
320                 } else if (rc == POLARSSL_ERR_X509_CERT_VERIFY_FAILED) { /* Allow this (selfsigned etc) */
321                         return 0;
322                 } else {
323                         Log_warn("SSL handshake failed: %d", rc);
324                         return -1;
325                 }
326         }
327         *SSLready = true;
328         return 0;
329 }
330
331 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
332 {
333         int rc;
334
335         rc = ssl_read(ssl, buf, len);
336         if (rc == POLARSSL_ERR_NET_WANT_READ)
337                 return SSLI_ERROR_WANT_READ;
338         return rc;
339 }
340
341 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
342 {
343         int rc;
344
345         rc = ssl_write(ssl, buf, len);
346         if (rc == POLARSSL_ERR_NET_WANT_WRITE)
347                 return SSLI_ERROR_WANT_WRITE;
348         return rc;
349 }
350
351 int SSLi_get_error(SSL_handle_t *ssl, int code)
352 {
353         return code;
354 }
355
356 bool_t SSLi_data_pending(SSL_handle_t *ssl)
357 {
358         return ssl_get_bytes_avail(ssl) > 0;
359 }
360
361 void SSLi_shutdown(SSL_handle_t *ssl)
362 {
363         ssl_close_notify(ssl);
364 }
365
366 void SSLi_free(SSL_handle_t *ssl)
367 {
368         Log_debug("SSLi_free");
369 #if (POLARSSL_VERSION_MINOR <= 2 && POLARSSL_VERSION_PATCH < 6)
370         free(ssl->session); /* Workaround for memory leak in PolarSSL < 1.2.6 */
371         ssl->session = NULL;
372 #endif
373         ssl_free(ssl);
374         free(ssl);
375 }
376