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 static int s_fd_read(void *ctx, unsigned char *buf, size_t len) 89 { 90 struct uloop_fd *ufd = ctx; 91 mbedtls_net_context net = { 92 .fd = ufd->fd 93 }; 94 95 return mbedtls_net_recv(&net, buf, len); 96 } 97 98 static int s_fd_write(void *ctx, const unsigned char *buf, size_t len) 99 { 100 struct uloop_fd *ufd = ctx; 101 mbedtls_net_context net = { 102 .fd = ufd->fd 103 }; 104 105 return mbedtls_net_send(&net, buf, len); 106 } 107 108 __hidden void ustream_set_io(struct ustream_ssl *us) 109 { 110 if (us->conn) 111 mbedtls_ssl_set_bio(us->ssl, us->conn, s_ustream_write, s_ustream_read, NULL); 112 else 113 mbedtls_ssl_set_bio(us->ssl, &us->fd, s_fd_write, s_fd_read, NULL); 114 } 115 116 static int _random(void *ctx, unsigned char *out, size_t len) 117 { 118 #ifdef linux 119 if (getrandom(out, len, 0) != (ssize_t) len) 120 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; 121 #else 122 static FILE *f; 123 124 if (!f) 125 f = fopen("/dev/urandom", "r"); 126 if (fread(out, len, 1, f) != 1) 127 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; 128 #endif 129 130 return 0; 131 } 132 133 #define AES_GCM_CIPHERS(v) \ 134 MBEDTLS_TLS_##v##_WITH_AES_128_GCM_SHA256, \ 135 MBEDTLS_TLS_##v##_WITH_AES_256_GCM_SHA384 136 137 #define AES_CBC_CIPHERS(v) \ 138 MBEDTLS_TLS_##v##_WITH_AES_128_CBC_SHA, \ 139 MBEDTLS_TLS_##v##_WITH_AES_256_CBC_SHA 140 141 #define AES_CIPHERS(v) \ 142 AES_GCM_CIPHERS(v), \ 143 AES_CBC_CIPHERS(v) 144 145 static const int default_ciphersuites_server[] = 146 { 147 #ifdef MBEDTLS_SSL_PROTO_TLS1_3 148 MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256, 149 MBEDTLS_TLS1_3_AES_256_GCM_SHA384, 150 MBEDTLS_TLS1_3_AES_128_GCM_SHA256, 151 MBEDTLS_TLS1_3_AES_128_CCM_SHA256, 152 MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256, 153 #endif 154 155 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 156 AES_GCM_CIPHERS(ECDHE_ECDSA), 157 MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 158 AES_GCM_CIPHERS(ECDHE_RSA), 159 AES_CBC_CIPHERS(ECDHE_RSA), 160 AES_CIPHERS(RSA), 161 0 162 }; 163 164 static const int default_ciphersuites_client[] = 165 { 166 #ifdef MBEDTLS_SSL_PROTO_TLS1_3 167 MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256, 168 MBEDTLS_TLS1_3_AES_256_GCM_SHA384, 169 MBEDTLS_TLS1_3_AES_128_GCM_SHA256, 170 MBEDTLS_TLS1_3_AES_128_CCM_SHA256, 171 MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256, 172 #endif 173 174 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 175 AES_GCM_CIPHERS(ECDHE_ECDSA), 176 MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 177 AES_GCM_CIPHERS(ECDHE_RSA), 178 MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 179 AES_GCM_CIPHERS(DHE_RSA), 180 AES_CBC_CIPHERS(ECDHE_ECDSA), 181 AES_CBC_CIPHERS(ECDHE_RSA), 182 AES_CBC_CIPHERS(DHE_RSA), 183 /* Removed in Mbed TLS 3.0.0 */ 184 #ifdef MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 185 MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 186 #endif 187 AES_CIPHERS(RSA), 188 /* Removed in Mbed TLS 3.0.0 */ 189 #ifdef MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA 190 MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, 191 #endif 192 0 193 }; 194 195 196 __hidden struct ustream_ssl_ctx * 197 __ustream_ssl_context_new(bool server) 198 { 199 struct ustream_ssl_ctx *ctx; 200 mbedtls_ssl_config *conf; 201 int ep; 202 203 #ifdef MBEDTLS_PSA_CRYPTO_C 204 static bool psa_init; 205 206 if (!psa_init && !psa_crypto_init()) 207 psa_init = true; 208 #endif 209 210 ctx = calloc(1, sizeof(*ctx)); 211 if (!ctx) 212 return NULL; 213 214 ctx->server = server; 215 mbedtls_pk_init(&ctx->key); 216 mbedtls_x509_crt_init(&ctx->cert); 217 mbedtls_x509_crt_init(&ctx->ca_cert); 218 219 #if defined(MBEDTLS_SSL_CACHE_C) 220 mbedtls_ssl_cache_init(&ctx->cache); 221 mbedtls_ssl_cache_set_timeout(&ctx->cache, 30 * 60); 222 mbedtls_ssl_cache_set_max_entries(&ctx->cache, 5); 223 #endif 224 225 conf = &ctx->conf; 226 mbedtls_ssl_config_init(conf); 227 228 ep = server ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT; 229 230 mbedtls_ssl_config_defaults(conf, ep, MBEDTLS_SSL_TRANSPORT_STREAM, 231 MBEDTLS_SSL_PRESET_DEFAULT); 232 mbedtls_ssl_conf_rng(conf, _random, NULL); 233 234 if (server) { 235 mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_NONE); 236 mbedtls_ssl_conf_ciphersuites(conf, default_ciphersuites_server); 237 mbedtls_ssl_conf_min_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, 238 MBEDTLS_SSL_MINOR_VERSION_3); 239 } else { 240 mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_OPTIONAL); 241 mbedtls_ssl_conf_ciphersuites(conf, default_ciphersuites_client); 242 } 243 244 #if defined(MBEDTLS_SSL_CACHE_C) 245 mbedtls_ssl_conf_session_cache(conf, &ctx->cache, 246 mbedtls_ssl_cache_get, 247 mbedtls_ssl_cache_set); 248 #endif 249 return ctx; 250 } 251 252 static void ustream_ssl_update_own_cert(struct ustream_ssl_ctx *ctx) 253 { 254 if (!ctx->cert.version) 255 return; 256 257 if (mbedtls_pk_get_type(&ctx->key) == MBEDTLS_PK_NONE) 258 return; 259 260 mbedtls_ssl_conf_own_cert(&ctx->conf, &ctx->cert, &ctx->key); 261 } 262 263 __hidden int __ustream_ssl_add_ca_crt_file(struct ustream_ssl_ctx *ctx, const char *file) 264 { 265 int ret; 266 267 ret = mbedtls_x509_crt_parse_file(&ctx->ca_cert, file); 268 if (ret) 269 return -1; 270 271 mbedtls_ssl_conf_ca_chain(&ctx->conf, &ctx->ca_cert, NULL); 272 mbedtls_ssl_conf_authmode(&ctx->conf, MBEDTLS_SSL_VERIFY_OPTIONAL); 273 return 0; 274 } 275 276 __hidden int __ustream_ssl_set_crt_file(struct ustream_ssl_ctx *ctx, const char *file) 277 { 278 int ret; 279 280 ret = mbedtls_x509_crt_parse_file(&ctx->cert, file); 281 if (ret) 282 return -1; 283 284 ustream_ssl_update_own_cert(ctx); 285 return 0; 286 } 287 288 __hidden int __ustream_ssl_set_key_file(struct ustream_ssl_ctx *ctx, const char *file) 289 { 290 int ret; 291 292 #if (MBEDTLS_VERSION_NUMBER >= 0x03000000) 293 ret = mbedtls_pk_parse_keyfile(&ctx->key, file, NULL, _random, NULL); 294 #else 295 ret = mbedtls_pk_parse_keyfile(&ctx->key, file, NULL); 296 #endif 297 if (ret) 298 return -1; 299 300 ustream_ssl_update_own_cert(ctx); 301 return 0; 302 } 303 304 __hidden int __ustream_ssl_set_ciphers(struct ustream_ssl_ctx *ctx, const char *ciphers) 305 { 306 int *ciphersuites = NULL, *tmp, id; 307 char *cipherstr, *p, *last, c; 308 size_t len = 0; 309 310 if (ciphers == NULL) 311 return -1; 312 313 cipherstr = strdup(ciphers); 314 315 if (cipherstr == NULL) 316 return -1; 317 318 for (p = cipherstr, last = p;; p++) { 319 if (*p == ':' || *p == 0) { 320 c = *p; 321 *p = 0; 322 323 id = mbedtls_ssl_get_ciphersuite_id(last); 324 325 if (id != 0) { 326 tmp = realloc(ciphersuites, (len + 2) * sizeof(int)); 327 328 if (tmp == NULL) { 329 free(ciphersuites); 330 free(cipherstr); 331 332 return -1; 333 } 334 335 ciphersuites = tmp; 336 ciphersuites[len++] = id; 337 ciphersuites[len] = 0; 338 } 339 340 if (c == 0) 341 break; 342 343 last = p + 1; 344 } 345 346 /* 347 * mbedTLS expects cipher names with dashes while many sources elsewhere 348 * like the Firefox wiki or Wireshark specify ciphers with underscores, 349 * so simply convert all underscores to dashes to accept both notations. 350 */ 351 else if (*p == '_') { 352 *p = '-'; 353 } 354 } 355 356 free(cipherstr); 357 358 if (len == 0) 359 return -1; 360 361 mbedtls_ssl_conf_ciphersuites(&ctx->conf, ciphersuites); 362 free(ctx->ciphersuites); 363 364 ctx->ciphersuites = ciphersuites; 365 366 return 0; 367 } 368 369 __hidden int __ustream_ssl_set_require_validation(struct ustream_ssl_ctx *ctx, bool require) 370 { 371 int mode = MBEDTLS_SSL_VERIFY_OPTIONAL; 372 373 if (!require) 374 mode = MBEDTLS_SSL_VERIFY_NONE; 375 376 /* force TLS 1.2 when not requiring validation for now */ 377 if (!require && !ctx->server) 378 mbedtls_ssl_conf_max_version(&ctx->conf, MBEDTLS_SSL_MAJOR_VERSION_3, 379 MBEDTLS_SSL_MINOR_VERSION_3); 380 mbedtls_ssl_conf_authmode(&ctx->conf, mode); 381 382 return 0; 383 } 384 385 __hidden void __ustream_ssl_context_free(struct ustream_ssl_ctx *ctx) 386 { 387 free(ctx->session_data); 388 #if defined(MBEDTLS_SSL_CACHE_C) 389 mbedtls_ssl_cache_free(&ctx->cache); 390 #endif 391 mbedtls_pk_free(&ctx->key); 392 mbedtls_x509_crt_free(&ctx->ca_cert); 393 mbedtls_x509_crt_free(&ctx->cert); 394 mbedtls_ssl_config_free(&ctx->conf); 395 free(ctx->ciphersuites); 396 free(ctx); 397 } 398 399 static void ustream_ssl_error(struct ustream_ssl *us, int ret) 400 { 401 us->error = ret; 402 uloop_timeout_set(&us->error_timer, 0); 403 } 404 405 #ifdef MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET 406 static void 407 __ustream_ssl_save_session(struct ustream_ssl *us) 408 { 409 struct ustream_ssl_ctx *ctx = us->ctx; 410 mbedtls_ssl_session sess; 411 412 if (ctx->server) 413 return; 414 415 free(ctx->session_data); 416 ctx->session_data = NULL; 417 418 mbedtls_ssl_session_init(&sess); 419 if (mbedtls_ssl_get_session(us->ssl, &sess) != 0) 420 return; 421 422 mbedtls_ssl_session_save(&sess, NULL, 0, &ctx->session_data_len); 423 ctx->session_data = malloc(ctx->session_data_len); 424 if (mbedtls_ssl_session_save(&sess, ctx->session_data, ctx->session_data_len, 425 &ctx->session_data_len)) 426 ctx->session_data_len = 0; 427 mbedtls_ssl_session_free(&sess); 428 } 429 #endif 430 431 static int ssl_check_return(struct ustream_ssl *us, int ret) 432 { 433 switch(ret) { 434 case MBEDTLS_ERR_SSL_WANT_READ: 435 case MBEDTLS_ERR_SSL_WANT_WRITE: 436 return U_SSL_PENDING; 437 #ifdef MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET 438 case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET: 439 __ustream_ssl_save_session(us); 440 return U_SSL_RETRY; 441 #endif 442 #ifdef MBEDTLS_ECP_RESTARTABLE 443 case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS: 444 return U_SSL_RETRY; 445 #endif 446 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: 447 case MBEDTLS_ERR_NET_CONN_RESET: 448 return 0; 449 default: 450 ustream_ssl_error(us, ret); 451 return U_SSL_ERROR; 452 } 453 } 454 455 static void ustream_ssl_verify_cert(struct ustream_ssl *us) 456 { 457 void *ssl = us->ssl; 458 const char *msg = NULL; 459 bool cn_mismatch; 460 int r; 461 462 r = mbedtls_ssl_get_verify_result(ssl); 463 cn_mismatch = r & MBEDTLS_X509_BADCERT_CN_MISMATCH; 464 r &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH; 465 466 if (r & MBEDTLS_X509_BADCERT_EXPIRED) 467 msg = "certificate has expired"; 468 else if (r & MBEDTLS_X509_BADCERT_REVOKED) 469 msg = "certificate has been revoked"; 470 else if (r & MBEDTLS_X509_BADCERT_NOT_TRUSTED) 471 msg = "certificate is self-signed or not signed by a trusted CA"; 472 else 473 msg = "unknown error"; 474 475 if (r) { 476 if (us->notify_verify_error) 477 us->notify_verify_error(us, r, msg); 478 return; 479 } 480 481 if (!cn_mismatch) 482 us->valid_cn = true; 483 } 484 485 __hidden enum ssl_conn_status __ustream_ssl_connect(struct ustream_ssl *us) 486 { 487 void *ssl = us->ssl; 488 int r; 489 490 do { 491 r = mbedtls_ssl_handshake(ssl); 492 if (r == 0) { 493 ustream_ssl_verify_cert(us); 494 return U_SSL_OK; 495 } 496 497 r = ssl_check_return(us, r); 498 } while (r == U_SSL_RETRY); 499 500 return r; 501 } 502 503 __hidden int __ustream_ssl_write(struct ustream_ssl *us, const char *buf, int len) 504 { 505 void *ssl = us->ssl; 506 int done = 0, ret = 0; 507 508 while (done != len) { 509 ret = mbedtls_ssl_write(ssl, (const unsigned char *) buf + done, len - done); 510 if (ret < 0) { 511 ret = ssl_check_return(us, ret); 512 if (ret == U_SSL_RETRY) 513 continue; 514 515 if (ret == U_SSL_PENDING) 516 return done; 517 518 return -1; 519 } 520 521 done += ret; 522 } 523 524 return done; 525 } 526 527 __hidden int __ustream_ssl_read(struct ustream_ssl *us, char *buf, int len) 528 { 529 int ret; 530 531 do { 532 ret = mbedtls_ssl_read(us->ssl, (unsigned char *) buf, len); 533 if (ret >= 0) 534 return ret; 535 536 ret = ssl_check_return(us, ret); 537 } while (ret == U_SSL_RETRY); 538 539 return ret; 540 } 541 542 __hidden void __ustream_ssl_set_debug(struct ustream_ssl_ctx *ctx, int level, 543 ustream_ssl_debug_cb cb, void *cb_priv) 544 { 545 ctx->debug_cb = cb; 546 ctx->debug_cb_priv = cb_priv; 547 mbedtls_ssl_conf_dbg(&ctx->conf, debug_cb, ctx); 548 #ifdef MBEDTLS_DEBUG_C 549 mbedtls_debug_set_threshold(level); 550 #endif 551 } 552 553 __hidden void *__ustream_ssl_session_new(struct ustream_ssl_ctx *ctx) 554 { 555 mbedtls_ssl_context *ssl; 556 mbedtls_ssl_session sess; 557 558 ssl = calloc(1, sizeof(*ssl)); 559 if (!ssl) 560 return NULL; 561 562 mbedtls_ssl_init(ssl); 563 564 if (mbedtls_ssl_setup(ssl, &ctx->conf)) { 565 free(ssl); 566 return NULL; 567 } 568 569 if (!ctx->session_data_len) 570 return ssl; 571 572 mbedtls_ssl_session_init(&sess); 573 if (mbedtls_ssl_session_load(&sess, ctx->session_data, ctx->session_data_len) == 0) 574 mbedtls_ssl_set_session(ssl, &sess); 575 576 return ssl; 577 } 578 579 __hidden void __ustream_ssl_session_free(struct ustream_ssl *us) 580 { 581 mbedtls_ssl_free(us->ssl); 582 free(us->ssl); 583 } 584
This page was automatically generated by LXR 0.3.1. • OpenWrt