nxt_openssl.c (1942:296628096d6c) nxt_openssl.c (1952:0bca988e9541)
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>
16
17
18typedef struct {
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>
16
17
18typedef struct {
19 SSL *session;
20 nxt_conn_t *conn;
19 SSL *session;
20 nxt_conn_t *conn;
21
21
22 int ssl_error;
23 uint8_t times; /* 2 bits */
24 uint8_t handshake; /* 1 bit */
22 int ssl_error;
23 uint8_t times; /* 2 bits */
24 uint8_t handshake; /* 1 bit */
25
25
26 nxt_tls_conf_t *conf;
27 nxt_buf_mem_t buffer;
26 nxt_tls_conf_t *conf;
27 nxt_buf_mem_t buffer;
28} nxt_openssl_conn_t;
29
30
28} nxt_openssl_conn_t;
29
30
31struct nxt_tls_ticket_s {
32 u_char name[16];
33 u_char hmac_key[32];
34 u_char aes_key[32];
35 uint8_t size;
36};
37
38
39struct nxt_tls_tickets_s {
40 nxt_uint_t count;
41 nxt_tls_ticket_t tickets[];
42};
43
44
31typedef enum {
32 NXT_OPENSSL_HANDSHAKE = 0,
33 NXT_OPENSSL_READ,
34 NXT_OPENSSL_WRITE,
35 NXT_OPENSSL_SHUTDOWN,
36} nxt_openssl_io_t;
37
38

--- 633 unchanged lines hidden (view full) ---

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
45typedef enum {
46 NXT_OPENSSL_HANDSHAKE = 0,
47 NXT_OPENSSL_READ,
48 NXT_OPENSSL_WRITE,
49 NXT_OPENSSL_SHUTDOWN,
50} nxt_openssl_io_t;
51
52

--- 633 unchanged lines hidden (view full) ---

686
687 nxt_conf_get_string(member, &value);
688
689 ret = nxt_openssl_base64_decode(buf, 80, value.start, value.length);
690 if (nxt_slow_path(ret == NXT_ERROR)) {
691 return NXT_ERROR;
692 }
693
694 nxt_memcpy(ticket->name, buf, 16);
695
680 if (ret == 48) {
696 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);
697 nxt_memcpy(ticket->aes_key, buf + 16, 16);
698 nxt_memcpy(ticket->hmac_key, buf + 32, 16);
699 ticket->size = 16;
684
685 } else {
700
701 } else {
686 ticket->aes128 = 0;
687 nxt_memcpy(ticket->hmac_key, buf + 16, 32);
688 nxt_memcpy(ticket->aes_key, buf + 48, 32);
702 nxt_memcpy(ticket->hmac_key, buf + 16, 32);
703 nxt_memcpy(ticket->aes_key, buf + 48, 32);
704 ticket->size = 32;
689 }
690
705 }
706
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 "

--- 22 unchanged lines hidden (view full) ---

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{
707 } while (i < count);
708
709 if (SSL_CTX_set_tlsext_ticket_key_cb(ctx, nxt_tls_ticket_key_callback)
710 == 0)
711 {
712 nxt_openssl_log_error(task, NXT_LOG_ALERT,
713 "Unit was built with Session Tickets support, however, "
714 "now it is linked dynamically to an OpenSSL library "

--- 22 unchanged lines hidden (view full) ---

737
738
739#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
740
741static int
742nxt_tls_ticket_key_callback(SSL *s, unsigned char *name, unsigned char *iv,
743 EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc)
744{
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
745 nxt_uint_t i;
746 nxt_conn_t *c;
747 const EVP_MD *digest;
748 const EVP_CIPHER *cipher;
749 nxt_tls_ticket_t *ticket;
750 nxt_openssl_conn_t *tls;
751
752 c = SSL_get_ex_data(s, nxt_openssl_connection_index);
753
754 if (nxt_slow_path(c == NULL)) {
755 nxt_thread_log_alert("SSL_get_ex_data() failed");
756 return -1;
757 }
758
759 tls = c->u.tls;
760 ticket = tls->conf->tickets->tickets;
761
748#ifdef OPENSSL_NO_SHA256
749 digest = EVP_sha1();
750#else
751 digest = EVP_sha256();
752#endif
762 i = 0;
753
754 if (enc == 1) {
755 /* encrypt session ticket */
756
757 nxt_debug(c->socket.task, "TLS session ticket encrypt");
758
763
764 if (enc == 1) {
765 /* encrypt session ticket */
766
767 nxt_debug(c->socket.task, "TLS session ticket encrypt");
768
759 if (ticket[0].aes128 == 1) {
760 cipher = EVP_aes_128_cbc();
761 size = 16;
769 cipher = (ticket[0].size == 16) ? EVP_aes_128_cbc() : EVP_aes_256_cbc();
762
770
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
771 if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1) {
772 nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT,
773 "RAND_bytes() failed");
774 return -1;
775 }
776
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
777 nxt_memcpy(name, ticket[0].name, 16);
778
790 return 1;
791
792 } else {
793 /* decrypt session ticket */
794
779 } else {
780 /* decrypt session ticket */
781
795 for (i = 0; i < tls->conf->tickets->count; i++) {
782 do {
796 if (nxt_memcmp(name, ticket[i].name, 16) == 0) {
797 goto found;
798 }
783 if (nxt_memcmp(name, ticket[i].name, 16) == 0) {
784 goto found;
785 }
799 }
800
786
787 } while (++i < tls->conf->tickets->count);
788
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
789 nxt_debug(c->socket.task, "TLS session ticket decrypt, key not found");
790
791 return 0;
792
793 found:
794
795 nxt_debug(c->socket.task,
796 "TLS session ticket decrypt, key number: \"%d\"", i);
797
810 if (ticket[i].aes128 == 1) {
811 cipher = EVP_aes_128_cbc();
812 size = 16;
798 enc = (i == 0) ? 1 : 2 /* renew */;
813
799
814 } else {
815 cipher = EVP_aes_256_cbc();
816 size = 32;
817 }
800 cipher = (ticket[i].size == 16) ? EVP_aes_128_cbc() : EVP_aes_256_cbc();
801 }
818
802
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 }
803 if (EVP_DecryptInit_ex(ectx, cipher, NULL, ticket[i].aes_key, iv) != 1) {
804 nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT,
805 "EVP_DecryptInit_ex() failed");
806 return -1;
807 }
824
808
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 }
809#ifdef OPENSSL_NO_SHA256
810 digest = EVP_sha1();
811#else
812 digest = EVP_sha256();
813#endif
830
814
831 return (i == 0) ? 1 : 2 /* renew */;
815 if (HMAC_Init_ex(hctx, ticket[i].hmac_key, ticket[i].size, digest, NULL)
816 != 1)
817 {
818 nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT,
819 "HMAC_Init_ex() failed");
820 return -1;
832 }
821 }
822
823 return enc;
833}
834
835#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
836
837#endif /* NXT_HAVE_OPENSSL_TLSEXT */
838
839
840static void

--- 1048 unchanged lines hidden ---
824}
825
826#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
827
828#endif /* NXT_HAVE_OPENSSL_TLSEXT */
829
830
831static void

--- 1048 unchanged lines hidden ---