Deleted
Added
nxt_openssl.c (1921:b0deb6fa9219) | nxt_openssl.c (1942:296628096d6c) |
---|---|
1 2/* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7#include <nxt_main.h> 8#include <nxt_conf.h> 9#include <openssl/ssl.h> 10#include <openssl/conf.h> 11#include <openssl/err.h> 12#include <openssl/rand.h> 13#include <openssl/x509v3.h> | 1 2/* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7#include <nxt_main.h> 8#include <nxt_conf.h> 9#include <openssl/ssl.h> 10#include <openssl/conf.h> 11#include <openssl/err.h> 12#include <openssl/rand.h> 13#include <openssl/x509v3.h> |
14#include <openssl/bio.h> 15#include <openssl/evp.h> |
|
14 15 16typedef struct { 17 SSL *session; 18 nxt_conn_t *conn; 19 20 int ssl_error; 21 uint8_t times; /* 2 bits */ --- 23 unchanged lines hidden (view full) --- 45static nxt_int_t nxt_openssl_server_init(nxt_task_t *task, nxt_mp_t *mp, 46 nxt_tls_init_t *tls_init, nxt_bool_t last); 47static nxt_int_t nxt_openssl_chain_file(nxt_task_t *task, SSL_CTX *ctx, 48 nxt_tls_conf_t *conf, nxt_mp_t *mp, nxt_bool_t single); 49#if (NXT_HAVE_OPENSSL_CONF_CMD) 50static nxt_int_t nxt_ssl_conf_commands(nxt_task_t *task, SSL_CTX *ctx, 51 nxt_conf_value_t *value, nxt_mp_t *mp); 52#endif | 16 17 18typedef struct { 19 SSL *session; 20 nxt_conn_t *conn; 21 22 int ssl_error; 23 uint8_t times; /* 2 bits */ --- 23 unchanged lines hidden (view full) --- 47static nxt_int_t nxt_openssl_server_init(nxt_task_t *task, nxt_mp_t *mp, 48 nxt_tls_init_t *tls_init, nxt_bool_t last); 49static nxt_int_t nxt_openssl_chain_file(nxt_task_t *task, SSL_CTX *ctx, 50 nxt_tls_conf_t *conf, nxt_mp_t *mp, nxt_bool_t single); 51#if (NXT_HAVE_OPENSSL_CONF_CMD) 52static nxt_int_t nxt_ssl_conf_commands(nxt_task_t *task, SSL_CTX *ctx, 53 nxt_conf_value_t *value, nxt_mp_t *mp); 54#endif |
55#if (NXT_HAVE_OPENSSL_TLSEXT) 56static nxt_int_t nxt_tls_ticket_keys(nxt_task_t *task, SSL_CTX *ctx, 57 nxt_tls_init_t *tls_init, nxt_mp_t *mp); 58static int nxt_tls_ticket_key_callback(SSL *s, unsigned char *name, 59 unsigned char *iv, EVP_CIPHER_CTX *ectx,HMAC_CTX *hctx, int enc); 60#endif |
|
53static void nxt_ssl_session_cache(SSL_CTX *ctx, size_t cache_size, 54 time_t timeout); 55static nxt_uint_t nxt_openssl_cert_get_names(nxt_task_t *task, X509 *cert, 56 nxt_tls_conf_t *conf, nxt_mp_t *mp); 57static nxt_int_t nxt_openssl_bundle_hash_test(nxt_lvlhsh_query_t *lhq, 58 void *data); 59static nxt_int_t nxt_openssl_bundle_hash_insert(nxt_task_t *task, 60 nxt_lvlhsh_t *lvlhsh, nxt_tls_bundle_hash_item_t *item, nxt_mp_t * mp); --- 284 unchanged lines hidden (view full) --- 345 && nxt_ssl_conf_commands(task, ctx, tls_init->conf_cmds, mp) != NXT_OK) 346 { 347 goto fail; 348 } 349#endif 350 351 nxt_ssl_session_cache(ctx, tls_init->cache_size, tls_init->timeout); 352 | 61static void nxt_ssl_session_cache(SSL_CTX *ctx, size_t cache_size, 62 time_t timeout); 63static nxt_uint_t nxt_openssl_cert_get_names(nxt_task_t *task, X509 *cert, 64 nxt_tls_conf_t *conf, nxt_mp_t *mp); 65static nxt_int_t nxt_openssl_bundle_hash_test(nxt_lvlhsh_query_t *lhq, 66 void *data); 67static nxt_int_t nxt_openssl_bundle_hash_insert(nxt_task_t *task, 68 nxt_lvlhsh_t *lvlhsh, nxt_tls_bundle_hash_item_t *item, nxt_mp_t * mp); --- 284 unchanged lines hidden (view full) --- 353 && nxt_ssl_conf_commands(task, ctx, tls_init->conf_cmds, mp) != NXT_OK) 354 { 355 goto fail; 356 } 357#endif 358 359 nxt_ssl_session_cache(ctx, tls_init->cache_size, tls_init->timeout); 360 |
361#if (NXT_HAVE_OPENSSL_TLSEXT) 362 if (nxt_tls_ticket_keys(task, ctx, tls_init, mp) != NXT_OK) { 363 goto fail; 364 } 365#endif 366 |
|
353 SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); 354 355 if (conf->ca_certificate != NULL) { 356 357 /* TODO: verify callback */ 358 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 359 360 /* TODO: verify depth */ --- 221 unchanged lines hidden (view full) --- 582 583 SSL_CONF_CTX_free(cctx); 584 585 return NXT_ERROR; 586} 587 588#endif 589 | 367 SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); 368 369 if (conf->ca_certificate != NULL) { 370 371 /* TODO: verify callback */ 372 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 373 374 /* TODO: verify depth */ --- 221 unchanged lines hidden (view full) --- 596 597 SSL_CONF_CTX_free(cctx); 598 599 return NXT_ERROR; 600} 601 602#endif 603 |
604#if (NXT_HAVE_OPENSSL_TLSEXT) |
|
590 | 605 |
606static nxt_int_t 607nxt_tls_ticket_keys(nxt_task_t *task, SSL_CTX *ctx, nxt_tls_init_t *tls_init, 608 nxt_mp_t *mp) 609{ 610 uint32_t i; 611 nxt_int_t ret; 612 nxt_str_t value; 613 nxt_uint_t count; 614 nxt_conf_value_t *member, *tickets_conf; 615 nxt_tls_ticket_t *ticket; 616 nxt_tls_tickets_t *tickets; 617 u_char buf[80]; 618 619 tickets_conf = tls_init->tickets_conf; 620 621 if (tickets_conf == NULL) { 622 goto no_ticket; 623 } 624 625 if (nxt_conf_type(tickets_conf) == NXT_CONF_BOOLEAN) { 626 if (nxt_conf_get_boolean(tickets_conf) == 0) { 627 goto no_ticket; 628 } 629 630 return NXT_OK; 631 } 632 633 if (nxt_conf_type(tickets_conf) == NXT_CONF_ARRAY) { 634 count = nxt_conf_array_elements_count(tickets_conf); 635 636 if (count == 0) { 637 goto no_ticket; 638 } 639 640 } else { 641 /* nxt_conf_type(tickets_conf) == NXT_CONF_STRING */ 642 count = 1; 643 } 644 645#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 646 647 tickets = nxt_mp_get(mp, sizeof(nxt_tls_tickets_t) 648 + count * sizeof(nxt_tls_ticket_t)); 649 if (nxt_slow_path(tickets == NULL)) { 650 return NXT_ERROR; 651 } 652 653 tickets->count = count; 654 tls_init->conf->tickets = tickets; 655 i = 0; 656 657 do { 658 ticket = &tickets->tickets[i]; 659 660 i++; 661 662 if (nxt_conf_type(tickets_conf) == NXT_CONF_ARRAY) { 663 member = nxt_conf_get_array_element(tickets_conf, count - i); 664 if (member == NULL) { 665 break; 666 } 667 668 } else { 669 /* nxt_conf_type(tickets_conf) == NXT_CONF_STRING */ 670 member = tickets_conf; 671 } 672 673 nxt_conf_get_string(member, &value); 674 675 ret = nxt_openssl_base64_decode(buf, 80, value.start, value.length); 676 if (nxt_slow_path(ret == NXT_ERROR)) { 677 return NXT_ERROR; 678 } 679 680 if (ret == 48) { 681 ticket->aes128 = 1; 682 nxt_memcpy(ticket->aes_key, buf + 16, 16); 683 nxt_memcpy(ticket->hmac_key, buf + 32, 16); 684 685 } else { 686 ticket->aes128 = 0; 687 nxt_memcpy(ticket->hmac_key, buf + 16, 32); 688 nxt_memcpy(ticket->aes_key, buf + 48, 32); 689 } 690 691 nxt_memcpy(ticket->name, buf, 16); 692 } while (i < count); 693 694 if (SSL_CTX_set_tlsext_ticket_key_cb(ctx, nxt_tls_ticket_key_callback) 695 == 0) 696 { 697 nxt_openssl_log_error(task, NXT_LOG_ALERT, 698 "Unit was built with Session Tickets support, however, " 699 "now it is linked dynamically to an OpenSSL library " 700 "which has no tlsext support, therefore Session Tickets " 701 "are not available"); 702 703 return NXT_ERROR; 704 } 705 706 return NXT_OK; 707 708#else 709 nxt_alert(task, "Setting custom session ticket keys is not supported with " 710 "this version of OpenSSL library"); 711 712 return NXT_ERROR; 713 714#endif 715 716no_ticket: 717 718 SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET); 719 720 return NXT_OK; 721} 722 723 724#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 725 726static int 727nxt_tls_ticket_key_callback(SSL *s, unsigned char *name, unsigned char *iv, 728 EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc) 729{ 730 size_t size; 731 nxt_uint_t i; 732 nxt_conn_t *c; 733 const EVP_MD *digest; 734 const EVP_CIPHER *cipher; 735 nxt_tls_ticket_t *ticket; 736 nxt_openssl_conn_t *tls; 737 738 c = SSL_get_ex_data(s, nxt_openssl_connection_index); 739 740 if (nxt_slow_path(c == NULL)) { 741 nxt_thread_log_alert("SSL_get_ex_data() failed"); 742 return -1; 743 } 744 745 tls = c->u.tls; 746 ticket = tls->conf->tickets->tickets; 747 748#ifdef OPENSSL_NO_SHA256 749 digest = EVP_sha1(); 750#else 751 digest = EVP_sha256(); 752#endif 753 754 if (enc == 1) { 755 /* encrypt session ticket */ 756 757 nxt_debug(c->socket.task, "TLS session ticket encrypt"); 758 759 if (ticket[0].aes128 == 1) { 760 cipher = EVP_aes_128_cbc(); 761 size = 16; 762 763 } else { 764 cipher = EVP_aes_256_cbc(); 765 size = 32; 766 } 767 768 if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1) { 769 nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT, 770 "RAND_bytes() failed"); 771 return -1; 772 } 773 774 if (EVP_EncryptInit_ex(ectx, cipher, NULL, ticket[0].aes_key, iv) 775 != 1) 776 { 777 nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT, 778 "EVP_EncryptInit_ex() failed"); 779 return -1; 780 } 781 782 if (HMAC_Init_ex(hctx, ticket[0].hmac_key, size, digest, NULL) != 1) { 783 nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT, 784 "HMAC_Init_ex() failed"); 785 return -1; 786 } 787 788 nxt_memcpy(name, ticket[0].name, 16); 789 790 return 1; 791 792 } else { 793 /* decrypt session ticket */ 794 795 for (i = 0; i < tls->conf->tickets->count; i++) { 796 if (nxt_memcmp(name, ticket[i].name, 16) == 0) { 797 goto found; 798 } 799 } 800 801 nxt_debug(c->socket.task, "TLS session ticket decrypt, key not found"); 802 803 return 0; 804 805 found: 806 807 nxt_debug(c->socket.task, 808 "TLS session ticket decrypt, key number: \"%d\"", i); 809 810 if (ticket[i].aes128 == 1) { 811 cipher = EVP_aes_128_cbc(); 812 size = 16; 813 814 } else { 815 cipher = EVP_aes_256_cbc(); 816 size = 32; 817 } 818 819 if (EVP_DecryptInit_ex(ectx, cipher, NULL, ticket[i].aes_key, iv) != 1) { 820 nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT, 821 "EVP_DecryptInit_ex() failed"); 822 return -1; 823 } 824 825 if (HMAC_Init_ex(hctx, ticket[i].hmac_key, size, digest, NULL) != 1) { 826 nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT, 827 "HMAC_Init_ex() failed"); 828 return -1; 829 } 830 831 return (i == 0) ? 1 : 2 /* renew */; 832 } 833} 834 835#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */ 836 837#endif /* NXT_HAVE_OPENSSL_TLSEXT */ 838 839 |
|
591static void 592nxt_ssl_session_cache(SSL_CTX *ctx, size_t cache_size, time_t timeout) 593{ 594 if (cache_size == 0) { 595 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); 596 return; 597 } 598 --- 300 unchanged lines hidden (view full) --- 899 bundle = conf->bundle; 900 nxt_assert(bundle != NULL); 901 902 do { 903 SSL_CTX_free(bundle->ctx); 904 bundle = bundle->next; 905 } while (bundle != NULL); 906 | 840static void 841nxt_ssl_session_cache(SSL_CTX *ctx, size_t cache_size, time_t timeout) 842{ 843 if (cache_size == 0) { 844 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); 845 return; 846 } 847 --- 300 unchanged lines hidden (view full) --- 1148 bundle = conf->bundle; 1149 nxt_assert(bundle != NULL); 1150 1151 do { 1152 SSL_CTX_free(bundle->ctx); 1153 bundle = bundle->next; 1154 } while (bundle != NULL); 1155 |
1156 if (conf->tickets) { 1157 nxt_memzero(conf->tickets->tickets, 1158 conf->tickets->count * sizeof(nxt_tls_ticket_t)); 1159 } 1160 |
|
907#if (OPENSSL_VERSION_NUMBER >= 0x1010100fL \ 908 && OPENSSL_VERSION_NUMBER < 0x1010101fL) 909 RAND_keep_random_devices_open(0); 910#endif 911} 912 913 914static void --- 645 unchanged lines hidden (view full) --- 1560 } 1561 1562 if (p < end) { 1563 *p++ = ')'; 1564 } 1565 1566 return p; 1567} | 1161#if (OPENSSL_VERSION_NUMBER >= 0x1010100fL \ 1162 && OPENSSL_VERSION_NUMBER < 0x1010101fL) 1163 RAND_keep_random_devices_open(0); 1164#endif 1165} 1166 1167 1168static void --- 645 unchanged lines hidden (view full) --- 1814 } 1815 1816 if (p < end) { 1817 *p++ = ')'; 1818 } 1819 1820 return p; 1821} |
1822 1823 1824nxt_int_t 1825nxt_openssl_base64_decode(u_char *d, size_t dlen, const u_char *s, size_t slen) 1826{ 1827 BIO *bio, *b64; 1828 nxt_int_t count, ret; 1829 u_char buf[128]; 1830 1831 b64 = BIO_new(BIO_f_base64()); 1832 if (nxt_slow_path(b64 == NULL)) { 1833 goto error; 1834 } 1835 1836 bio = BIO_new_mem_buf(s, slen); 1837 if (nxt_slow_path(bio == NULL)) { 1838 goto error; 1839 } 1840 1841 bio = BIO_push(b64, bio); 1842 1843 BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); 1844 1845 count = 0; 1846 1847 if (d == NULL) { 1848 1849 for ( ;; ) { 1850 ret = BIO_read(bio, buf, 128); 1851 1852 if (ret < 0) { 1853 goto invalid; 1854 } 1855 1856 count += ret; 1857 1858 if (ret != 128) { 1859 break; 1860 } 1861 } 1862 1863 } else { 1864 count = BIO_read(bio, d, dlen); 1865 1866 if (count < 0) { 1867 goto invalid; 1868 } 1869 } 1870 1871 BIO_free_all(bio); 1872 1873 return count; 1874 1875error: 1876 1877 BIO_vfree(b64); 1878 ERR_clear_error(); 1879 1880 return NXT_ERROR; 1881 1882invalid: 1883 1884 BIO_free_all(bio); 1885 ERR_clear_error(); 1886 1887 return NXT_DECLINED; 1888} |
|