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