mbedtls: disable TLS 1.3 in client mode when skipping verification
[project/ustream-ssl.git] / ustream-mbedtls.c
1 /*
2 * ustream-ssl - library for SSL over ustream
3 *
4 * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <sys/types.h>
20 #include <sys/random.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "ustream-ssl.h"
27 #include "ustream-internal.h"
28 #include <psa/crypto.h>
29 #include <mbedtls/debug.h>
30
31 static void debug_cb(void *ctx_p, int level,
32 const char *file, int line,
33 const char *str)
34 {
35 struct ustream_ssl_ctx *ctx = ctx_p;
36 const char *fstr;
37 char buf[512];
38 int len;
39
40 if (!ctx->debug_cb)
41 return;
42
43 while ((fstr = strstr(file + 1, "library/")) != NULL)
44 file = fstr;
45
46 len = snprintf(buf, sizeof(buf), "%s:%04d: %s", file, line, str);
47 if (len >= (int)sizeof(buf))
48 len = (int)sizeof(buf) - 1;
49 if (buf[len - 1] == '\n')
50 buf[len - 1] = 0;
51 ctx->debug_cb(ctx->debug_cb_priv, level, buf);
52 }
53
54 static int s_ustream_read(void *ctx, unsigned char *buf, size_t len)
55 {
56 struct ustream *s = ctx;
57 char *sbuf;
58 int slen;
59
60 if (s->eof)
61 return 0;
62
63 sbuf = ustream_get_read_buf(s, &slen);
64 if ((size_t) slen > len)
65 slen = len;
66
67 if (!slen)
68 return MBEDTLS_ERR_SSL_WANT_READ;
69
70 memcpy(buf, sbuf, slen);
71 ustream_consume(s, slen);
72
73 return slen;
74 }
75
76 static int s_ustream_write(void *ctx, const unsigned char *buf, size_t len)
77 {
78 struct ustream *s = ctx;
79 int ret;
80
81 ret = ustream_write(s, (const char *) buf, len, false);
82 if (ret < 0 || s->write_error)
83 return MBEDTLS_ERR_NET_SEND_FAILED;
84
85 return ret;
86 }
87
88 __hidden void ustream_set_io(struct ustream_ssl_ctx *ctx, void *ssl, struct ustream *conn)
89 {
90 mbedtls_ssl_set_bio(ssl, conn, s_ustream_write, s_ustream_read, NULL);
91 }
92
93 static int _random(void *ctx, unsigned char *out, size_t len)
94 {
95 #ifdef linux
96 if (getrandom(out, len, 0) != (ssize_t) len)
97 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
98 #else
99 static FILE *f;
100
101 if (!f)
102 f = fopen("/dev/urandom", "r");
103 if (fread(out, len, 1, f) != 1)
104 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
105 #endif
106
107 return 0;
108 }
109
110 #define AES_GCM_CIPHERS(v) \
111 MBEDTLS_TLS_##v##_WITH_AES_128_GCM_SHA256, \
112 MBEDTLS_TLS_##v##_WITH_AES_256_GCM_SHA384
113
114 #define AES_CBC_CIPHERS(v) \
115 MBEDTLS_TLS_##v##_WITH_AES_128_CBC_SHA, \
116 MBEDTLS_TLS_##v##_WITH_AES_256_CBC_SHA
117
118 #define AES_CIPHERS(v) \
119 AES_GCM_CIPHERS(v), \
120 AES_CBC_CIPHERS(v)
121
122 static const int default_ciphersuites_server[] =
123 {
124 #ifdef MBEDTLS_SSL_PROTO_TLS1_3
125 MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256,
126 MBEDTLS_TLS1_3_AES_256_GCM_SHA384,
127 MBEDTLS_TLS1_3_AES_128_GCM_SHA256,
128 MBEDTLS_TLS1_3_AES_128_CCM_SHA256,
129 MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256,
130 #endif
131
132 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
133 AES_GCM_CIPHERS(ECDHE_ECDSA),
134 MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
135 AES_GCM_CIPHERS(ECDHE_RSA),
136 AES_CBC_CIPHERS(ECDHE_RSA),
137 AES_CIPHERS(RSA),
138 0
139 };
140
141 static const int default_ciphersuites_client[] =
142 {
143 #ifdef MBEDTLS_SSL_PROTO_TLS1_3
144 MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256,
145 MBEDTLS_TLS1_3_AES_256_GCM_SHA384,
146 MBEDTLS_TLS1_3_AES_128_GCM_SHA256,
147 MBEDTLS_TLS1_3_AES_128_CCM_SHA256,
148 MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256,
149 #endif
150
151 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
152 AES_GCM_CIPHERS(ECDHE_ECDSA),
153 MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
154 AES_GCM_CIPHERS(ECDHE_RSA),
155 MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
156 AES_GCM_CIPHERS(DHE_RSA),
157 AES_CBC_CIPHERS(ECDHE_ECDSA),
158 AES_CBC_CIPHERS(ECDHE_RSA),
159 AES_CBC_CIPHERS(DHE_RSA),
160 /* Removed in Mbed TLS 3.0.0 */
161 #ifdef MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
162 MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
163 #endif
164 AES_CIPHERS(RSA),
165 /* Removed in Mbed TLS 3.0.0 */
166 #ifdef MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
167 MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
168 #endif
169 0
170 };
171
172
173 __hidden struct ustream_ssl_ctx *
174 __ustream_ssl_context_new(bool server)
175 {
176 struct ustream_ssl_ctx *ctx;
177 mbedtls_ssl_config *conf;
178 int ep;
179
180 #ifdef MBEDTLS_PSA_CRYPTO_C
181 static bool psa_init;
182
183 if (!psa_init && !psa_crypto_init())
184 psa_init = true;
185 #endif
186
187 ctx = calloc(1, sizeof(*ctx));
188 if (!ctx)
189 return NULL;
190
191 ctx->server = server;
192 mbedtls_pk_init(&ctx->key);
193 mbedtls_x509_crt_init(&ctx->cert);
194 mbedtls_x509_crt_init(&ctx->ca_cert);
195
196 #if defined(MBEDTLS_SSL_CACHE_C)
197 mbedtls_ssl_cache_init(&ctx->cache);
198 mbedtls_ssl_cache_set_timeout(&ctx->cache, 30 * 60);
199 mbedtls_ssl_cache_set_max_entries(&ctx->cache, 5);
200 #endif
201
202 conf = &ctx->conf;
203 mbedtls_ssl_config_init(conf);
204
205 ep = server ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT;
206
207 mbedtls_ssl_config_defaults(conf, ep, MBEDTLS_SSL_TRANSPORT_STREAM,
208 MBEDTLS_SSL_PRESET_DEFAULT);
209 mbedtls_ssl_conf_rng(conf, _random, NULL);
210
211 if (server) {
212 mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_NONE);
213 mbedtls_ssl_conf_ciphersuites(conf, default_ciphersuites_server);
214 mbedtls_ssl_conf_min_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3,
215 MBEDTLS_SSL_MINOR_VERSION_3);
216 } else {
217 mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
218 mbedtls_ssl_conf_ciphersuites(conf, default_ciphersuites_client);
219 }
220
221 #if defined(MBEDTLS_SSL_CACHE_C)
222 mbedtls_ssl_conf_session_cache(conf, &ctx->cache,
223 mbedtls_ssl_cache_get,
224 mbedtls_ssl_cache_set);
225 #endif
226 return ctx;
227 }
228
229 static void ustream_ssl_update_own_cert(struct ustream_ssl_ctx *ctx)
230 {
231 if (!ctx->cert.version)
232 return;
233
234 if (mbedtls_pk_get_type(&ctx->key) == MBEDTLS_PK_NONE)
235 return;
236
237 mbedtls_ssl_conf_own_cert(&ctx->conf, &ctx->cert, &ctx->key);
238 }
239
240 __hidden int __ustream_ssl_add_ca_crt_file(struct ustream_ssl_ctx *ctx, const char *file)
241 {
242 int ret;
243
244 ret = mbedtls_x509_crt_parse_file(&ctx->ca_cert, file);
245 if (ret)
246 return -1;
247
248 mbedtls_ssl_conf_ca_chain(&ctx->conf, &ctx->ca_cert, NULL);
249 mbedtls_ssl_conf_authmode(&ctx->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
250 return 0;
251 }
252
253 __hidden int __ustream_ssl_set_crt_file(struct ustream_ssl_ctx *ctx, const char *file)
254 {
255 int ret;
256
257 ret = mbedtls_x509_crt_parse_file(&ctx->cert, file);
258 if (ret)
259 return -1;
260
261 ustream_ssl_update_own_cert(ctx);
262 return 0;
263 }
264
265 __hidden int __ustream_ssl_set_key_file(struct ustream_ssl_ctx *ctx, const char *file)
266 {
267 int ret;
268
269 #if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
270 ret = mbedtls_pk_parse_keyfile(&ctx->key, file, NULL, _random, NULL);
271 #else
272 ret = mbedtls_pk_parse_keyfile(&ctx->key, file, NULL);
273 #endif
274 if (ret)
275 return -1;
276
277 ustream_ssl_update_own_cert(ctx);
278 return 0;
279 }
280
281 __hidden int __ustream_ssl_set_ciphers(struct ustream_ssl_ctx *ctx, const char *ciphers)
282 {
283 int *ciphersuites = NULL, *tmp, id;
284 char *cipherstr, *p, *last, c;
285 size_t len = 0;
286
287 if (ciphers == NULL)
288 return -1;
289
290 cipherstr = strdup(ciphers);
291
292 if (cipherstr == NULL)
293 return -1;
294
295 for (p = cipherstr, last = p;; p++) {
296 if (*p == ':' || *p == 0) {
297 c = *p;
298 *p = 0;
299
300 id = mbedtls_ssl_get_ciphersuite_id(last);
301
302 if (id != 0) {
303 tmp = realloc(ciphersuites, (len + 2) * sizeof(int));
304
305 if (tmp == NULL) {
306 free(ciphersuites);
307 free(cipherstr);
308
309 return -1;
310 }
311
312 ciphersuites = tmp;
313 ciphersuites[len++] = id;
314 ciphersuites[len] = 0;
315 }
316
317 if (c == 0)
318 break;
319
320 last = p + 1;
321 }
322
323 /*
324 * mbedTLS expects cipher names with dashes while many sources elsewhere
325 * like the Firefox wiki or Wireshark specify ciphers with underscores,
326 * so simply convert all underscores to dashes to accept both notations.
327 */
328 else if (*p == '_') {
329 *p = '-';
330 }
331 }
332
333 free(cipherstr);
334
335 if (len == 0)
336 return -1;
337
338 mbedtls_ssl_conf_ciphersuites(&ctx->conf, ciphersuites);
339 free(ctx->ciphersuites);
340
341 ctx->ciphersuites = ciphersuites;
342
343 return 0;
344 }
345
346 __hidden int __ustream_ssl_set_require_validation(struct ustream_ssl_ctx *ctx, bool require)
347 {
348 int mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
349
350 if (!require)
351 mode = MBEDTLS_SSL_VERIFY_NONE;
352
353 /* force TLS 1.2 when not requiring validation for now */
354 if (!require && !ctx->server)
355 mbedtls_ssl_conf_max_version(&ctx->conf, MBEDTLS_SSL_MAJOR_VERSION_3,
356 MBEDTLS_SSL_MINOR_VERSION_3);
357 mbedtls_ssl_conf_authmode(&ctx->conf, mode);
358
359 return 0;
360 }
361
362 __hidden void __ustream_ssl_context_free(struct ustream_ssl_ctx *ctx)
363 {
364 #if defined(MBEDTLS_SSL_CACHE_C)
365 mbedtls_ssl_cache_free(&ctx->cache);
366 #endif
367 mbedtls_pk_free(&ctx->key);
368 mbedtls_x509_crt_free(&ctx->ca_cert);
369 mbedtls_x509_crt_free(&ctx->cert);
370 mbedtls_ssl_config_free(&ctx->conf);
371 free(ctx->ciphersuites);
372 free(ctx);
373 }
374
375 static void ustream_ssl_error(struct ustream_ssl *us, int ret)
376 {
377 us->error = ret;
378 uloop_timeout_set(&us->error_timer, 0);
379 }
380
381 static bool ssl_do_wait(int ret)
382 {
383 switch(ret) {
384 case MBEDTLS_ERR_SSL_WANT_READ:
385 case MBEDTLS_ERR_SSL_WANT_WRITE:
386 return true;
387 default:
388 return false;
389 }
390 }
391
392 static void ustream_ssl_verify_cert(struct ustream_ssl *us)
393 {
394 void *ssl = us->ssl;
395 const char *msg = NULL;
396 bool cn_mismatch;
397 int r;
398
399 r = mbedtls_ssl_get_verify_result(ssl);
400 cn_mismatch = r & MBEDTLS_X509_BADCERT_CN_MISMATCH;
401 r &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH;
402
403 if (r & MBEDTLS_X509_BADCERT_EXPIRED)
404 msg = "certificate has expired";
405 else if (r & MBEDTLS_X509_BADCERT_REVOKED)
406 msg = "certificate has been revoked";
407 else if (r & MBEDTLS_X509_BADCERT_NOT_TRUSTED)
408 msg = "certificate is self-signed or not signed by a trusted CA";
409 else
410 msg = "unknown error";
411
412 if (r) {
413 if (us->notify_verify_error)
414 us->notify_verify_error(us, r, msg);
415 return;
416 }
417
418 if (!cn_mismatch)
419 us->valid_cn = true;
420 }
421
422 __hidden enum ssl_conn_status __ustream_ssl_connect(struct ustream_ssl *us)
423 {
424 void *ssl = us->ssl;
425 int r;
426
427 r = mbedtls_ssl_handshake(ssl);
428 if (r == 0) {
429 ustream_ssl_verify_cert(us);
430 return U_SSL_OK;
431 }
432
433 if (ssl_do_wait(r))
434 return U_SSL_PENDING;
435
436 ustream_ssl_error(us, r);
437 return U_SSL_ERROR;
438 }
439
440 __hidden int __ustream_ssl_write(struct ustream_ssl *us, const char *buf, int len)
441 {
442 void *ssl = us->ssl;
443 int done = 0, ret = 0;
444
445 while (done != len) {
446 ret = mbedtls_ssl_write(ssl, (const unsigned char *) buf + done, len - done);
447
448 if (ret < 0) {
449 if (ssl_do_wait(ret))
450 return done;
451
452 ustream_ssl_error(us, ret);
453 return -1;
454 }
455
456 done += ret;
457 }
458
459 return done;
460 }
461
462 __hidden int __ustream_ssl_read(struct ustream_ssl *us, char *buf, int len)
463 {
464 int ret = mbedtls_ssl_read(us->ssl, (unsigned char *) buf, len);
465
466 if (ret < 0) {
467 if (ssl_do_wait(ret))
468 return U_SSL_PENDING;
469
470 if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
471 return 0;
472
473 ustream_ssl_error(us, ret);
474 return U_SSL_ERROR;
475 }
476
477 return ret;
478 }
479
480 __hidden void __ustream_ssl_set_debug(struct ustream_ssl_ctx *ctx, int level,
481 ustream_ssl_debug_cb cb, void *cb_priv)
482 {
483 ctx->debug_cb = cb;
484 ctx->debug_cb_priv = cb_priv;
485 mbedtls_ssl_conf_dbg(&ctx->conf, debug_cb, ctx);
486 mbedtls_debug_set_threshold(level);
487 }
488
489 __hidden void *__ustream_ssl_session_new(struct ustream_ssl_ctx *ctx)
490 {
491 mbedtls_ssl_context *ssl;
492
493 ssl = calloc(1, sizeof(*ssl));
494 if (!ssl)
495 return NULL;
496
497 mbedtls_ssl_init(ssl);
498
499 if (mbedtls_ssl_setup(ssl, &ctx->conf)) {
500 free(ssl);
501 return NULL;
502 }
503
504 return ssl;
505 }
506
507 __hidden void __ustream_ssl_session_free(void *ssl)
508 {
509 mbedtls_ssl_free(ssl);
510 free(ssl);
511 }