diff options
author | Dirk Engling <erdgeist@erdgeist.org> | 2022-05-20 23:39:50 +0200 |
---|---|---|
committer | Dirk Engling <erdgeist@erdgeist.org> | 2022-05-20 23:39:50 +0200 |
commit | ee2b2043cf49560e70eb6a62fc883e5073bd2a92 (patch) | |
tree | 7f6cf766dda3587599eed689e6724cd0e8033190 /vchat-tls.c | |
parent | 7632890682859f37c873e7cd779fe28fcbe4ef3d (diff) |
Check pinned fingerprints and add much more error checks
Diffstat (limited to 'vchat-tls.c')
-rwxr-xr-x | vchat-tls.c | 130 |
1 files changed, 91 insertions, 39 deletions
diff --git a/vchat-tls.c b/vchat-tls.c index bb139f1..1156494 100755 --- a/vchat-tls.c +++ b/vchat-tls.c | |||
@@ -405,6 +405,7 @@ void vc_tls_cleanup() { | |||
405 | #include <mbedtls/ctr_drbg.h> | 405 | #include <mbedtls/ctr_drbg.h> |
406 | #include <mbedtls/x509.h> | 406 | #include <mbedtls/x509.h> |
407 | #include <mbedtls/pk.h> | 407 | #include <mbedtls/pk.h> |
408 | #include <mbedtls/md.h> | ||
408 | #include <mbedtls/debug.h> | 409 | #include <mbedtls/debug.h> |
409 | #include "mbedtls/error.h" | 410 | #include "mbedtls/error.h" |
410 | 411 | ||
@@ -454,7 +455,7 @@ void vc_init_x509store(vc_x509store_t *store) | |||
454 | } | 455 | } |
455 | 456 | ||
456 | static void vc_tls_report_error(int error, char *message) { | 457 | static void vc_tls_report_error(int error, char *message) { |
457 | size_t used = snprintf(tmpstr, sizeof(tmpstr), "%s", message); | 458 | size_t used = snprintf(tmpstr, sizeof(tmpstr), "Error: %s", message); |
458 | mbedtls_strerror(error, tmpstr + used, sizeof(tmpstr) - used); | 459 | mbedtls_strerror(error, tmpstr + used, sizeof(tmpstr) - used); |
459 | writecf(FS_ERR, tmpstr); | 460 | writecf(FS_ERR, tmpstr); |
460 | } | 461 | } |
@@ -466,7 +467,8 @@ int vc_tls_connect( int serverfd, vc_x509store_t *vc_store ) | |||
466 | mbedtls_ssl_config *conf = &_mbedtls_state._conf; | 467 | mbedtls_ssl_config *conf = &_mbedtls_state._conf; |
467 | mbedtls_ssl_context *ssl = &_mbedtls_state._ssl; | 468 | mbedtls_ssl_context *ssl = &_mbedtls_state._ssl; |
468 | int ret, suitecount = 0; | 469 | int ret, suitecount = 0; |
469 | char *token; | 470 | char fingerprint[128], *token; |
471 | uint8_t digest[20]; | ||
470 | 472 | ||
471 | mbedtls_x509_crt_init(&s->_cacert); | 473 | mbedtls_x509_crt_init(&s->_cacert); |
472 | mbedtls_x509_crt_init(&s->_cert); | 474 | mbedtls_x509_crt_init(&s->_cert); |
@@ -474,8 +476,11 @@ int vc_tls_connect( int serverfd, vc_x509store_t *vc_store ) | |||
474 | mbedtls_ssl_init(ssl); | 476 | mbedtls_ssl_init(ssl); |
475 | mbedtls_ssl_config_init(conf); | 477 | mbedtls_ssl_config_init(conf); |
476 | 478 | ||
477 | if (mbedtls_ssl_config_defaults(conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) { | 479 | writecf(FS_SERV, "[SOCKET CONNECTED ]"); |
478 | writecf(FS_ERR, "Out of memory"); | 480 | writecf(FS_SERV, "[UPGRADING TO TLS ]"); |
481 | |||
482 | if ((ret = mbedtls_ssl_config_defaults(conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { | ||
483 | vc_tls_report_error(ret, "Can not initialise tls parameters, mbedtls reports: "); | ||
479 | return -1; | 484 | return -1; |
480 | } | 485 | } |
481 | 486 | ||
@@ -500,74 +505,121 @@ int vc_tls_connect( int serverfd, vc_x509store_t *vc_store ) | |||
500 | mbedtls_ssl_conf_ciphersuites(conf, s->ciphersuits); | 505 | mbedtls_ssl_conf_ciphersuites(conf, s->ciphersuits); |
501 | 506 | ||
502 | if (vc_store->cafile) { | 507 | if (vc_store->cafile) { |
503 | mbedtls_x509_crt_parse_file(&s->_cacert, vc_store->cafile); | 508 | if ((ret = mbedtls_x509_crt_parse_file(&s->_cacert, vc_store->cafile)) != 0) { |
509 | vc_tls_report_error(ret, "Can not load CA cert, mbedtls reports: "); | ||
510 | return -1; | ||
511 | } | ||
504 | mbedtls_ssl_conf_ca_chain(conf, &s->_cacert, NULL); | 512 | mbedtls_ssl_conf_ca_chain(conf, &s->_cacert, NULL); |
513 | writecf(FS_SERV, "[CA CERT LOADED ]"); | ||
505 | } | 514 | } |
506 | 515 | ||
507 | mbedtls_x509_crt_parse_file(&s->_cert, vc_store->certfile); | 516 | if (vc_store->flags & VC_X509S_USE_CERTIFICATE) { |
508 | char *password = NULL; | 517 | char *password = NULL; |
509 | char password_buf[1024]; | 518 | char password_buf[1024]; |
510 | while (1) { | 519 | |
511 | ret = mbedtls_pk_parse_keyfile(&s->_key, vc_store->keyfile, password | 520 | if ((ret = mbedtls_x509_crt_parse_file(&s->_cert, vc_store->certfile)) != 0) { |
521 | vc_tls_report_error(ret, "Can not load client cert, mbedtls reports: "); | ||
522 | return -1; | ||
523 | } | ||
524 | writecf(FS_SERV, "[CLIENT CERT LOADED ]"); | ||
525 | |||
526 | while (1) { | ||
527 | if ((ret = mbedtls_pk_parse_keyfile(&s->_key, vc_store->keyfile, password | ||
512 | #if MBEDTLS_VERSION_MAJOR >= 3 | 528 | #if MBEDTLS_VERSION_MAJOR >= 3 |
513 | , mbedtls_ctr_drbg_random, &s->_ctr_drbg | 529 | , mbedtls_ctr_drbg_random, &s->_ctr_drbg |
514 | #endif | 530 | #endif |
515 | ); | 531 | )) == 0) |
516 | if (!ret) | 532 | break; |
517 | break; | 533 | if (ret != MBEDTLS_ERR_PK_PASSWORD_REQUIRED && ret != MBEDTLS_ERR_PK_PASSWORD_MISMATCH) { |
518 | if (ret != MBEDTLS_ERR_PK_PASSWORD_REQUIRED && ret != MBEDTLS_ERR_PK_PASSWORD_MISMATCH) { | 534 | vc_tls_report_error(ret, "Can not load client key, mbedtls reports: "); |
519 | vc_tls_report_error(ret, "CREATE CTX: Loading key failed, mbedtls reports: "); | 535 | return -1; |
520 | return -1; | 536 | } |
537 | if (ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH) | ||
538 | vc_tls_report_error(ret, "Wrong passphrase, mbedtls reports: "); | ||
539 | vc_store->askpass_callback(password_buf, sizeof(password_buf), 0, NULL); | ||
540 | password = password_buf; | ||
521 | } | 541 | } |
522 | if (ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH) | 542 | memset_s(password_buf, sizeof(password_buf), 0, sizeof(password_buf)); |
523 | vc_tls_report_error(ret, "Wrong passphrase, mbedtls reports: "); | 543 | writecf(FS_SERV, "[CLIENT KEY LOADED ]"); |
524 | vc_store->askpass_callback(password_buf, sizeof(password_buf), 0, NULL); | 544 | |
525 | password = password_buf; | ||
526 | } | ||
527 | memset_s(password_buf, sizeof(password_buf), 0, sizeof(password_buf)); | ||
528 | 545 | ||
529 | #if MBEDTLS_VERSION_MAJOR == 3 && MBEDTLS_VERSION_MINOR == 0 | 546 | #if MBEDTLS_VERSION_MAJOR == 3 && MBEDTLS_VERSION_MINOR == 0 |
530 | if ((ret = mbedtls_pk_check_pair(&(s->_cert.MBEDTLS_PRIVATE(pk)), &s->_key | 547 | mbedtls_pk_context *pubkey = &(s->_cert.MBEDTLS_PRIVATE(pk)); |
531 | #else | 548 | #else |
532 | if ((ret = mbedtls_pk_check_pair(&(s->_cert.pk), &s->_key | 549 | mbedtls_pk_context *pubkey = &(s->_cert.pk); |
533 | #endif | 550 | #endif |
551 | |||
552 | if ((ret = mbedtls_pk_check_pair(pubkey, &s->_key | ||
534 | #if MBEDTLS_VERSION_MAJOR >= 3 | 553 | #if MBEDTLS_VERSION_MAJOR >= 3 |
535 | , mbedtls_ctr_drbg_random, &s->_ctr_drbg | 554 | , mbedtls_ctr_drbg_random, &s->_ctr_drbg |
536 | #endif | 555 | #endif |
537 | ))) { | 556 | )) != 0) { |
538 | vc_tls_report_error(ret, "ERROR: Cert and key mismatch, mbedtls reports: "); | 557 | vc_tls_report_error(ret, "Cert and key mismatch, mbedtls reports: "); |
539 | return 1; | 558 | return 1; |
540 | } | 559 | } |
541 | 560 | ||
542 | if ((ret = mbedtls_ssl_conf_own_cert(conf, &s->_cert, &s->_key)) != 0) { | 561 | if ((ret = mbedtls_ssl_conf_own_cert(conf, &s->_cert, &s->_key)) != 0) { |
543 | vc_tls_report_error(ret, "Setting key and cert to tls session fails, mbedtls reports: "); | 562 | vc_tls_report_error(ret, "Setting key and cert to tls session fails, mbedtls reports: "); |
544 | return -1; | 563 | return -1; |
564 | } | ||
545 | } | 565 | } |
546 | 566 | ||
547 | /* Config constructed, pass to ssl */ | 567 | /* Config constructed, pass to ssl */ |
548 | /* Init ssl and config structs and configure ssl ctx */ | 568 | /* Init ssl and config structs and configure ssl ctx */ |
549 | mbedtls_ssl_setup(ssl, conf); | 569 | if ((ret = mbedtls_ssl_setup(ssl, conf)) != 0) { |
570 | vc_tls_report_error(ret, "Can not configure parameters on tls context, mbedtls reports: "); | ||
571 | return -1; | ||
572 | } | ||
550 | /* TODO: mbedtls_ssl_set_hostname(&ssl, SERVER_NAME) */ | 573 | /* TODO: mbedtls_ssl_set_hostname(&ssl, SERVER_NAME) */ |
551 | 574 | ||
552 | mbedtls_ssl_set_bio(ssl, (void*)(intptr_t)serverfd, static_tcp_send, static_tcp_recv, NULL ); | 575 | mbedtls_ssl_set_bio(ssl, (void*)(intptr_t)serverfd, static_tcp_send, static_tcp_recv, NULL ); |
553 | 576 | ||
554 | while ((ret = mbedtls_ssl_handshake(ssl)) != 0) { | 577 | while ((ret = mbedtls_ssl_handshake(ssl)) != 0) |
555 | if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { | 578 | if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { |
556 | vc_tls_report_error(ret, "TLS handshake failed, mbedtls reports: "); | 579 | vc_tls_report_error(ret, "TLS handshake failed, mbedtls reports: "); |
557 | return -1; | 580 | return -1; |
558 | } | 581 | } |
559 | } | ||
560 | 582 | ||
561 | snprintf(tmpstr, TMPSTRSIZE, "[SSL CIPHER ] %s", mbedtls_ssl_get_ciphersuite(ssl)); | 583 | writecf(FS_SERV,"[TSL HANDSHAKE DONE ]"); |
584 | snprintf(tmpstr, TMPSTRSIZE, "[TSL CIPHER LIST ] %s", mbedtls_ssl_get_ciphersuite(ssl)); | ||
562 | writecf(FS_SERV, tmpstr); | 585 | writecf(FS_SERV, tmpstr); |
563 | 586 | ||
564 | const mbedtls_x509_crt* peer_cert = mbedtls_ssl_get_peer_cert(ssl); | 587 | const mbedtls_x509_crt* peer_cert = mbedtls_ssl_get_peer_cert(ssl); |
565 | mbedtls_x509_crt_info(tmpstr, sizeof(tmpstr), "[SSL PEER INFO ] ", peer_cert); | 588 | mbedtls_x509_crt_info(tmpstr, sizeof(tmpstr), "[TSL PEER INFO ] ", peer_cert); |
566 | 589 | ||
567 | for (token = strtok(tmpstr, "\n"); token; token = strtok(NULL, "\n")) | 590 | for (token = strtok(tmpstr, "\n"); token; token = strtok(NULL, "\n")) |
568 | writecf(FS_SERV, token); | 591 | writecf(FS_SERV, token); |
569 | 592 | ||
570 | mbedtls_ssl_get_verify_result(ssl); | 593 | #if MBEDTLS_VERSION_MAJOR == 3 && MBEDTLS_VERSION_MINOR == 0 |
594 | const uint8_t * const rawcert_buf = peer_cert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p); | ||
595 | size_t rawcert_len = peer_cert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len); | ||
596 | #else | ||
597 | const uint8_t * const rawcert_buf = peer_cert->raw.p; | ||
598 | size_t rawcert_len = peer_cert->raw.len; | ||
599 | #endif | ||
600 | const mbedtls_md_info_t *mdinfo = mbedtls_md_info_from_string("SHA1"); | ||
601 | if (mdinfo) { | ||
602 | mbedtls_md(mdinfo, rawcert_buf, rawcert_len, digest); | ||
603 | |||
604 | char *fp = fingerprint; | ||
605 | for (int j=0; j<mbedtls_md_get_size(mdinfo); j++) | ||
606 | fp += sprintf(fp, "%02X:", digest[j]); | ||
607 | assert ( fp > fingerprint ); | ||
608 | fp[-1] = 0; | ||
609 | snprintf(tmpstr, TMPSTRSIZE, "[TSL FINGERPRINT ] %s (from server)", fingerprint); | ||
610 | writecf(FS_SERV, tmpstr); | ||
611 | |||
612 | if (getintoption(CF_PINFINGER) && verify_or_store_fingerprint(fingerprint)) | ||
613 | return 1; | ||
614 | } else { | ||
615 | writecf(FS_SERV, "Unable to load SHA-1 md"); | ||
616 | if (getintoption(CF_PINFINGER)) { | ||
617 | writecf(FS_ERR, "ERROR: Can not compute fingerprint, but pinning check is required"); | ||
618 | return 1; | ||
619 | } | ||
620 | } | ||
621 | |||
622 | ret = mbedtls_ssl_get_verify_result(ssl); | ||
571 | 623 | ||
572 | return 0; | 624 | return 0; |
573 | } | 625 | } |