downstream已支持session ticket。
This commit is contained in:
@@ -100,7 +100,7 @@ char* tfe_strdup(const char* s);
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
static inline void tfe_hexdump(FILE *f, const char * title, const void * buf, unsigned int len)
|
static inline void tfe_hexdump2file(FILE *f, const char * title, const void * buf, unsigned int len)
|
||||||
{
|
{
|
||||||
unsigned int i, out, ofs;
|
unsigned int i, out, ofs;
|
||||||
const unsigned char *data = (const unsigned char *)buf;
|
const unsigned char *data = (const unsigned char *)buf;
|
||||||
@@ -129,3 +129,15 @@ static inline void tfe_hexdump(FILE *f, const char * title, const void * buf, un
|
|||||||
|
|
||||||
#undef LINE_LEN
|
#undef LINE_LEN
|
||||||
}
|
}
|
||||||
|
static inline unsigned char* tfe_hexdump(unsigned char *dst, unsigned char *src, size_t len)
|
||||||
|
{
|
||||||
|
static unsigned char hex[] = "0123456789abcdef";
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
*dst++ = hex[*src >> 4];
|
||||||
|
*dst++ = hex[*src++ & 0xf];
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
#include <ssl_utils.h>
|
#include <ssl_utils.h>
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
|
|
||||||
#define SSL_EX_DATA_IDX_SSLMGR 0
|
int SSL_EX_DATA_IDX_SSLMGR;
|
||||||
#define MAX_NET_RETRIES 50
|
#define MAX_NET_RETRIES 50
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -66,12 +66,22 @@ enum ssl_stream_stat
|
|||||||
SSL_DOWN_CACHE_SZ,
|
SSL_DOWN_CACHE_SZ,
|
||||||
SSL_DOWN_CACHE_QUERY,
|
SSL_DOWN_CACHE_QUERY,
|
||||||
SSL_DOWN_CACHE_HIT,
|
SSL_DOWN_CACHE_HIT,
|
||||||
|
SSL_DOWN_TICKET_NEW,
|
||||||
|
SSL_DOWN_TICKET_REUSE,
|
||||||
|
|
||||||
SSL_NO_CHELLO,
|
SSL_NO_CHELLO,
|
||||||
SSL_NO_SNI,
|
SSL_NO_SNI,
|
||||||
SSL_FAKE_CRT,
|
SSL_FAKE_CRT,
|
||||||
SSL_STAT_MAX
|
SSL_STAT_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct session_ticket_key
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
unsigned char name[16];
|
||||||
|
unsigned char hmac_key[32];
|
||||||
|
unsigned char aes_key[32];
|
||||||
|
} ;
|
||||||
struct ssl_mgr
|
struct ssl_mgr
|
||||||
{
|
{
|
||||||
unsigned int sslcomp;
|
unsigned int sslcomp;
|
||||||
@@ -91,6 +101,9 @@ struct ssl_mgr
|
|||||||
struct sess_cache * down_sess_cache;
|
struct sess_cache * down_sess_cache;
|
||||||
struct sess_cache * up_sess_cache;
|
struct sess_cache * up_sess_cache;
|
||||||
|
|
||||||
|
struct session_ticket_key ticket_key;
|
||||||
|
|
||||||
|
|
||||||
char default_ciphers[TFE_STRING_MAX];
|
char default_ciphers[TFE_STRING_MAX];
|
||||||
DH * dh;
|
DH * dh;
|
||||||
char * ecdhcurve;
|
char * ecdhcurve;
|
||||||
@@ -206,6 +219,8 @@ void ssl_stat_init(struct ssl_mgr * mgr)
|
|||||||
spec[SSL_DOWN_CACHE_SZ]="dsess_cache";
|
spec[SSL_DOWN_CACHE_SZ]="dsess_cache";
|
||||||
spec[SSL_DOWN_CACHE_QUERY]="dcache_query";
|
spec[SSL_DOWN_CACHE_QUERY]="dcache_query";
|
||||||
spec[SSL_DOWN_CACHE_HIT]="dsess_hitcnt";
|
spec[SSL_DOWN_CACHE_HIT]="dsess_hitcnt";
|
||||||
|
spec[SSL_DOWN_TICKET_NEW]="dtkt_new";
|
||||||
|
spec[SSL_DOWN_TICKET_REUSE]="dtkt_reuse";
|
||||||
|
|
||||||
spec[SSL_NO_CHELLO]="ssl_no_chlo";
|
spec[SSL_NO_CHELLO]="ssl_no_chlo";
|
||||||
spec[SSL_NO_SNI]="ssl_no_sni";
|
spec[SSL_NO_SNI]="ssl_no_sni";
|
||||||
@@ -396,7 +411,13 @@ ssl_stream_gc_cb(evutil_socket_t fd, short what, void * arg)
|
|||||||
struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section,
|
struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section,
|
||||||
struct event_base * ev_base_gc, void * logger, screen_stat_handle_t fs)
|
struct event_base * ev_base_gc, void * logger, screen_stat_handle_t fs)
|
||||||
{
|
{
|
||||||
struct timeval gc_delay = {0, 500*1000}; //Microseconds, we set 500 miliseconds here.
|
struct timeval gc_delay = {0, 500*1000}; //Microseconds, we set 500 miliseconds here.
|
||||||
|
unsigned char key_name[]="!mesalab-tfe3a~&";
|
||||||
|
unsigned char aes_key_def[]={0xC5,0xAC,0xC1,0xA6,0xB2,0xBB,0xCA,0xC7,0xE3,0xBE,0xE3,0xB2,0xC6,0xA3,0xB1,0xB9
|
||||||
|
,0xA3,0xAC,0xB6,0xF8,0xCA,0xC7,0xD1,0xDB,0xBE,0xA6,0xC0,0xEF,0xD3,0xD0,0xB9,0x84};
|
||||||
|
unsigned char hmac_key_def[]={0xD6,0xC8,0xD0,0xF2,0xC8,0xCB,0xBF,0xDA,0xBA,0xCD,0xBF,0xC6,0xBC,0xBC,0xA3,0xAC
|
||||||
|
,0xC8,0xCB,0xC0,0xE0,0xC9,0xE7,0xBB,0xE1,0xB5,0xC4,0xBB,0xF9,0xCA,0xAF,0x19,0x84};
|
||||||
|
|
||||||
struct ssl_mgr * mgr = ALLOC(struct ssl_mgr, 1);
|
struct ssl_mgr * mgr = ALLOC(struct ssl_mgr, 1);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char version_str[TFE_SYMBOL_MAX];
|
char version_str[TFE_SYMBOL_MAX];
|
||||||
@@ -421,6 +442,7 @@ struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section
|
|||||||
}
|
}
|
||||||
//tfe2a uses SSLv23_method, it was been deprecated and replaced with the TLS_method() in openssl 1.1.0.
|
//tfe2a uses SSLv23_method, it was been deprecated and replaced with the TLS_method() in openssl 1.1.0.
|
||||||
mgr->sslmethod = TLS_method;
|
mgr->sslmethod = TLS_method;
|
||||||
|
SSL_EX_DATA_IDX_SSLMGR = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
|
||||||
MESA_load_profile_uint_def(ini_profile, section, "ssl_compression", &(mgr->sslcomp), 1);
|
MESA_load_profile_uint_def(ini_profile, section, "ssl_compression", &(mgr->sslcomp), 1);
|
||||||
MESA_load_profile_uint_def(ini_profile, section, "no_ssl2", &(mgr->no_ssl2), 1);
|
MESA_load_profile_uint_def(ini_profile, section, "no_ssl2", &(mgr->no_ssl2), 1);
|
||||||
MESA_load_profile_uint_def(ini_profile, section, "no_ssl3", &(mgr->no_ssl3), 1);
|
MESA_load_profile_uint_def(ini_profile, section, "no_ssl3", &(mgr->no_ssl3), 1);
|
||||||
@@ -437,6 +459,13 @@ struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section
|
|||||||
|
|
||||||
mgr->up_sess_cache = ssl_sess_cache_create(mgr->cache_slots, mgr->sess_expire_seconds, CONN_DIR_UPSTREAM);
|
mgr->up_sess_cache = ssl_sess_cache_create(mgr->cache_slots, mgr->sess_expire_seconds, CONN_DIR_UPSTREAM);
|
||||||
mgr->down_sess_cache = ssl_sess_cache_create(mgr->cache_slots, mgr->sess_expire_seconds, CONN_DIR_DOWNSTREAM);
|
mgr->down_sess_cache = ssl_sess_cache_create(mgr->cache_slots, mgr->sess_expire_seconds, CONN_DIR_DOWNSTREAM);
|
||||||
|
|
||||||
|
//Reference to NGINX: http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_ticket_key
|
||||||
|
//Support key rotation in futher.
|
||||||
|
|
||||||
|
memcpy(mgr->ticket_key.name,key_name, sizeof(mgr->ticket_key.name));
|
||||||
|
memcpy(mgr->ticket_key.aes_key, aes_key_def, sizeof(mgr->ticket_key.aes_key));
|
||||||
|
memcpy(mgr->ticket_key.hmac_key, hmac_key_def, sizeof(mgr->ticket_key.hmac_key));
|
||||||
mgr->key_keeper = key_keeper_init(ini_profile, "key_keeper", logger);
|
mgr->key_keeper = key_keeper_init(ini_profile, "key_keeper", logger);
|
||||||
if (mgr->key_keeper == NULL)
|
if (mgr->key_keeper == NULL)
|
||||||
{
|
{
|
||||||
@@ -926,6 +955,82 @@ extern void ssl_async_upstream_create(struct future * f, struct ssl_mgr * mgr, e
|
|||||||
ssl_async_peek_client_hello(ctx->f_peek_chello, fd_downstream, evbase, mgr->logger);
|
ssl_async_peek_client_hello(ctx->f_peek_chello, fd_downstream, evbase, mgr->logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ossl_session_ticket_key_callback(SSL *ssl_conn,
|
||||||
|
unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx,
|
||||||
|
HMAC_CTX *hctx, int enc)
|
||||||
|
{
|
||||||
|
const EVP_MD *digest=NULL;
|
||||||
|
const EVP_CIPHER *cipher=NULL;
|
||||||
|
size_t size=0;
|
||||||
|
struct ssl_mgr * mgr = (struct ssl_mgr *) SSL_get_ex_data(ssl_conn, SSL_EX_DATA_IDX_SSLMGR);
|
||||||
|
struct session_ticket_key* key=&(mgr->ticket_key);
|
||||||
|
assert(mgr!=NULL);
|
||||||
|
digest = EVP_sha256();
|
||||||
|
unsigned char buf[32];
|
||||||
|
|
||||||
|
if (enc == 1)
|
||||||
|
{
|
||||||
|
/* encrypt session ticket */
|
||||||
|
cipher = EVP_aes_256_cbc();
|
||||||
|
size = 32;
|
||||||
|
|
||||||
|
if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(mgr->logger, "Session Ticket RAND_bytes() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EVP_EncryptInit_ex(ectx, cipher, NULL, key[0].aes_key, iv) != 1)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(mgr->logger, "EVP_EncryptInit_ex() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL) != 1)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(mgr->logger, "HMAC_Init_ex() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(name, key[0].name, 16);
|
||||||
|
ATOMIC_INC(&(mgr->stat_val[SSL_DOWN_TICKET_NEW]));
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* decrypt session ticket */
|
||||||
|
if(0!=memcmp(name, key[0].name, 16))
|
||||||
|
{
|
||||||
|
TFE_LOG_INFO(mgr->logger, "ssl session ticket decrypt, key: \"%*s\" not found"
|
||||||
|
,tfe_hexdump(buf, name ,16)-buf, buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cipher = EVP_aes_256_cbc();
|
||||||
|
size = 32;
|
||||||
|
|
||||||
|
|
||||||
|
if (HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL) != 1)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(mgr->logger, "HMAC_Init_ex() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[0].aes_key, iv) != 1)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(mgr->logger, "EVP_DecryptInit_ex() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ATOMIC_INC(&(mgr->stat_val[SSL_DOWN_TICKET_REUSE]));
|
||||||
|
//Todo: Implement key expire.
|
||||||
|
return 1; //Return 1 indicates that the ctx and hctx have been set and the session can continue on those parameters.
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called by OpenSSL when a new src SSL session is created.
|
* Called by OpenSSL when a new src SSL session is created.
|
||||||
* OpenSSL increments the refcount before calling the callback and will
|
* OpenSSL increments the refcount before calling the callback and will
|
||||||
@@ -1006,69 +1111,34 @@ static void sslctx_set_opts(SSL_CTX * sslctx, struct ssl_mgr * mgr)
|
|||||||
SSL_CTX_set_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
|
SSL_CTX_set_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
|
||||||
#endif /* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */
|
#endif /* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */
|
||||||
|
|
||||||
#ifdef SSL_OP_NO_TICKET
|
|
||||||
SSL_CTX_set_options(sslctx, SSL_OP_NO_TICKET);
|
|
||||||
#endif /* SSL_OP_NO_TICKET */
|
|
||||||
|
|
||||||
#ifdef SSL_OP_NO_SSLv2
|
|
||||||
|
|
||||||
#ifdef HAVE_SSLV2
|
if (mgr->no_ssl2)
|
||||||
|
{
|
||||||
if (mgr->no_ssl2) {
|
SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv2);
|
||||||
#endif /* HAVE_SSLV2 */
|
|
||||||
|
|
||||||
SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv2);
|
|
||||||
|
|
||||||
#ifdef HAVE_SSLV2
|
|
||||||
}
|
}
|
||||||
|
if (mgr->no_ssl3)
|
||||||
#endif /* HAVE_SSLV2 */
|
{
|
||||||
|
|
||||||
#endif /* !SSL_OP_NO_SSLv2 */
|
|
||||||
|
|
||||||
#ifdef HAVE_SSLV3
|
|
||||||
|
|
||||||
if (mgr->no_ssl3) {
|
|
||||||
SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv3);
|
SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_SSLV3 */
|
|
||||||
|
|
||||||
#ifdef HAVE_TLSV10
|
|
||||||
|
|
||||||
if (mgr->no_tls10)
|
if (mgr->no_tls10)
|
||||||
{
|
{
|
||||||
SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1);
|
SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_TLSV10 */
|
|
||||||
|
|
||||||
#ifdef HAVE_TLSV11
|
|
||||||
|
|
||||||
if (mgr->no_tls11)
|
if (mgr->no_tls11)
|
||||||
{
|
{
|
||||||
SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_1);
|
SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_TLSV11 */
|
|
||||||
|
|
||||||
#ifdef HAVE_TLSV12
|
|
||||||
|
|
||||||
if (mgr->no_tls12)
|
if (mgr->no_tls12)
|
||||||
{
|
{
|
||||||
SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_2);
|
SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_TLSV12 */
|
|
||||||
|
|
||||||
#ifdef SSL_OP_NO_COMPRESSION
|
|
||||||
|
|
||||||
if (!mgr->sslcomp)
|
if (!mgr->sslcomp)
|
||||||
{
|
{
|
||||||
SSL_CTX_set_options(sslctx, SSL_OP_NO_COMPRESSION);
|
SSL_CTX_set_options(sslctx, SSL_OP_NO_COMPRESSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SSL_OP_NO_COMPRESSION */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1100,6 +1170,8 @@ static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt)
|
|||||||
SSL_CTX_sess_set_new_cb(sslctx, ossl_sessnew_cb);
|
SSL_CTX_sess_set_new_cb(sslctx, ossl_sessnew_cb);
|
||||||
SSL_CTX_sess_set_remove_cb(sslctx, ossl_sessremove_cb);
|
SSL_CTX_sess_set_remove_cb(sslctx, ossl_sessremove_cb);
|
||||||
SSL_CTX_sess_set_get_cb(sslctx, ossl_sessget_cb);
|
SSL_CTX_sess_set_get_cb(sslctx, ossl_sessget_cb);
|
||||||
|
ret=SSL_CTX_set_tlsext_ticket_key_cb(sslctx, ossl_session_ticket_key_callback);
|
||||||
|
assert(ret!=0);
|
||||||
SSL_CTX_set_session_cache_mode(sslctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL);
|
SSL_CTX_set_session_cache_mode(sslctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL);
|
||||||
SSL_CTX_set_session_id_context(sslctx, (const unsigned char *) mgr->ssl_session_context,
|
SSL_CTX_set_session_id_context(sslctx, (const unsigned char *) mgr->ssl_session_context,
|
||||||
sizeof(mgr->ssl_session_context));
|
sizeof(mgr->ssl_session_context));
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ enum tfe_stream_action __http_connection_entry_on_request(const struct tfe_strea
|
|||||||
struct http_half_private * hf_private_req_in = to_hf_request_private(hs_private);
|
struct http_half_private * hf_private_req_in = to_hf_request_private(hs_private);
|
||||||
struct http_half_private * hf_private_req_user;
|
struct http_half_private * hf_private_req_user;
|
||||||
|
|
||||||
/* tfe_hexdump(stderr, __FUNCTION__, data, (unsigned int)len); */
|
/* tfe_hexdump2file(stderr, __FUNCTION__, data, (unsigned int)len); */
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
size_t __action_byptes;
|
size_t __action_byptes;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user