2018-08-26 14:30:26 +08:00
/*
* SSL stream implementation .
* Use promise as parameter of every asynchronous function call . e . g . callback functions of libevent or future - promise .
* Author : zhengchao @ iie . ac . cn
* Create : 2018 - 8 - 17
*/
2018-08-21 16:11:50 +08:00
# include <netinet/in.h>
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <errno.h>
# include <assert.h>
2018-08-23 19:46:38 +08:00
# include <stdint.h>
# include <sys/socket.h>
2018-08-21 16:11:50 +08:00
# include <event2/event.h>
# include <event2/listener.h>
# include <event2/bufferevent.h>
# include <event2/bufferevent_ssl.h>
# include <event2/buffer.h>
# include <event2/thread.h>
# include <event2/dns.h>
2018-10-31 19:44:13 +08:00
# include <openssl/ssl.h>
# include <openssl/err.h>
# include <openssl/rand.h>
# include <openssl/x509.h>
# include <openssl/x509v3.h>
2018-08-27 21:10:45 +08:00
# include <MESA/MESA_htable.h>
# include <MESA/MESA_prof_load.h>
2018-08-21 19:01:10 +08:00
2019-10-28 17:10:38 +08:00
# include <ssl_fetch_cert.h>
2018-08-21 16:11:50 +08:00
# include <tfe_stream.h>
# include <tfe_utils.h>
# include <tfe_future.h>
2018-10-17 20:21:21 +08:00
# include <tfe_proxy.h>
2018-08-26 18:26:24 +08:00
# include <key_keeper.h>
2018-08-24 19:22:43 +08:00
# include <ssl_sess_cache.h>
2019-05-24 17:58:43 +08:00
# include <ssl_sess_ticket.h>
2018-10-31 19:44:13 +08:00
# include <ssl_trusted_cert_storage.h>
2018-08-28 15:25:09 +08:00
# include <ssl_utils.h>
2019-05-16 20:33:42 +08:00
# include <ssl_service_cache.h>
2018-08-27 21:10:45 +08:00
# include <platform.h>
2020-08-24 17:52:55 +08:00
# include <ssl_ja3.h>
2018-08-27 21:10:45 +08:00
2019-05-16 20:33:42 +08:00
static int SSL_CTX_EX_DATA_IDX_SSLMGR ;
static int SSL_EX_DATA_IDX_SSLSTREAM ;
2021-11-02 22:27:56 +08:00
static unsigned int ssl_debug ;
2018-10-08 15:06:01 +08:00
2018-08-27 21:10:45 +08:00
# define MAX_NET_RETRIES 50
2018-11-21 18:56:04 +08:00
# define LATENCY_WARNING_THRESHOLD_MS 1000
2018-08-31 14:32:34 +08:00
/*
* Default cipher suite spec .
* Use ' openssl ciphers - v spec ' to see what ciphers are effectively enabled
* by a cipher suite spec with a given version of OpenSSL .
*/
# define DFLT_CIPHERS "ALL:-aNULL"
2018-10-29 17:30:22 +08:00
static unsigned char SSL_ALPN_HTTP_1_1 [ ] = { 8 , ' h ' , ' t ' , ' t ' , ' p ' , ' / ' , ' 1 ' , ' . ' , ' 1 ' , 0 } ;
static unsigned char SSL_ALPN_HTTP_2 [ ] = { 2 , ' h ' , ' 2 ' , 0 } ;
2018-08-31 14:32:34 +08:00
/*
* Default elliptic curve for EC cipher suites .
*/
# define DFLT_CURVE "prime256v1"
2020-08-24 17:52:55 +08:00
extern long long certstore_is_unavailable ;
2020-05-18 20:32:38 +08:00
2018-08-31 19:59:22 +08:00
enum ssl_stream_stat
{
2018-10-05 18:30:58 +08:00
SSL_UP_NEW ,
2018-08-31 19:59:22 +08:00
SSL_UP_ERR ,
2018-12-05 19:58:34 +08:00
SSL_UP_ERR_NO_CIPHER ,
SSL_UP_ERR_UNSUPPORT_PROTO ,
2018-10-05 13:31:10 +08:00
SSL_UP_CLOSING ,
2018-08-31 19:59:22 +08:00
SSL_UP_CLOSED ,
2018-10-05 18:30:58 +08:00
SSL_UP_DIRTY_CLOSED ,
SSL_UP_CACHE_SZ ,
SSL_UP_CACHE_QUERY ,
SSL_UP_CACHE_HIT ,
2019-09-05 11:37:37 +08:00
2018-10-05 18:30:58 +08:00
SSL_DOWN_NEW ,
2018-08-31 19:59:22 +08:00
SSL_DOWN_ERR ,
2018-12-05 19:58:34 +08:00
SSL_DOWN_ERR_NO_CERT ,
2019-09-05 11:37:37 +08:00
SSL_DOWN_ERR_INAPPROPRIATE_FALLBACK ,
2018-10-05 13:31:10 +08:00
SSL_DOWN_CLOSING ,
2018-08-31 19:59:22 +08:00
SSL_DOWN_CLOSED ,
2018-10-05 13:31:10 +08:00
SSL_DOWN_DIRTY_CLOSED ,
2018-10-05 18:30:58 +08:00
SSL_DOWN_CACHE_SZ ,
SSL_DOWN_CACHE_QUERY ,
SSL_DOWN_CACHE_HIT ,
2018-10-05 21:34:57 +08:00
SSL_DOWN_TICKET_NEW ,
SSL_DOWN_TICKET_REUSE ,
2018-10-08 10:55:03 +08:00
SSL_DOWN_TICKET_NOTFOUND ,
SSL_DOWN_TIKCET_QUERY ,
2019-09-05 11:37:37 +08:00
2018-08-31 19:59:22 +08:00
SSL_NO_CHELLO ,
SSL_NO_SNI ,
SSL_FAKE_CRT ,
2018-11-26 14:54:20 +08:00
KEY_KEEPER_CACHE_SIZE ,
KEY_KEEPER_ASK ,
2018-12-09 19:45:01 +06:00
KEY_KEEPER_ISSUE ,
2018-12-05 19:58:34 +08:00
2019-05-20 16:56:37 +08:00
SSL_SVC_PINNING ,
SSL_SVC_MAUTH ,
SSL_SVC_CT_CERT ,
SSL_SVC_EV_CERT ,
2019-07-26 14:16:07 +06:00
SSL_SVC_APP_NOT_PINNING ,
2020-01-08 14:16:23 +08:00
SSL_SVC_TRUSTED_CERT ,
2018-08-31 19:59:22 +08:00
SSL_STAT_MAX
} ;
2018-11-02 13:52:30 +08:00
2018-08-27 21:10:45 +08:00
struct ssl_mgr
{
2018-08-28 15:25:09 +08:00
unsigned int sslcomp ;
unsigned int no_ssl2 ;
unsigned int no_ssl3 ;
unsigned int no_tls10 ;
unsigned int no_tls11 ;
unsigned int no_tls12 ;
2019-02-18 15:47:29 +06:00
unsigned int no_sesscache ;
2018-10-08 10:55:03 +08:00
unsigned int no_sessticket ;
2018-10-29 17:30:22 +08:00
unsigned int no_alpn ;
2019-01-14 18:23:46 +06:00
unsigned int no_cert_verify ;
2019-01-14 20:35:29 +06:00
unsigned int no_mirror_client_cipher_suite ;
2019-02-19 15:11:15 +06:00
2018-08-27 21:10:45 +08:00
CONST_SSL_METHOD * ( * sslmethod ) ( void ) ; //Parameter of SSL_CTX_new
2018-09-14 18:43:28 +08:00
int ssl_min_version , ssl_max_version ;
2018-08-27 21:10:45 +08:00
char ssl_session_context [ 8 ] ;
2018-08-28 15:25:09 +08:00
2019-06-05 20:43:45 +08:00
unsigned int sess_cache_slots ;
2018-08-28 15:25:09 +08:00
unsigned int sess_expire_seconds ;
2019-06-05 20:43:45 +08:00
unsigned int svc_cache_slots ;
unsigned int svc_expire_seconds ;
2019-06-10 18:39:01 +08:00
unsigned int svc_fail_as_pinning_cnt ;
unsigned int svc_fail_as_proto_err_cnt ;
2019-08-26 15:28:04 +08:00
unsigned int svc_succ_as_app_not_pinning_cnt ;
2019-06-10 18:39:01 +08:00
unsigned int svc_cnt_time_window ;
2019-06-05 20:43:45 +08:00
2018-08-26 14:30:26 +08:00
struct sess_cache * down_sess_cache ;
struct sess_cache * up_sess_cache ;
2019-05-24 17:58:43 +08:00
struct sess_ticket_box * down_stek_box ;
2019-09-05 11:37:37 +08:00
2019-05-16 20:33:42 +08:00
struct ssl_service_cache * svc_cache ;
2019-05-19 17:45:16 +08:00
ssl_stream_new_hook * on_new_upstream_cb ;
void * upstream_cb_param ;
2019-05-24 17:58:43 +08:00
struct sess_ticket_key ticket_key ;
2018-10-05 21:34:57 +08:00
2018-10-08 10:55:03 +08:00
char default_ciphers [ TFE_SYMBOL_MAX ] ;
2018-08-27 21:10:45 +08:00
DH * dh ;
char * ecdhcurve ;
2018-08-31 19:59:22 +08:00
char * crl_url ;
2018-08-27 21:10:45 +08:00
2019-06-14 23:43:03 +08:00
unsigned int trusted_cert_load_local ;
2018-11-12 13:58:01 +08:00
struct cert_store_param cert_verify_param ;
2018-08-27 21:10:45 +08:00
uint8_t ssl_mode_release_buffers ;
2018-11-02 20:38:06 +08:00
char trusted_cert_file [ TFE_PATH_MAX ] ;
char trusted_cert_dir [ TFE_PATH_MAX ] ;
2018-10-31 19:44:13 +08:00
struct ssl_trusted_cert_storage * trust_CA_store ;
2018-09-19 14:25:11 +08:00
struct key_keeper * key_keeper ;
2018-08-31 10:39:25 +08:00
struct event_base * ev_base_gc ;
2018-08-31 19:59:22 +08:00
struct event * gcev ;
2018-10-18 12:13:41 +08:00
unsigned int log_master_key ;
char master_key_file [ TFE_PATH_MAX ] ;
FILE * fp_master_key ;
2019-09-05 11:37:37 +08:00
2018-08-31 19:59:22 +08:00
void * logger ;
2018-10-05 13:31:10 +08:00
screen_stat_handle_t fs_handle ;
2018-08-31 19:59:22 +08:00
long long stat_val [ SSL_STAT_MAX ] ;
int fs_id [ SSL_STAT_MAX ] ;
2018-08-23 19:46:38 +08:00
} ;
2018-08-26 14:30:26 +08:00
2018-08-26 18:26:24 +08:00
struct __ssl_stream_debug
{
evutil_socket_t fd ;
} ;
2019-05-17 21:35:20 +08:00
struct ssl_bypass_condition
2019-05-14 19:58:23 +08:00
{
char bypass_ev_cert ;
char bypass_ct_cert ;
char bypass_mutual_auth ;
char bypass_cert_pinning ;
} ;
struct ssl_upstream_parts
{
2019-09-05 11:37:37 +08:00
2019-05-14 19:58:23 +08:00
struct cert_verify_param verify_param ;
2019-05-15 20:09:12 +08:00
struct cert_verify_result verify_result ;
2019-05-17 21:35:20 +08:00
char block_fake_cert ;
2019-05-16 20:33:42 +08:00
struct ssl_service_status svc_status ;
2019-05-17 21:35:20 +08:00
enum ssl_stream_action action ;
2019-05-27 14:17:52 +08:00
int apln_enabled ;
2022-11-08 10:53:05 +08:00
int keyring_for_trusted ;
int keyring_for_untrusted ;
2019-05-14 19:58:23 +08:00
struct ssl_chello * client_hello ;
2023-04-23 16:55:30 +08:00
uint8_t is_server_cert_verify_passed ;
2019-05-14 19:58:23 +08:00
} ;
struct ssl_downstream_parts
{
2019-05-16 20:33:42 +08:00
struct keyring * keyring ;
2019-05-14 19:58:23 +08:00
} ;
2018-08-27 21:10:45 +08:00
struct ssl_stream
{
2018-08-24 10:55:47 +08:00
enum tfe_conn_dir dir ;
2018-08-27 21:10:45 +08:00
SSL * ssl ;
2018-08-26 14:30:26 +08:00
struct ssl_mgr * mgr ;
2018-08-26 18:26:24 +08:00
union
{
2019-05-14 19:58:23 +08:00
struct ssl_upstream_parts up_parts ;
struct ssl_downstream_parts down_parts ;
2018-08-26 18:26:24 +08:00
} ;
2019-05-18 18:27:13 +08:00
int ssl_min_version , ssl_max_version , negotiated_version ;
2019-05-14 19:58:23 +08:00
const unsigned char * alpn_selected ; //reference to SSL_ALPN_HTTP_2/SSL_ALPN_HTTP_1_1
2019-06-01 20:28:07 +08:00
struct tfe_stream * tcp_stream ;
uint64_t connect_latency_ms ;
2019-05-16 20:33:42 +08:00
struct ssl_stream * peer ;
2019-06-21 16:10:26 +08:00
socklen_t peer_addrlen ;
struct sockaddr_storage peer_addr ;
2018-08-26 18:26:24 +08:00
struct __ssl_stream_debug _do_not_use ;
2019-06-01 20:28:07 +08:00
enum ssl_stream_error error ;
2018-08-23 19:46:38 +08:00
} ;
2018-08-26 14:30:26 +08:00
2018-08-21 19:01:10 +08:00
2018-08-27 21:10:45 +08:00
struct peek_client_hello_ctx
{
2018-09-14 18:43:28 +08:00
struct ssl_chello * chello ;
2018-08-27 21:10:45 +08:00
unsigned char sni_peek_retries ; /* max 64 SNI parse retries */
2018-08-26 14:30:26 +08:00
struct event * ev ;
struct event_base * evbase ;
2018-08-27 21:10:45 +08:00
void * logger ;
2018-08-21 16:11:50 +08:00
} ;
2018-08-26 14:30:26 +08:00
2018-10-18 12:13:41 +08:00
struct ssl_connect_server_ctx
2018-08-27 21:10:45 +08:00
{
2018-08-26 14:30:26 +08:00
struct bufferevent * bev ;
struct ssl_stream * s_stream ;
struct ssl_mgr * mgr ;
2018-08-28 15:25:09 +08:00
struct sockaddr_storage addr ;
2018-08-27 21:10:45 +08:00
socklen_t addrlen ;
void * logger ;
2018-08-26 14:30:26 +08:00
evutil_socket_t fd_upstream ;
evutil_socket_t fd_downstream ;
2019-09-05 11:37:37 +08:00
2019-06-01 20:28:07 +08:00
struct tfe_stream * tcp_stream ;
2019-09-05 11:37:37 +08:00
2018-08-26 14:30:26 +08:00
struct future * f_peek_chello ;
2018-11-21 18:56:04 +08:00
struct timespec start , end ;
2018-08-26 14:30:26 +08:00
} ;
2018-10-18 12:13:41 +08:00
struct ssl_connect_client_ctx
2018-08-27 21:10:45 +08:00
{
2019-06-01 20:28:07 +08:00
struct tfe_stream * tcp_stream ;
struct ssl_stream * peer ;
2018-08-27 21:10:45 +08:00
X509 * origin_crt ;
2018-10-08 15:06:01 +08:00
int is_origin_crt_verify_passed ;
2018-08-26 14:30:26 +08:00
struct ssl_mgr * ssl_mgr ;
evutil_socket_t fd_downstream ;
2018-08-27 21:10:45 +08:00
2018-10-08 15:06:01 +08:00
struct future * f_ask_keyring ;
2018-08-26 14:30:26 +08:00
struct bufferevent * bev_down ;
2018-08-27 21:10:45 +08:00
struct ssl_stream * downstream ;
2018-11-21 18:56:04 +08:00
struct timespec start , end ;
2018-08-23 19:46:38 +08:00
} ;
2018-08-26 14:30:26 +08:00
2018-08-24 10:55:47 +08:00
/*
* SSL shutdown context .
*/
2018-08-27 21:10:45 +08:00
struct ssl_shutdown_ctx
{
2018-08-26 14:30:26 +08:00
struct ssl_stream * s_stream ;
struct event_base * evbase ;
struct event * ev ;
2018-10-05 18:30:58 +08:00
struct ssl_mgr * mgr ;
enum tfe_conn_dir dir ;
2018-08-27 21:10:45 +08:00
unsigned int retries ;
2018-08-24 10:55:47 +08:00
} ;
2018-08-31 19:59:22 +08:00
struct fs_spec
{
enum ssl_stream_stat id ;
const char * name ;
} ;
2021-11-02 22:27:56 +08:00
unsigned int is_ssl_debug ( )
{
return ssl_debug ;
}
2019-05-20 15:08:42 +08:00
int sslver_str2num ( const char * version_str )
{
int sslversion = - 1 ;
assert ( OPENSSL_VERSION_NUMBER > = 0x10100000L ) ;
/*
* Support for SSLv2 and the corresponding SSLv2_method ( ) ,
* SSLv2_server_method ( ) and SSLv2_client_method ( ) functions were
* removed in OpenSSL 1.1 .0 .
*/
2019-06-17 20:55:20 +08:00
if ( ! strcasecmp ( version_str , " ssl3 " ) | | ! strcasecmp ( version_str , " SSLv3 " ) | | ! strcasecmp ( version_str , " sslv3.0 " ) )
2019-05-20 15:08:42 +08:00
{
sslversion = SSL3_VERSION ;
}
2019-06-10 21:27:27 +08:00
else if ( ! strcasecmp ( version_str , " tls10 " ) | | ! strcasecmp ( version_str , " tls1 " ) | |
! strcasecmp ( version_str , " TLSv1.0 " ) | | ! strcasecmp ( version_str , " TLSv1 " ) )
2019-05-20 15:08:42 +08:00
{
sslversion = TLS1_VERSION ;
}
2019-06-10 21:27:27 +08:00
else if ( ! strcasecmp ( version_str , " tls11 " ) | | ! strcasecmp ( version_str , " TLSv1.1 " ) )
2019-05-20 15:08:42 +08:00
{
sslversion = TLS1_1_VERSION ;
}
2019-06-10 21:27:27 +08:00
else if ( ! strcasecmp ( version_str , " tls12 " ) | | ! strcasecmp ( version_str , " TLSv1.2 " ) )
2019-05-20 15:08:42 +08:00
{
sslversion = TLS1_2_VERSION ;
}
2019-06-10 21:27:27 +08:00
else if ( ! strcasecmp ( version_str , " tls13 " ) | | ! strcasecmp ( version_str , " TLSv1.3 " ) )
2019-05-20 15:08:42 +08:00
{
sslversion = TLS1_3_VERSION ;
}
else
{
sslversion = - 1 ;
}
return sslversion ;
}
2019-06-01 20:28:07 +08:00
const char * ssl_stream_get_error_string ( enum ssl_stream_error error )
{
const char * ssl_err_str [ __SSL_STREAM_R_MAX ] ;
ssl_err_str [ SSL_STREAM_R_NO_ERROR ] = " OK " ;
ssl_err_str [ SSL_STREAM_R_SERVER_CLOSED ] = " server-side closed " ;
ssl_err_str [ SSL_STREAM_R_CLIENT_CLOSED ] = " client-side closed " ;
ssl_err_str [ SSL_STREAM_R_CONNECT_SERVER_TIMEOUT ] = " server-side timeout " ;
ssl_err_str [ SSL_STREAM_R_CONNECT_CLIENT_TIMEOUT ] = " client-side timeout " ;
ssl_err_str [ SSL_STREAM_R_SERVER_PROTOCOL_ERROR ] = " server-side protocol errors " ;
ssl_err_str [ SSL_STREAM_R_CLIENT_PROTOCOL_ERROR ] = " client-side protocol errors " ;
return ssl_err_str [ error ] ;
}
2018-10-17 20:21:21 +08:00
/*
* Garbage collection handler .
*/
static void
ssl_stream_gc_cb ( evutil_socket_t fd , short what , void * arg )
{
struct ssl_mgr * mgr = ( struct ssl_mgr * ) arg ;
int i = 0 ;
2019-02-18 15:47:29 +06:00
if ( ! mgr - > no_sesscache )
2019-09-05 11:37:37 +08:00
{
2019-02-18 15:47:29 +06:00
ssl_sess_cache_stat ( mgr - > up_sess_cache , & ( mgr - > stat_val [ SSL_UP_CACHE_SZ ] ) , & ( mgr - > stat_val [ SSL_UP_CACHE_QUERY ] ) , & ( mgr - > stat_val [ SSL_UP_CACHE_HIT ] ) ) ;
ssl_sess_cache_stat ( mgr - > down_sess_cache , & ( mgr - > stat_val [ SSL_DOWN_CACHE_SZ ] ) , & ( mgr - > stat_val [ SSL_DOWN_CACHE_QUERY ] ) , & ( mgr - > stat_val [ SSL_DOWN_CACHE_HIT ] ) ) ;
}
2020-08-31 13:11:27 +08:00
struct key_keeper_stat keeper_stat = { 0 } ;
2018-11-26 14:54:20 +08:00
key_keeper_statistic ( mgr - > key_keeper , & keeper_stat ) ;
mgr - > stat_val [ KEY_KEEPER_ASK ] = keeper_stat . ask_times ;
2018-12-09 19:45:01 +06:00
mgr - > stat_val [ KEY_KEEPER_ISSUE ] = keeper_stat . new_issue ;
2018-11-26 14:54:20 +08:00
mgr - > stat_val [ KEY_KEEPER_CACHE_SIZE ] = keeper_stat . cached_num ;
2019-09-05 11:37:37 +08:00
2019-05-20 16:56:37 +08:00
struct ssl_service_cache_statistics svc_stat ;
memset ( & svc_stat , 0 , sizeof ( svc_stat ) ) ;
ssl_service_cache_stat ( mgr - > svc_cache , & svc_stat ) ;
mgr - > stat_val [ SSL_SVC_PINNING ] = svc_stat . pinning_cli_cnt ;
mgr - > stat_val [ SSL_SVC_MAUTH ] = svc_stat . mutual_auth_cli_cnt ;
mgr - > stat_val [ SSL_SVC_CT_CERT ] = svc_stat . ct_srv_cnt ;
2019-09-05 11:37:37 +08:00
mgr - > stat_val [ SSL_SVC_EV_CERT ] = svc_stat . ev_srv_cnt ;
2019-07-26 14:16:07 +06:00
mgr - > stat_val [ SSL_SVC_APP_NOT_PINNING ] = svc_stat . app_not_pinning_cnt ;
2020-01-08 14:16:23 +08:00
mgr - > stat_val [ SSL_SVC_TRUSTED_CERT ] = svc_stat . trusted_cert_cnt ;
2018-10-17 20:21:21 +08:00
for ( i = 0 ; i < SSL_STAT_MAX ; i + + )
{
FS_operate ( mgr - > fs_handle , mgr - > fs_id [ i ] , 0 , FS_OP_SET , ATOMIC_READ ( & ( mgr - > stat_val [ i ] ) ) ) ;
}
2018-10-18 12:13:41 +08:00
if ( mgr - > log_master_key & & mgr - > fp_master_key )
{
fflush ( mgr - > fp_master_key ) ;
}
2018-10-17 20:21:21 +08:00
return ;
}
2018-08-31 19:59:22 +08:00
void ssl_stat_init ( struct ssl_mgr * mgr )
{
int i = 0 ;
2018-10-08 10:55:03 +08:00
const char * spec [ SSL_STAT_MAX ] = { 0 } ;
2018-10-05 18:30:58 +08:00
spec [ SSL_UP_NEW ] = " ussl_new " ;
2018-12-05 19:58:34 +08:00
spec [ SSL_UP_ERR ] = " ussl_err " ;
spec [ SSL_UP_ERR_NO_CIPHER ] = " ussl_e_ciph " ;
2018-12-05 22:56:11 +08:00
spec [ SSL_UP_ERR_UNSUPPORT_PROTO ] = " ussl_e_prt " ;
2019-09-05 11:37:37 +08:00
2018-10-05 18:30:58 +08:00
spec [ SSL_UP_CLOSING ] = " ussl_clsing " ;
2019-02-18 15:47:29 +06:00
spec [ SSL_UP_CLOSED ] = " ussl_clsd " ;
2018-12-05 22:56:11 +08:00
spec [ SSL_UP_DIRTY_CLOSED ] = " ussl_dt_cls " ;
2018-10-05 18:30:58 +08:00
spec [ SSL_UP_CACHE_SZ ] = " usess_cache " ;
spec [ SSL_UP_CACHE_QUERY ] = " usess_query " ;
2018-12-05 22:56:11 +08:00
spec [ SSL_UP_CACHE_HIT ] = " usess_hitn " ;
2019-09-05 11:37:37 +08:00
2018-10-05 18:30:58 +08:00
spec [ SSL_DOWN_NEW ] = " dssl_new " ;
spec [ SSL_DOWN_ERR ] = " dssl_err " ;
2018-12-05 22:56:11 +08:00
spec [ SSL_DOWN_ERR_NO_CERT ] = " dssl_e_cert " ;
2018-12-05 19:58:34 +08:00
spec [ SSL_DOWN_ERR_INAPPROPRIATE_FALLBACK ] = " dssl_e_fb " ;
2019-09-05 11:37:37 +08:00
spec [ SSL_DOWN_CLOSING ] = " dssl_clsing " ;
2019-02-18 15:47:29 +06:00
spec [ SSL_DOWN_CLOSED ] = " dssl_clsd " ;
2018-12-05 22:56:11 +08:00
spec [ SSL_DOWN_DIRTY_CLOSED ] = " dssl_dt_cls " ;
2018-10-05 18:30:58 +08:00
spec [ SSL_DOWN_CACHE_SZ ] = " dsess_cache " ;
spec [ SSL_DOWN_CACHE_QUERY ] = " dcache_query " ;
2018-12-05 22:56:11 +08:00
spec [ SSL_DOWN_CACHE_HIT ] = " dsess_hitn " ;
2019-09-05 11:37:37 +08:00
2018-10-08 10:55:03 +08:00
if ( ! mgr - > no_sessticket )
{
spec [ SSL_DOWN_TICKET_NEW ] = " dtkt_new " ;
spec [ SSL_DOWN_TICKET_REUSE ] = " dtkt_reuse " ;
spec [ SSL_DOWN_TICKET_NOTFOUND ] = " dtkt_notfnd " ;
spec [ SSL_DOWN_TIKCET_QUERY ] = " dtkt_query " ;
}
2018-10-05 13:31:10 +08:00
spec [ SSL_NO_CHELLO ] = " ssl_no_chlo " ;
spec [ SSL_NO_SNI ] = " ssl_no_sni " ;
spec [ SSL_FAKE_CRT ] = " ssl_fk_crt " ;
2018-11-26 14:54:20 +08:00
spec [ KEY_KEEPER_ASK ] = " kyr_ask " ;
2018-12-09 19:45:01 +06:00
spec [ KEY_KEEPER_ISSUE ] = " kyr_new " ;
2018-11-26 14:54:20 +08:00
spec [ KEY_KEEPER_CACHE_SIZE ] = " kyr_cache " ;
2018-10-05 13:31:10 +08:00
2019-05-20 16:56:37 +08:00
spec [ SSL_SVC_PINNING ] = " ssl_pinning " ;
spec [ SSL_SVC_MAUTH ] = " ssl_mauth " ;
spec [ SSL_SVC_CT_CERT ] = " ssl_ct_crt " ;
spec [ SSL_SVC_EV_CERT ] = " ssl_ev_crt " ;
2019-07-26 14:16:07 +06:00
spec [ SSL_SVC_APP_NOT_PINNING ] = " app_no_pinning " ;
2019-09-05 11:37:37 +08:00
2020-01-08 14:16:23 +08:00
spec [ SSL_SVC_TRUSTED_CERT ] = " trusted_cert_nums " ;
2019-05-20 16:56:37 +08:00
2018-08-31 19:59:22 +08:00
for ( i = 0 ; i < SSL_STAT_MAX ; i + + )
{
2018-10-08 10:55:03 +08:00
if ( spec [ i ] ! = NULL )
{
2019-01-14 18:23:46 +06:00
mgr - > fs_id [ i ] = FS_register ( mgr - > fs_handle , FS_STYLE_FIELD , FS_CALC_CURRENT , spec [ i ] ) ;
2018-10-08 10:55:03 +08:00
}
2018-08-31 19:59:22 +08:00
}
2018-10-05 18:30:58 +08:00
int value = mgr - > fs_id [ SSL_UP_CACHE_HIT ] ;
FS_set_para ( mgr - > fs_handle , ID_INVISBLE , & value , sizeof ( value ) ) ;
value = mgr - > fs_id [ SSL_UP_CACHE_QUERY ] ;
FS_set_para ( mgr - > fs_handle , ID_INVISBLE , & value , sizeof ( value ) ) ;
2019-09-05 11:37:37 +08:00
2018-10-05 18:30:58 +08:00
FS_register_ratio ( mgr - > fs_handle ,
2019-09-05 11:37:37 +08:00
mgr - > fs_id [ SSL_UP_CACHE_HIT ] ,
mgr - > fs_id [ SSL_UP_CACHE_QUERY ] ,
2018-10-05 18:30:58 +08:00
1 ,
FS_STYLE_STATUS ,
FS_CALC_CURRENT ,
" usess_hit " ) ;
2018-11-02 13:52:30 +08:00
2018-10-05 18:30:58 +08:00
value = mgr - > fs_id [ SSL_DOWN_CACHE_HIT ] ;
FS_set_para ( mgr - > fs_handle , ID_INVISBLE , & value , sizeof ( value ) ) ;
value = mgr - > fs_id [ SSL_DOWN_CACHE_QUERY ] ;
FS_set_para ( mgr - > fs_handle , ID_INVISBLE , & value , sizeof ( value ) ) ;
2019-09-05 11:37:37 +08:00
2018-10-05 18:30:58 +08:00
FS_register_ratio ( mgr - > fs_handle ,
2019-09-05 11:37:37 +08:00
mgr - > fs_id [ SSL_DOWN_CACHE_HIT ] ,
mgr - > fs_id [ SSL_DOWN_CACHE_QUERY ] ,
2018-10-05 18:30:58 +08:00
1 ,
FS_STYLE_STATUS ,
FS_CALC_CURRENT ,
2018-10-08 10:55:03 +08:00
" dsess_hit " ) ;
2018-11-02 13:52:30 +08:00
2018-10-08 10:55:03 +08:00
if ( ! mgr - > no_sessticket )
{
value = mgr - > fs_id [ SSL_DOWN_TIKCET_QUERY ] ;
FS_set_para ( mgr - > fs_handle , ID_INVISBLE , & value , sizeof ( value ) ) ;
2019-09-05 11:37:37 +08:00
2018-10-08 10:55:03 +08:00
value = mgr - > fs_id [ SSL_DOWN_TICKET_REUSE ] ;
FS_set_para ( mgr - > fs_handle , ID_INVISBLE , & value , sizeof ( value ) ) ;
2019-09-05 11:37:37 +08:00
2018-10-08 10:55:03 +08:00
FS_register_ratio ( mgr - > fs_handle ,
2019-09-05 11:37:37 +08:00
mgr - > fs_id [ SSL_DOWN_TICKET_REUSE ] ,
mgr - > fs_id [ SSL_DOWN_TIKCET_QUERY ] ,
2018-10-08 10:55:03 +08:00
1 ,
FS_STYLE_STATUS ,
FS_CALC_CURRENT ,
" dtkt_hit " ) ;
}
2019-09-05 11:37:37 +08:00
2018-10-17 20:21:21 +08:00
struct timeval gc_delay = { 0 , 500 * 1000 } ; //Microseconds, we set 500 miliseconds here.
2019-09-05 11:37:37 +08:00
mgr - > gcev = event_new ( mgr - > ev_base_gc , - 1 , EV_PERSIST , ssl_stream_gc_cb , mgr ) ;
2018-10-17 20:21:21 +08:00
evtimer_add ( mgr - > gcev , & gc_delay ) ;
2018-08-31 19:59:22 +08:00
return ;
}
2019-05-24 14:20:44 +08:00
static void downstream_ossl_init ( struct ssl_stream * s_stream ) ;
2019-08-28 14:17:21 +08:00
static int upstream_ossl_init ( struct ssl_stream * s_stream ) ;
2019-05-14 21:02:06 +08:00
2018-08-27 21:10:45 +08:00
static void sslctx_set_opts ( SSL_CTX * sslctx , struct ssl_mgr * mgr ) ;
struct ssl_chello * ssl_peek_result_release_chello ( future_result_t * result )
{
2018-09-14 18:43:28 +08:00
struct peek_client_hello_ctx * ctx = ( struct peek_client_hello_ctx * ) result ;
struct ssl_chello * p = ctx - > chello ;
ctx - > chello = NULL ;
return p ;
2018-08-27 21:10:45 +08:00
}
struct ssl_stream * ssl_stream_new ( struct ssl_mgr * mgr , evutil_socket_t fd , enum tfe_conn_dir dir ,
2019-06-01 20:28:07 +08:00
struct ssl_chello * client_hello , struct keyring * kyr , struct ssl_stream * peer , struct tfe_stream * tcp_stream )
2018-08-26 18:26:24 +08:00
{
2018-09-07 15:19:28 +08:00
2018-11-26 16:30:51 +08:00
UNUSED int ret = 0 ;
2019-05-18 18:27:13 +08:00
2018-08-26 14:30:26 +08:00
struct ssl_stream * s_stream = ALLOC ( struct ssl_stream , 1 ) ;
2018-08-27 21:10:45 +08:00
s_stream - > dir = dir ;
s_stream - > mgr = mgr ;
s_stream - > _do_not_use . fd = fd ;
2019-05-18 18:27:13 +08:00
s_stream - > ssl_max_version = mgr - > ssl_max_version ;
s_stream - > ssl_min_version = mgr - > ssl_min_version ;
s_stream - > peer = peer ;
2019-06-01 20:28:07 +08:00
s_stream - > tcp_stream = tcp_stream ;
2019-06-21 16:10:26 +08:00
ret = getpeername ( fd , ( struct sockaddr * ) ( & s_stream - > peer_addr ) , & ( s_stream - > peer_addrlen ) ) ;
2018-08-26 18:26:24 +08:00
switch ( dir )
{
2019-05-18 18:27:13 +08:00
case CONN_DIR_DOWNSTREAM :
assert ( peer ! = NULL ) ;
2018-10-05 18:30:58 +08:00
ATOMIC_INC ( & ( s_stream - > mgr - > stat_val [ SSL_DOWN_NEW ] ) ) ;
2019-05-14 19:58:23 +08:00
s_stream - > down_parts . keyring = kyr ;
2019-05-24 14:20:44 +08:00
s_stream - > peer = peer ;
2018-08-26 18:26:24 +08:00
break ;
2019-05-18 18:27:13 +08:00
case CONN_DIR_UPSTREAM :
2018-10-05 18:30:58 +08:00
ATOMIC_INC ( & ( s_stream - > mgr - > stat_val [ SSL_UP_NEW ] ) ) ;
2019-05-18 18:27:13 +08:00
s_stream - > up_parts . verify_param . no_verify_cn = 1 ;
s_stream - > up_parts . client_hello = client_hello ;
s_stream - > ssl_min_version = client_hello - > min_version . ossl_format ;
s_stream - > ssl_max_version = client_hello - > max_version . ossl_format ;
2018-08-26 18:26:24 +08:00
break ;
2018-08-27 21:10:45 +08:00
default : assert ( 0 ) ;
2018-08-26 18:26:24 +08:00
}
2018-08-26 14:30:26 +08:00
return s_stream ;
2018-08-26 18:26:24 +08:00
}
2018-08-26 14:30:26 +08:00
static void ssl_stream_free ( struct ssl_stream * s_stream )
{
2019-05-24 14:20:44 +08:00
if ( s_stream - > ssl )
{
SSL_free ( s_stream - > ssl ) ;
s_stream - > ssl = NULL ;
}
2018-08-26 18:26:24 +08:00
switch ( s_stream - > dir )
{
case CONN_DIR_DOWNSTREAM :
2019-05-14 19:58:23 +08:00
if ( s_stream - > down_parts . keyring ! = NULL )
2018-08-26 18:26:24 +08:00
{
2019-05-14 19:58:23 +08:00
key_keeper_free_keyring ( s_stream - > down_parts . keyring ) ;
s_stream - > down_parts . keyring = NULL ;
2019-09-05 11:37:37 +08:00
}
2018-10-05 18:30:58 +08:00
ATOMIC_INC ( & ( s_stream - > mgr - > stat_val [ SSL_DOWN_CLOSED ] ) ) ;
2018-08-26 18:26:24 +08:00
break ;
case CONN_DIR_UPSTREAM :
2019-05-14 19:58:23 +08:00
if ( s_stream - > up_parts . client_hello ! = NULL )
2019-09-05 11:37:37 +08:00
{
2019-05-14 19:58:23 +08:00
ssl_chello_free ( s_stream - > up_parts . client_hello ) ;
s_stream - > up_parts . client_hello = NULL ;
2018-08-26 18:26:24 +08:00
}
2018-10-05 18:30:58 +08:00
ATOMIC_INC ( & ( s_stream - > mgr - > stat_val [ SSL_UP_CLOSED ] ) ) ;
2018-08-26 18:26:24 +08:00
break ;
2018-08-27 21:10:45 +08:00
default : assert ( 0 ) ;
2018-08-26 14:30:26 +08:00
}
2018-10-29 17:30:22 +08:00
if ( s_stream - > alpn_selected )
{
s_stream - > alpn_selected = NULL ;
}
2018-08-27 21:10:45 +08:00
s_stream - > mgr = NULL ;
2018-08-26 14:30:26 +08:00
free ( s_stream ) ;
return ;
}
2021-04-28 18:01:32 +08:00
static void log_ssl_master_key ( struct ssl_stream * s_stream , tfe_conn_dir dir , FILE * fp )
2018-10-18 12:13:41 +08:00
{
char * key_str = NULL ;
2021-04-28 18:01:32 +08:00
key_str = ssl_ssl_masterkey_to_str ( s_stream - > ssl ) ;
2018-10-18 12:13:41 +08:00
char time_str [ TFE_SYMBOL_MAX ] ;
time_t now = time ( NULL ) ;
tfe_thread_safe_ctime ( & now , time_str , sizeof ( time_str ) ) ;
2021-04-28 18:01:32 +08:00
fprintf ( fp , " #%s %s %s \n %s \n " , time_str , tfe_stream_conn_dir_to_str ( dir ) , s_stream - > tcp_stream - > str_stream_info ? s_stream - > tcp_stream - > str_stream_info : NULL , key_str ) ;
2018-10-18 12:13:41 +08:00
free ( key_str ) ;
return ;
}
2018-08-26 14:30:26 +08:00
void ssl_manager_destroy ( struct ssl_mgr * mgr )
2018-08-23 19:46:38 +08:00
{
2018-10-18 12:13:41 +08:00
if ( mgr - > key_keeper )
2018-08-26 18:26:24 +08:00
{
2018-09-19 14:25:11 +08:00
key_keeper_destroy ( mgr - > key_keeper ) ;
2018-08-26 18:26:24 +08:00
}
2018-10-18 12:13:41 +08:00
if ( mgr - > trust_CA_store )
2018-08-26 18:26:24 +08:00
{
2018-10-31 19:44:13 +08:00
ssl_trusted_cert_storage_destroy ( mgr - > trust_CA_store ) ;
2018-08-27 21:10:45 +08:00
mgr - > trust_CA_store = NULL ;
2018-08-26 18:26:24 +08:00
}
2018-10-18 12:13:41 +08:00
if ( mgr - > down_sess_cache )
2018-08-31 19:59:22 +08:00
{
ssl_sess_cache_destroy ( mgr - > down_sess_cache ) ;
}
2018-10-18 12:13:41 +08:00
if ( mgr - > up_sess_cache )
2018-08-31 19:59:22 +08:00
{
ssl_sess_cache_destroy ( mgr - > up_sess_cache ) ;
}
2018-10-18 12:13:41 +08:00
if ( mgr - > gcev )
2018-08-31 19:59:22 +08:00
{
event_free ( mgr - > gcev ) ;
}
2018-10-18 12:13:41 +08:00
if ( mgr - > fp_master_key )
{
fclose ( mgr - > fp_master_key ) ;
}
2018-08-23 19:46:38 +08:00
free ( mgr ) ;
}
2018-10-17 20:21:21 +08:00
2018-08-23 19:46:38 +08:00
2019-09-16 16:40:31 +08:00
struct ssl_mgr * ssl_manager_init ( const char * ini_profile , const char * section ,
2019-09-16 14:01:14 +08:00
struct event_base * ev_base_gc , struct key_keeper * key_keeper , void * logger )
2018-08-27 21:10:45 +08:00
{
2019-05-24 17:58:43 +08:00
unsigned int stek_group_num = 0 ;
unsigned int stek_rotation_time = 0 ;
2018-08-26 14:30:26 +08:00
struct ssl_mgr * mgr = ALLOC ( struct ssl_mgr , 1 ) ;
2018-09-05 10:38:27 +08:00
int ret = 0 ;
2018-11-26 16:04:03 +08:00
2020-12-25 21:52:14 +06:00
char ja3_table_name [ TFE_STRING_MAX ] = { 0 } ;
char version_str [ TFE_SYMBOL_MAX ] = { } ;
2018-08-26 14:30:26 +08:00
mgr - > logger = logger ;
2018-08-31 19:59:22 +08:00
mgr - > ev_base_gc = ev_base_gc ;
2019-10-28 17:10:38 +08:00
if ( ssl_mid_cert_kafka_logger_create ( ini_profile , section ) )
{
goto error_out ;
}
2021-11-02 22:27:56 +08:00
MESA_load_profile_uint_def ( ini_profile , section , " ssl_debug " , & ( ssl_debug ) , 0 ) ;
2020-08-24 17:52:55 +08:00
MESA_load_profile_string_def ( ini_profile , section , " ssl_min_version " , version_str , sizeof ( version_str ) , " ssl3 " ) ;
2018-09-14 18:43:28 +08:00
mgr - > ssl_min_version = sslver_str2num ( version_str ) ;
2018-11-26 16:04:03 +08:00
if ( mgr - > ssl_min_version < 0 )
{
TFE_LOG_ERROR ( logger , " Unsupported SSL/TLS protocol %s " , version_str ) ;
goto error_out ;
}
2018-09-14 18:43:28 +08:00
MESA_load_profile_string_def ( ini_profile , section , " ssl_max_version " , version_str , sizeof ( version_str ) , " tls12 " ) ;
mgr - > ssl_max_version = sslver_str2num ( version_str ) ;
2018-11-26 16:04:03 +08:00
if ( mgr - > ssl_max_version < 0 )
2018-08-27 21:10:45 +08:00
{
2018-08-26 14:30:26 +08:00
TFE_LOG_ERROR ( logger , " Unsupported SSL/TLS protocol %s " , version_str ) ;
2018-08-24 19:22:43 +08:00
goto error_out ;
2018-08-23 19:46:38 +08:00
}
2018-11-26 16:04:03 +08:00
2018-09-02 15:46:39 +08:00
ret = ssl_init ( ) ;
if ( ret < 0 )
{
TFE_LOG_ERROR ( logger , " OpenSSL global init failed. " ) ;
goto error_out ;
}
2018-08-24 19:22:43 +08:00
//tfe2a uses SSLv23_method, it was been deprecated and replaced with the TLS_method() in openssl 1.1.0.
2018-08-26 14:30:26 +08:00
mgr - > sslmethod = TLS_method ;
2019-05-16 20:33:42 +08:00
SSL_CTX_EX_DATA_IDX_SSLMGR = SSL_CTX_get_ex_new_index ( 0 , NULL , NULL , NULL , NULL ) ;
SSL_EX_DATA_IDX_SSLSTREAM = SSL_get_ex_new_index ( 0 , NULL , NULL , NULL , NULL ) ;
2018-08-28 15:25:09 +08:00
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 ) ;
2019-05-25 15:54:28 +08:00
MESA_load_profile_uint_def ( ini_profile , section , " no_ssl3 " , & ( mgr - > no_ssl3 ) , 0 ) ;
2018-10-04 18:34:18 +08:00
MESA_load_profile_uint_def ( ini_profile , section , " no_tls10 " , & ( mgr - > no_tls10 ) , 0 ) ;
2018-08-28 15:25:09 +08:00
MESA_load_profile_uint_def ( ini_profile , section , " no_tls11 " , & ( mgr - > no_tls11 ) , 0 ) ;
MESA_load_profile_uint_def ( ini_profile , section , " no_tls12 " , & ( mgr - > no_tls12 ) , 0 ) ;
2019-09-05 11:37:37 +08:00
MESA_load_profile_string_def ( ini_profile , section , " default_ciphers " , mgr - > default_ciphers ,
2018-08-31 14:32:34 +08:00
sizeof ( mgr - > default_ciphers ) , DFLT_CIPHERS ) ;
2019-02-19 15:11:15 +06:00
2019-02-18 15:47:29 +06:00
MESA_load_profile_uint_def ( ini_profile , section , " no_session_cache " , & ( mgr - > no_sesscache ) , 0 ) ;
2018-10-08 10:55:03 +08:00
MESA_load_profile_uint_def ( ini_profile , section , " no_session_ticket " , & ( mgr - > no_sessticket ) , 0 ) ;
2018-10-29 17:30:22 +08:00
MESA_load_profile_uint_def ( ini_profile , section , " no_alpn " , & ( mgr - > no_alpn ) , 0 ) ;
2019-01-14 18:23:46 +06:00
MESA_load_profile_uint_def ( ini_profile , section , " no_cert_verify " , & ( mgr - > no_cert_verify ) , 0 ) ;
2018-08-31 14:32:34 +08:00
2019-02-19 15:11:15 +06:00
MESA_load_profile_uint_def ( ini_profile , section , " no_mirror_client_cipher_suite " ,
& ( mgr - > no_mirror_client_cipher_suite ) , 0 ) ;
MESA_load_profile_uint_def ( ini_profile , section , " session_cache_slots " ,
2019-06-05 20:43:45 +08:00
& ( mgr - > sess_cache_slots ) , 4 * 1024 * 1024 ) ;
2019-02-19 15:11:15 +06:00
MESA_load_profile_uint_def ( ini_profile , section , " session_cache_expire_seconds " ,
& ( mgr - > sess_expire_seconds ) , 30 * 60 ) ;
2019-09-05 11:37:37 +08:00
2018-08-23 19:46:38 +08:00
2019-02-18 15:47:29 +06:00
if ( ! mgr - > no_sesscache )
{
2019-06-05 20:43:45 +08:00
mgr - > up_sess_cache = ssl_sess_cache_create ( mgr - > sess_cache_slots , mgr - > sess_expire_seconds , CONN_DIR_UPSTREAM ) ;
mgr - > down_sess_cache = ssl_sess_cache_create ( mgr - > sess_cache_slots , mgr - > sess_expire_seconds , CONN_DIR_DOWNSTREAM ) ;
2019-02-18 15:47:29 +06:00
}
2019-09-05 11:37:37 +08:00
2019-05-24 17:58:43 +08:00
MESA_load_profile_uint_def ( ini_profile , section , " stek_group_num " , & stek_group_num , 1 ) ;
MESA_load_profile_uint_def ( ini_profile , section , " stek_rotation_time " , & stek_rotation_time , 3600 ) ;
if ( ! mgr - > no_sessticket )
{
mgr - > down_stek_box = sess_ticket_box_create ( ev_base_gc , stek_group_num , stek_rotation_time , logger ) ;
}
2019-06-05 20:43:45 +08:00
MESA_load_profile_uint_def ( ini_profile , section , " service_cache_slots " ,
& ( mgr - > svc_cache_slots ) , 4 * 1024 * 1024 ) ;
MESA_load_profile_uint_def ( ini_profile , section , " service_cache_expire_seconds " ,
& ( mgr - > svc_expire_seconds ) , 5 * 60 ) ;
2019-06-10 18:39:01 +08:00
MESA_load_profile_uint_def ( ini_profile , section , " service_cache_fail_as_pinning_cnt " ,
& ( mgr - > svc_fail_as_pinning_cnt ) , 4 ) ;
MESA_load_profile_uint_def ( ini_profile , section , " service_cache_fail_as_proto_err_cnt " ,
& ( mgr - > svc_fail_as_proto_err_cnt ) , 5 ) ;
MESA_load_profile_uint_def ( ini_profile , section , " service_cache_fail_time_window " ,
& ( mgr - > svc_cnt_time_window ) , 30 ) ;
2020-12-25 21:52:14 +06:00
MESA_load_profile_string_def ( ini_profile , section , " ssl_ja3_table " , ja3_table_name , sizeof ( ja3_table_name ) , " PXY_SSL_FINGERPRINT " ) ;
mgr - > svc_cache = ssl_service_cache_create ( mgr - > svc_cache_slots , mgr - > svc_expire_seconds ,
2019-06-10 18:39:01 +08:00
mgr - > svc_fail_as_pinning_cnt ,
mgr - > svc_fail_as_proto_err_cnt ,
2020-12-25 21:52:14 +06:00
mgr - > svc_cnt_time_window , ja3_table_name ) ;
if ( mgr - > svc_cache = = NULL )
{
TFE_LOG_ERROR ( logger , " Failed to create service cache " ) ;
goto error_out ;
}
2019-09-16 16:40:31 +08:00
2020-12-25 21:52:14 +06:00
mgr - > key_keeper = key_keeper ;
2019-06-14 23:43:03 +08:00
MESA_load_profile_uint_def ( ini_profile , section , " trusted_cert_load_local " ,
& ( mgr - > trusted_cert_load_local ) , 1 ) ;
2018-11-12 13:58:01 +08:00
MESA_load_profile_uint_def ( ini_profile , section , " check_cert_crl " , & ( mgr - > cert_verify_param . check_crl ) , 0 ) ;
2019-06-14 23:43:03 +08:00
if ( mgr - > trusted_cert_load_local ) //Other wise, use policy defined trusted CA file.
{
MESA_load_profile_string_def ( ini_profile , section , " trusted_cert_file " , mgr - > trusted_cert_file , sizeof ( mgr - > trusted_cert_file ) ,
" /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem " ) ;
2019-09-05 11:37:37 +08:00
2019-06-14 23:43:03 +08:00
MESA_load_profile_string_def ( ini_profile , section , " trusted_cert_dir " , mgr - > trusted_cert_dir , sizeof ( mgr - > trusted_cert_dir ) ,
" ./resource/tfe/trusted_storage " ) ;
2019-09-05 11:37:37 +08:00
}
2018-11-12 13:58:01 +08:00
mgr - > trust_CA_store = ssl_trusted_cert_storage_create ( mgr - > trusted_cert_file , mgr - > trusted_cert_dir , & ( mgr - > cert_verify_param ) ) ;
2018-08-27 21:10:45 +08:00
if ( mgr - > trust_CA_store = = NULL )
2018-08-26 18:26:24 +08:00
{
2018-08-27 21:10:45 +08:00
TFE_LOG_ERROR ( logger , " Failed at creating X509_STORE " ) ;
2018-08-26 18:26:24 +08:00
goto error_out ;
2018-08-27 21:10:45 +08:00
}
2018-08-26 14:30:26 +08:00
memcpy ( mgr - > ssl_session_context , " mesa-tfe " , sizeof ( mgr - > ssl_session_context ) ) ;
2018-10-18 12:13:41 +08:00
MESA_load_profile_uint_def ( ini_profile , section , " log_master_key " , & ( mgr - > log_master_key ) , 0 ) ;
MESA_load_profile_string_def ( ini_profile , section , " key_log_file " , mgr - > master_key_file , sizeof ( mgr - > master_key_file ) ,
" ./sslkeylog.log " ) ;
if ( mgr - > log_master_key )
{
mgr - > fp_master_key = fopen ( mgr - > master_key_file , " a " ) ;
if ( mgr - > fp_master_key = = NULL )
{
TFE_LOG_ERROR ( logger , " Failed at open master key log file %s " , mgr - > master_key_file ) ;
mgr - > log_master_key = 0 ;
}
}
2019-09-05 11:37:37 +08:00
2018-10-17 20:21:21 +08:00
mgr - > fs_handle = tfe_proxy_get_fs_handle ( ) ;
2018-10-05 13:31:10 +08:00
ssl_stat_init ( mgr ) ;
2018-08-24 19:22:43 +08:00
return mgr ;
2018-08-26 14:30:26 +08:00
2018-08-24 19:22:43 +08:00
error_out :
ssl_manager_destroy ( mgr ) ;
return NULL ;
2018-08-26 18:26:24 +08:00
}
2019-05-19 17:45:16 +08:00
void ssl_manager_set_new_upstream_cb ( struct ssl_mgr * mgr , ssl_stream_new_hook * new_upstream_cb , void * u_para )
{
mgr - > on_new_upstream_cb = new_upstream_cb ;
mgr - > upstream_cb_param = u_para ;
return ;
}
2018-08-27 21:10:45 +08:00
void peek_client_hello_ctx_free ( struct peek_client_hello_ctx * _ctx )
2018-08-21 16:11:50 +08:00
{
event_free ( _ctx - > ev ) ;
2018-08-27 21:10:45 +08:00
_ctx - > ev = NULL ;
2018-09-14 18:43:28 +08:00
if ( _ctx - > chello ! = NULL )
{
ssl_chello_free ( _ctx - > chello ) ;
_ctx - > chello = NULL ;
}
2018-08-21 16:11:50 +08:00
free ( _ctx ) ;
}
2018-08-26 14:30:26 +08:00
2018-09-10 16:40:25 +08:00
void peek_client_hello_ctx_free_cb ( void * p )
2018-08-21 19:01:10 +08:00
{
2018-09-10 16:40:25 +08:00
struct peek_client_hello_ctx * _ctx = ( struct peek_client_hello_ctx * ) p ;
2018-08-27 21:10:45 +08:00
return peek_client_hello_ctx_free ( _ctx ) ;
2018-08-21 19:01:10 +08:00
}
2018-08-21 16:11:50 +08:00
2018-08-21 19:01:10 +08:00
static void peek_client_hello_cb ( evutil_socket_t fd , short what , void * arg )
2018-08-21 16:11:50 +08:00
{
2018-08-27 21:10:45 +08:00
struct promise * promise = ( struct promise * ) arg ;
2018-08-26 18:26:24 +08:00
//use promise_get_ctx instead of promise_dettach_ctx for try more times.
2018-08-27 21:10:45 +08:00
struct peek_client_hello_ctx * ctx = ( struct peek_client_hello_ctx * ) promise_get_ctx ( promise ) ;
2018-09-14 18:43:28 +08:00
enum chello_parse_result chello_status = CHELLO_PARSE_INVALID_FORMAT ;
2019-09-05 11:37:37 +08:00
struct ssl_chello * chello = NULL ;
2018-08-27 21:10:45 +08:00
const char * reason = NULL ;
2018-09-14 18:43:28 +08:00
unsigned char buf [ 2048 ] ;
2018-08-27 21:10:45 +08:00
ssize_t n = 0 ;
2018-08-26 14:30:26 +08:00
2018-08-27 21:10:45 +08:00
n = recv ( fd , buf , sizeof ( buf ) , MSG_PEEK ) ;
if ( n = = - 1 )
{
2019-07-18 19:56:50 +08:00
char * addr_string = tfe_string_addr_create_by_fd ( fd , CONN_DIR_DOWNSTREAM ) ;
TFE_LOG_ERROR ( ctx - > logger , " Error peeking on fd, aborting connection, addr_string is %s, errno is %d, errmsg is %s \n " , addr_string , errno , strerror ( errno ) ) ;
2020-07-30 15:57:34 +08:00
/* after log, reset errno */
errno = 0 ;
2019-07-18 19:56:50 +08:00
free ( addr_string ) ;
2018-08-21 19:01:10 +08:00
goto failed ;
2018-08-21 16:11:50 +08:00
}
2018-08-26 14:30:26 +08:00
2018-08-27 21:10:45 +08:00
if ( n = = 0 )
{
2018-08-21 19:01:10 +08:00
goto failed ;
2018-08-21 16:11:50 +08:00
}
2018-08-26 14:30:26 +08:00
2019-05-25 15:54:28 +08:00
chello = ssl_chello_parse ( buf , n , & chello_status ) ;
2018-09-14 18:43:28 +08:00
switch ( chello_status )
2018-08-27 21:10:45 +08:00
{
2018-09-14 18:43:28 +08:00
case CHELLO_PARSE_SUCCESS :
{
2021-11-02 22:27:56 +08:00
if ( is_ssl_debug ( ) )
2020-08-24 17:52:55 +08:00
{
char * addr = tfe_string_addr_create_by_fd ( fd , CONN_DIR_DOWNSTREAM ) ;
struct ssl_ja3 * fingerprint = ssl_ja3_generate_fingerprint ( buf , n ) ;
TFE_LOG_INFO ( ctx - > logger , " ja3:%s, hash:%s addr:%s \n " , fingerprint ? fingerprint - > ja3 : " null " , fingerprint ? fingerprint - > ja3_hash : " null " , addr ) ;
ssl_ja3_free ( fingerprint ) ;
free ( addr ) ;
}
promise_dettach_ctx ( promise ) ;
2018-09-14 18:43:28 +08:00
ctx - > chello = chello ;
promise_success ( promise , ctx ) ;
peek_client_hello_ctx_free ( ctx ) ;
break ;
}
2019-05-21 17:15:05 +08:00
case CHELLO_PARSE_NOT_ENOUGH_BUFF :
2018-08-27 21:10:45 +08:00
{
2018-09-14 18:43:28 +08:00
ssl_chello_free ( chello ) ;
chello = NULL ;
if ( ctx - > sni_peek_retries + + > MAX_NET_RETRIES )
{
TFE_LOG_ERROR ( ctx - > logger , " Peek failed due to too many retries \n " ) ;
reason = " too many peek retries " ;
goto failed ;
}
2019-09-05 11:37:37 +08:00
2018-09-14 18:43:28 +08:00
/* ssl_tls_clienthello_parse indicates that we
* should retry later when we have more data , and we
* haven ' t reached the maximum retry count yet .
* Reschedule this event as timeout - only event in
* order to prevent busy looping over the read event .
* Because we only peeked at the pending bytes and
* never actually read them , fd is still ready for
* reading now . We use 25 * 0.2 s = 5 s timeout . */
struct timeval retry_delay = { 0 , 100 } ;
2019-09-05 11:37:37 +08:00
event_del ( ctx - > ev ) ;
2018-09-14 18:43:28 +08:00
event_free ( ctx - > ev ) ;
ctx - > ev = event_new ( ctx - > evbase , fd , 0 , peek_client_hello_cb , promise ) ;
assert ( ctx - > ev ! = NULL ) ;
event_add ( ctx - > ev , & retry_delay ) ;
break ;
}
case CHELLO_PARSE_INVALID_FORMAT :
{
ssl_chello_free ( chello ) ;
chello = NULL ;
2018-08-27 21:10:45 +08:00
TFE_LOG_ERROR ( ctx - > logger ,
" Peeking did not yield a (truncated) ClientHello message, aborting connection \n " ) ;
reason = " see no client hello " ;
2018-08-23 19:46:38 +08:00
goto failed ;
2018-09-14 18:43:28 +08:00
break ;
2018-08-26 14:30:26 +08:00
}
2018-09-14 18:43:28 +08:00
default :
assert ( 0 ) ;
2018-08-21 16:11:50 +08:00
}
return ;
2018-08-26 14:30:26 +08:00
2018-08-21 19:01:10 +08:00
failed :
promise_dettach_ctx ( promise ) ;
2018-08-26 14:30:26 +08:00
promise_failed ( promise , FUTURE_ERROR_EXCEPTION , reason ) ;
2018-08-23 19:46:38 +08:00
peek_client_hello_ctx_free ( ctx ) ;
2018-08-21 16:11:50 +08:00
return ;
}
2019-05-25 15:54:28 +08:00
static void ssl_async_peek_client_hello ( struct future * f , evutil_socket_t fd , struct event_base * evbase ,
2018-08-26 14:30:26 +08:00
void * logger )
2018-08-21 16:11:50 +08:00
{
2018-11-23 20:15:01 +08:00
struct promise * p = future_to_promise ( f ) ;
2018-08-26 14:30:26 +08:00
struct peek_client_hello_ctx * ctx = ALLOC ( struct peek_client_hello_ctx , 1 ) ;
2018-08-27 21:10:45 +08:00
ctx - > ev = event_new ( evbase , fd , EV_READ , peek_client_hello_cb , p ) ;
2019-05-21 17:15:05 +08:00
ctx - > evbase = evbase ;
2018-08-27 21:10:45 +08:00
ctx - > logger = logger ;
2018-09-10 16:40:25 +08:00
promise_set_ctx ( p , ( void * ) ctx , peek_client_hello_ctx_free_cb ) ;
2018-11-14 16:01:48 +08:00
event_add ( ctx - > ev , NULL ) ;
2018-08-21 16:11:50 +08:00
return ;
}
2019-05-16 20:33:42 +08:00
int ossl_client_cert_cb ( SSL * ssl , X509 * * x509 , EVP_PKEY * * pkey )
{
struct ssl_stream * s_upstream = NULL ;
s_upstream = ( struct ssl_stream * ) SSL_get_ex_data ( ssl , SSL_EX_DATA_IDX_SSLSTREAM ) ;
s_upstream - > up_parts . svc_status . is_mutual_auth = 1 ;
2020-08-24 17:52:55 +08:00
ssl_service_cache_write ( s_upstream - > mgr - > svc_cache , s_upstream - > up_parts . client_hello , s_upstream - > tcp_stream , & s_upstream - > up_parts . svc_status ) ;
2019-05-16 20:33:42 +08:00
return 0 ;
}
2018-08-26 14:30:26 +08:00
2018-08-23 19:46:38 +08:00
/*
* Create new SSL context for outgoing connections to the original destination .
* If hostname sni is provided , use it for Server Name Indication .
*/
2019-08-28 14:17:21 +08:00
static int upstream_ossl_init ( struct ssl_stream * s_stream )
2018-08-21 16:11:50 +08:00
{
2018-08-27 21:10:45 +08:00
SSL_CTX * sslctx = NULL ;
SSL * ssl = NULL ;
SSL_SESSION * sess = NULL ;
2019-05-24 14:20:44 +08:00
struct ssl_mgr * mgr = s_stream - > mgr ;
2019-05-14 21:02:06 +08:00
struct ssl_chello * chello = s_stream - > up_parts . client_hello ;
2018-08-27 21:10:45 +08:00
sslctx = SSL_CTX_new ( mgr - > sslmethod ( ) ) ;
2019-08-28 14:17:21 +08:00
if ( sslctx = = NULL )
{
2019-08-28 19:17:00 +08:00
TFE_LOG_ERROR ( mgr - > logger , " ssl ctx new failed. " ) ;
2019-08-28 14:17:21 +08:00
return - 1 ;
}
2018-08-24 10:55:47 +08:00
sslctx_set_opts ( sslctx , mgr ) ;
2018-09-14 18:43:28 +08:00
int ret = 0 ;
2019-05-25 15:54:28 +08:00
char common_cipher [ TFE_STRING_MAX ] = { 0 } , tls13_cipher [ TFE_STRING_MAX ] = { 0 } ;
if ( chello - > cipher_suites )
{
ssl_cipher_suites_to_name ( chello - > cipher_suites , chello - > cipher_suites_len ,
common_cipher , sizeof ( common_cipher ) , tls13_cipher , sizeof ( tls13_cipher ) ) ;
}
if ( strlen ( common_cipher ) > 0 )
2018-09-14 18:43:28 +08:00
{
//SSL_CTX_set_cipher_list() and SSL_set_cipher_list() return 1 if any cipher could be selected and 0 on complete failure.
2019-05-25 15:54:28 +08:00
ret = SSL_CTX_set_cipher_list ( sslctx , common_cipher ) ;
2018-09-14 18:43:28 +08:00
if ( ret = = 0 )
{
2019-08-28 19:17:00 +08:00
TFE_LOG_ERROR ( mgr - > logger , " ssl ctx set cipher list %s failed. " , common_cipher ) ;
2018-09-14 18:43:28 +08:00
SSL_CTX_set_cipher_list ( sslctx , mgr - > default_ciphers ) ;
}
}
else
{
ret = SSL_CTX_set_cipher_list ( sslctx , mgr - > default_ciphers ) ;
}
2019-05-25 15:54:28 +08:00
if ( strlen ( tls13_cipher ) > 0 & & s_stream - > ssl_max_version = = TLS1_3_VERSION )
{
2019-05-30 12:34:42 +08:00
//SSL_CTX_set_ciphersuites(sslctx, tls13_cipher);
2019-02-19 15:11:15 +06:00
2019-05-25 15:54:28 +08:00
}
2019-08-28 14:17:21 +08:00
if ( SSL_CTX_set_min_proto_version ( sslctx , s_stream - > ssl_min_version ) = = 0 )
2018-08-27 21:10:45 +08:00
{
2019-02-19 15:11:15 +06:00
SSL_CTX_free ( sslctx ) ;
2019-08-28 19:17:00 +08:00
TFE_LOG_ERROR ( mgr - > logger , " ssl set min proto version failed %d. " , s_stream - > ssl_min_version ) ;
2019-08-28 14:17:21 +08:00
return - 1 ;
}
if ( SSL_CTX_set_max_proto_version ( sslctx , s_stream - > ssl_max_version ) = = 0 )
{
SSL_CTX_free ( sslctx ) ;
2019-08-28 19:17:00 +08:00
TFE_LOG_ERROR ( mgr - > logger , " ssl set max proto version failed %d. " , s_stream - > ssl_max_version ) ;
2019-08-28 14:17:21 +08:00
return - 1 ;
2018-08-23 19:46:38 +08:00
}
2019-09-05 11:37:37 +08:00
2018-08-23 19:46:38 +08:00
SSL_CTX_set_verify ( sslctx , SSL_VERIFY_NONE , NULL ) ;
2019-05-16 20:33:42 +08:00
SSL_CTX_set_client_cert_cb ( sslctx , ossl_client_cert_cb ) ;
2019-09-05 11:37:37 +08:00
2019-05-30 12:34:42 +08:00
if ( mgr - > no_sesscache )
{
SSL_CTX_set_session_cache_mode ( sslctx , SSL_SESS_CACHE_OFF ) ;
}
else
{
SSL_CTX_set_session_cache_mode ( sslctx , SSL_SESS_CACHE_NO_INTERNAL ) ;
/* session resuming based on remote endpoint address and port */
sess = up_session_get ( mgr - > up_sess_cache ,
2019-09-05 11:37:37 +08:00
( struct sockaddr * ) & ( s_stream - > peer_addr ) , s_stream - > peer_addrlen , chello - > sni ,
2019-05-30 12:34:42 +08:00
s_stream - > ssl_min_version , s_stream - > ssl_max_version ) ;
if ( sess )
{
ret = SSL_CTX_add_session ( sslctx , sess ) ; /* increments sess refcount */
assert ( ret = = 1 ) ;
SSL_SESSION_free ( sess ) ;
}
}
2018-08-27 21:10:45 +08:00
ssl = SSL_new ( sslctx ) ;
2019-02-19 15:11:15 +06:00
SSL_CTX_free ( sslctx ) ; /* SSL_new() increments refcount */
2018-08-27 21:10:45 +08:00
if ( ! ssl )
{
2019-08-28 19:17:00 +08:00
TFE_LOG_ERROR ( mgr - > logger , " ssl new failed. " ) ;
2019-08-28 14:17:21 +08:00
return - 1 ;
2018-08-23 19:46:38 +08:00
}
2019-05-16 20:33:42 +08:00
SSL_set_ex_data ( ssl , SSL_EX_DATA_IDX_SSLSTREAM , s_stream ) ;
2018-08-26 14:30:26 +08:00
2018-08-27 21:10:45 +08:00
if ( chello - > sni )
{
SSL_set_tlsext_host_name ( ssl , chello - > sni ) ;
2018-08-23 19:46:38 +08:00
}
2019-05-27 14:17:52 +08:00
if ( chello - > alpn & & s_stream - > up_parts . apln_enabled )
2018-10-29 14:45:07 +08:00
{
2018-10-29 15:17:11 +08:00
ret = SSL_set_alpn_protos ( ssl , ( unsigned char * ) chello - > alpn , strlen ( chello - > alpn ) ) ;
2018-10-29 17:30:22 +08:00
assert ( ret = = 0 ) ;
2018-10-29 14:45:07 +08:00
}
2018-08-23 19:46:38 +08:00
/* lower memory footprint for idle connections */
SSL_set_mode ( ssl , SSL_get_mode ( ssl ) | SSL_MODE_RELEASE_BUFFERS ) ;
2019-05-24 14:20:44 +08:00
s_stream - > ssl = ssl ;
2019-08-28 14:17:21 +08:00
return 0 ;
2018-08-23 19:46:38 +08:00
}
2018-10-18 12:13:41 +08:00
void ssl_connect_server_ctx_free ( struct ssl_connect_server_ctx * ctx )
2018-08-21 16:11:50 +08:00
{
2018-08-27 21:10:45 +08:00
if ( ctx - > s_stream ! = NULL )
{
2018-08-26 14:30:26 +08:00
ssl_stream_free ( ctx - > s_stream ) ;
2018-08-23 19:46:38 +08:00
}
2018-08-26 14:30:26 +08:00
2018-08-27 21:10:45 +08:00
if ( ctx - > bev ! = NULL )
{
2018-08-26 14:30:26 +08:00
bufferevent_free ( ctx - > bev ) ;
2018-08-27 21:10:45 +08:00
ctx - > bev = NULL ;
2018-08-26 14:30:26 +08:00
}
2018-08-27 21:10:45 +08:00
if ( ctx - > f_peek_chello ! = NULL )
{
2018-08-26 14:30:26 +08:00
future_destroy ( ctx - > f_peek_chello ) ;
2018-08-27 21:10:45 +08:00
ctx - > f_peek_chello = NULL ;
2018-08-23 19:46:38 +08:00
}
2018-08-26 14:30:26 +08:00
2018-08-23 19:46:38 +08:00
free ( ctx ) ;
return ;
}
2018-08-26 14:30:26 +08:00
2018-10-18 12:13:41 +08:00
void wrap_ssl_connect_server_ctx_free ( void * p )
2018-08-27 21:10:45 +08:00
{
2018-10-18 12:13:41 +08:00
struct ssl_connect_server_ctx * ctx = ( struct ssl_connect_server_ctx * ) p ;
ssl_connect_server_ctx_free ( ctx ) ;
2018-08-27 21:10:45 +08:00
}
2019-05-17 21:35:20 +08:00
enum ssl_stream_action ssl_upstream_create_result_release_action ( future_result_t * result )
{
struct ssl_connect_server_ctx * ctx = ( struct ssl_connect_server_ctx * ) result ;
return ctx - > s_stream - > up_parts . action ;
}
evutil_socket_t ssl_upstream_create_result_release_fd ( future_result_t * result )
{
struct ssl_connect_server_ctx * ctx = ( struct ssl_connect_server_ctx * ) result ;
return ctx - > fd_upstream ;
}
2018-08-26 14:30:26 +08:00
2018-08-28 15:25:09 +08:00
struct ssl_stream * ssl_upstream_create_result_release_stream ( future_result_t * result )
2018-08-27 21:10:45 +08:00
{
2018-10-18 12:13:41 +08:00
struct ssl_connect_server_ctx * ctx = ( struct ssl_connect_server_ctx * ) result ;
2018-08-26 14:30:26 +08:00
struct ssl_stream * ret = ctx - > s_stream ;
2018-08-27 21:10:45 +08:00
ctx - > s_stream = NULL ; //giveup ownership
2018-08-23 19:46:38 +08:00
return ret ;
}
2018-08-26 14:30:26 +08:00
2018-08-28 15:25:09 +08:00
struct bufferevent * ssl_upstream_create_result_release_bev ( future_result_t * result )
2018-08-27 21:10:45 +08:00
{
2018-10-18 12:13:41 +08:00
struct ssl_connect_server_ctx * ctx = ( struct ssl_connect_server_ctx * ) result ;
2018-08-26 14:30:26 +08:00
struct bufferevent * ret = ctx - > bev ;
2018-08-27 21:10:45 +08:00
ctx - > bev = NULL ; //giveup ownership
2018-08-23 19:46:38 +08:00
return ret ;
2018-08-21 16:11:50 +08:00
}
2019-02-18 18:25:19 +06:00
const char * ssl_stream_dump_info ( struct ssl_stream * stream , char * buffer , size_t sz )
{
snprintf ( buffer , sz , " %s:%s " , SSL_get_version ( stream - > ssl ) ,
2019-05-14 19:58:23 +08:00
stream - > dir = = CONN_DIR_UPSTREAM ? stream - > up_parts . client_hello - > sni : NULL ) ;
2019-02-18 18:25:19 +06:00
return buffer ;
}
2021-01-11 23:06:19 +06:00
void ssl_stream_set_cmsg_string ( struct ssl_stream * stream , enum tfe_cmsg_tlv_type type , const char * value_str )
2019-06-10 21:27:27 +08:00
{
struct tfe_cmsg * cmsg = tfe_stream_get0_cmsg ( stream - > tcp_stream ) ;
2019-09-02 11:39:19 +08:00
UNUSED int ret = tfe_cmsg_set ( cmsg , type , ( const unsigned char * ) value_str , ( uint16_t ) strlen ( value_str ) ) ;
2019-06-10 21:27:27 +08:00
assert ( ret = = 0 ) ;
return ;
}
2023-04-23 16:55:30 +08:00
static void ssl_stream_set_cmsg_uint8 ( struct ssl_stream * stream , enum tfe_cmsg_tlv_type type , uint8_t value_int )
{
struct tfe_cmsg * cmsg = tfe_stream_get0_cmsg ( stream - > tcp_stream ) ;
UNUSED int ret = tfe_cmsg_set ( cmsg , type , ( const unsigned char * ) & value_int , ( uint16_t ) sizeof ( value_int ) ) ;
assert ( ret = = 0 ) ;
return ;
}
2019-06-10 21:27:27 +08:00
static void ssl_stream_set_cmsg_integer ( struct ssl_stream * stream , enum tfe_cmsg_tlv_type type , uint64_t value_int )
{
struct tfe_cmsg * cmsg = tfe_stream_get0_cmsg ( stream - > tcp_stream ) ;
2019-09-02 11:39:19 +08:00
UNUSED int ret = tfe_cmsg_set ( cmsg , type , ( const unsigned char * ) & value_int , ( uint16_t ) sizeof ( value_int ) ) ;
2019-06-10 21:27:27 +08:00
assert ( ret = = 0 ) ;
return ;
}
2019-05-16 20:33:42 +08:00
unsigned long ssl_stream_log_error ( struct bufferevent * bev , enum tfe_conn_dir dir , struct ssl_mgr * mgr )
2018-08-31 14:32:34 +08:00
{
2019-05-16 20:33:42 +08:00
unsigned long sslerr = 0 , ret_sslerr = 0 ;
2018-10-04 18:34:18 +08:00
int fd = bufferevent_getfd ( bev ) ;
2018-10-21 20:34:39 +08:00
char * addr_string = tfe_string_addr_create_by_fd ( fd , dir ) ;
2018-12-05 19:58:34 +08:00
void * logger = mgr - > logger ;
int fs_id = - 1 ;
2018-10-21 20:34:39 +08:00
2018-08-31 14:32:34 +08:00
/* Can happen for socket errs, ssl errs;
* may happen for unclean ssl socket shutdowns . */
sslerr = bufferevent_get_openssl_error ( bev ) ;
2019-05-25 15:54:28 +08:00
ret_sslerr = ERR_GET_REASON ( sslerr ) ;
switch ( ret_sslerr )
2018-12-05 19:58:34 +08:00
{
case SSL_R_INAPPROPRIATE_FALLBACK :
if ( dir = = CONN_DIR_DOWNSTREAM ) fs_id = SSL_DOWN_ERR_INAPPROPRIATE_FALLBACK ;
break ;
case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN :
if ( dir = = CONN_DIR_DOWNSTREAM ) fs_id = SSL_DOWN_ERR_NO_CERT ;
break ;
2019-05-25 15:54:28 +08:00
case SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM :
2018-12-05 19:58:34 +08:00
case SSL_R_UNSUPPORTED_PROTOCOL :
2019-05-25 15:54:28 +08:00
case SSL_R_UNSUPPORTED_SSL_VERSION :
case SSL_R_UNSUPPORTED_STATUS_TYPE :
case SSL_R_NO_PROTOCOLS_AVAILABLE :
2018-12-05 19:58:34 +08:00
if ( dir = = CONN_DIR_UPSTREAM ) fs_id = SSL_UP_ERR_UNSUPPORT_PROTO ;
case SSL_R_NO_CIPHERS_AVAILABLE :
if ( dir = = CONN_DIR_UPSTREAM ) fs_id = SSL_UP_ERR_NO_CIPHER ;
break ;
default :
fs_id = - 1 ;
}
if ( fs_id > = 0 )
{
2019-09-05 11:37:37 +08:00
mgr - > stat_val [ fs_id ] + + ;
2018-12-05 19:58:34 +08:00
}
2018-08-31 14:32:34 +08:00
if ( ! errno & & ! sslerr )
{
/* We have disabled notification for unclean shutdowns
* so this should not happen ; log a warning . */
TFE_LOG_ERROR ( logger , " Warning: Spurious error from "
2019-05-16 20:33:42 +08:00
" bufferevent (errno=0, sslerr=0) \n " ) ;
2018-08-31 14:32:34 +08:00
}
else if ( ERR_GET_REASON ( sslerr ) = =
SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE )
{
/* these can happen due to client cert auth,
* only log error if debugging is activated */
2018-10-04 18:34:18 +08:00
TFE_LOG_ERROR ( logger , " Handshake Error from bufferevent of ssl %s %s: "
" %i:%s %lu:%i:%s:%i:%s:%i:%s " ,
tfe_stream_conn_dir_to_str ( dir ) ,
addr_string ,
2018-08-31 14:32:34 +08:00
errno ,
errno ? strerror ( errno ) : " - " ,
sslerr ,
ERR_GET_REASON ( sslerr ) ,
sslerr ?
ERR_reason_error_string ( sslerr ) : " - " ,
ERR_GET_LIB ( sslerr ) ,
sslerr ?
ERR_lib_error_string ( sslerr ) : " - " ,
ERR_GET_FUNC ( sslerr ) ,
sslerr ?
ERR_func_error_string ( sslerr ) : " - " ) ;
2020-07-30 15:57:34 +08:00
/* after log, reset errno */
errno = 0 ;
2018-08-31 14:32:34 +08:00
while ( ( sslerr = bufferevent_get_openssl_error ( bev ) ) )
{
TFE_LOG_ERROR ( logger , " Additional SSL error: "
2018-10-04 18:34:18 +08:00
" %lu:%i:%s:%i:%s:%i:%s " ,
2018-08-31 14:32:34 +08:00
sslerr ,
ERR_GET_REASON ( sslerr ) ,
ERR_reason_error_string ( sslerr ) ,
ERR_GET_LIB ( sslerr ) ,
ERR_lib_error_string ( sslerr ) ,
ERR_GET_FUNC ( sslerr ) ,
ERR_func_error_string ( sslerr ) ) ;
}
}
else
{
/* real errors */
2018-10-04 18:34:18 +08:00
TFE_LOG_ERROR ( logger , " Error from bufferevent of ssl %s %s: "
" %i:%s %lu:%i:%s:%i:%s:%i:%s " ,
tfe_stream_conn_dir_to_str ( dir ) ,
addr_string ,
2018-08-31 14:32:34 +08:00
errno ,
errno ? strerror ( errno ) : " - " ,
sslerr ,
ERR_GET_REASON ( sslerr ) ,
sslerr ?
ERR_reason_error_string ( sslerr ) : " - " ,
ERR_GET_LIB ( sslerr ) ,
sslerr ?
ERR_lib_error_string ( sslerr ) : " - " ,
ERR_GET_FUNC ( sslerr ) ,
sslerr ?
ERR_func_error_string ( sslerr ) : " - " ) ;
2020-07-30 15:57:34 +08:00
/* after log, reset errno */
errno = 0 ;
2018-08-31 14:32:34 +08:00
while ( ( sslerr = bufferevent_get_openssl_error ( bev ) ) )
{
TFE_LOG_ERROR ( logger , " Additional SSL error: "
" %lu:%i:%s:%i:%s:%i:%s \n " ,
sslerr ,
ERR_GET_REASON ( sslerr ) ,
ERR_reason_error_string ( sslerr ) ,
ERR_GET_LIB ( sslerr ) ,
ERR_lib_error_string ( sslerr ) ,
ERR_GET_FUNC ( sslerr ) ,
ERR_func_error_string ( sslerr ) ) ;
}
}
2018-10-04 18:34:18 +08:00
free ( addr_string ) ;
2019-05-16 20:33:42 +08:00
return ret_sslerr ;
2018-08-31 14:32:34 +08:00
}
2019-06-10 21:27:27 +08:00
void ssl_stream_process_error ( struct ssl_stream * s_stream , unsigned long sslerr , struct ssl_mgr * mgr )
2019-06-01 20:28:07 +08:00
{
2019-06-10 21:27:27 +08:00
struct ssl_upstream_parts * s_upstream = NULL ;
assert ( sslerr ) ;
switch ( s_stream - > dir )
{
case CONN_DIR_DOWNSTREAM :
s_upstream = & ( s_stream - > peer - > up_parts ) ;
2019-06-28 12:05:47 +06:00
if ( ( sslerr = = SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN | |
sslerr = = SSL_R_SSLV3_ALERT_BAD_CERTIFICATE | |
sslerr = = SSL_R_TLSV1_ALERT_UNKNOWN_CA | |
sslerr = = SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE | |
2019-06-28 12:19:32 +06:00
sslerr = = SSL_R_UNKNOWN_CERTIFICATE_TYPE )
2019-06-28 12:05:47 +06:00
& & s_upstream - > is_server_cert_verify_passed
& & s_upstream - > verify_result . is_hostmatched )
2019-06-10 21:27:27 +08:00
{
2019-07-26 12:28:17 +06:00
s_upstream - > svc_status . cli_pinning_status = PINNING_ST_PINNING ;
2020-11-04 15:43:24 +08:00
// This feature is also displayed when the root certificate is not installed.
// Here no longer set the pinning state to cmsg, but use the pinng state
// corrected by app_is_not_pinnig in the peek_chello_on_succ function
// ssl_stream_set_cmsg_integer(s_stream, TFE_CMSG_SSL_PINNING_STATE, PINNING_ST_PINNING);
2020-08-24 17:52:55 +08:00
ssl_service_cache_write ( mgr - > svc_cache , s_upstream - > client_hello , s_stream - > tcp_stream , & s_upstream - > svc_status ) ;
2019-06-10 21:27:27 +08:00
}
else if ( sslerr > 0 & & sslerr ! = SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN )
{
s_upstream - > svc_status . has_protocol_errors = 1 ;
2020-08-24 17:52:55 +08:00
ssl_service_cache_write ( mgr - > svc_cache , s_upstream - > client_hello , s_stream - > tcp_stream , & s_upstream - > svc_status ) ;
2019-06-10 21:27:27 +08:00
}
break ;
case CONN_DIR_UPSTREAM :
s_upstream = & ( s_stream - > up_parts ) ;
2019-09-05 11:37:37 +08:00
s_upstream - > svc_status . has_protocol_errors = 1 ;
2020-08-24 17:52:55 +08:00
ssl_service_cache_write ( mgr - > svc_cache , s_stream - > up_parts . client_hello , s_stream - > tcp_stream , & ( s_stream - > up_parts . svc_status ) ) ;
2019-06-10 21:27:27 +08:00
break ;
default :
assert ( 0 ) ;
}
2019-06-01 20:28:07 +08:00
return ;
}
2019-06-14 22:49:41 +08:00
void ssl_stream_process_zero_eof ( struct ssl_stream * s_stream , struct ssl_mgr * mgr )
{
struct ssl_upstream_parts * s_upstream = NULL ;
if ( s_stream - > dir = = CONN_DIR_UPSTREAM )
{
return ;
}
assert ( mgr = = s_stream - > mgr ) ;
s_upstream = & s_stream - > peer - > up_parts ;
if ( s_upstream - > verify_result . is_hostmatched & & s_upstream - > is_server_cert_verify_passed )
{
2020-11-04 15:43:24 +08:00
const char * sni = s_upstream - > client_hello ? ( s_upstream - > client_hello - > sni ? s_upstream - > client_hello - > sni : " null " ) : " null " ;
2021-12-20 16:35:34 +08:00
TFE_LOG_DEBUG ( mgr - > logger , " sni:%s cert verify passed and hit zero eof, set protocol errors " , sni ) ;
s_upstream - > svc_status . has_protocol_errors = 1 ;
2020-08-24 17:52:55 +08:00
ssl_service_cache_write ( mgr - > svc_cache , s_stream - > peer - > up_parts . client_hello , s_stream - > tcp_stream , & ( s_stream - > peer - > up_parts . svc_status ) ) ;
2019-06-14 22:49:41 +08:00
}
s_stream - > error = SSL_STREAM_R_CLIENT_CLOSED ;
return ;
}
2019-06-10 21:27:27 +08:00
2018-08-21 16:11:50 +08:00
/*
* Callback for meta events on the up - and downstream connection bufferevents .
* Called when EOF has been reached , a connection has been made , and on errors .
*/
2018-10-18 12:13:41 +08:00
static void ssl_server_connected_eventcb ( struct bufferevent * bev , short events , void * arg )
2018-08-21 16:11:50 +08:00
{
2018-10-18 12:13:41 +08:00
struct promise * p = ( struct promise * ) arg ;
struct ssl_connect_server_ctx * ctx = ( struct ssl_connect_server_ctx * ) promise_dettach_ctx ( p ) ;
2018-08-26 14:30:26 +08:00
struct ssl_stream * s_stream = ctx - > s_stream ;
2019-05-14 19:58:23 +08:00
assert ( s_stream - > dir = = CONN_DIR_UPSTREAM ) ;
struct ssl_upstream_parts * s_upstream = & ( s_stream - > up_parts ) ;
2018-10-08 15:06:01 +08:00
struct ssl_mgr * mgr = s_stream - > mgr ;
2018-08-27 21:10:45 +08:00
SSL_SESSION * ssl_sess = NULL ;
2018-11-02 20:38:06 +08:00
char error_str [ TFE_STRING_MAX ] ;
2019-06-01 20:28:07 +08:00
uint64_t jiffies_ms ;
2019-05-21 11:47:09 +08:00
unsigned long sslerr = 0 ;
2018-08-27 21:10:45 +08:00
if ( events & BEV_EVENT_ERROR )
{
2018-08-31 19:59:22 +08:00
ATOMIC_INC ( & ( ctx - > mgr - > stat_val [ SSL_UP_ERR ] ) ) ;
2019-05-21 11:47:09 +08:00
sslerr = ssl_stream_log_error ( bev , CONN_DIR_UPSTREAM , ctx - > mgr ) ;
if ( sslerr )
{
2019-06-10 21:27:27 +08:00
ssl_stream_process_error ( s_stream , sslerr , mgr ) ;
2019-05-21 11:47:09 +08:00
}
2019-06-01 20:28:07 +08:00
s_stream - > error = SSL_STREAM_R_SERVER_PROTOCOL_ERROR ;
2018-08-26 14:30:26 +08:00
}
2018-08-31 14:32:34 +08:00
else if ( events & BEV_EVENT_EOF )
2019-09-05 11:37:37 +08:00
{
ATOMIC_INC ( & ( ctx - > mgr - > stat_val [ SSL_UP_ERR ] ) ) ;
2019-06-01 20:28:07 +08:00
s_stream - > error = SSL_STREAM_R_SERVER_CLOSED ;
2018-08-31 14:32:34 +08:00
}
else if ( events & BEV_EVENT_TIMEOUT )
{
2019-06-01 20:28:07 +08:00
ATOMIC_INC ( & ( ctx - > mgr - > stat_val [ SSL_UP_ERR ] ) ) ;
s_stream - > error = SSL_STREAM_R_CONNECT_SERVER_TIMEOUT ;
2018-08-31 14:32:34 +08:00
}
else if ( events & BEV_EVENT_CONNECTED )
2019-09-05 11:37:37 +08:00
{
2018-08-31 14:32:34 +08:00
bufferevent_disable ( ctx - > bev , EV_READ | EV_WRITE ) ;
bufferevent_setcb ( ctx - > bev , NULL , NULL , NULL , NULL ) ; //leave a clean bev for on_success
2018-11-21 18:56:04 +08:00
clock_gettime ( CLOCK_MONOTONIC , & ( ctx - > end ) ) ;
jiffies_ms = ( ctx - > end . tv_sec - ctx - > start . tv_sec ) * 1000 + ( ctx - > end . tv_nsec - ctx - > start . tv_nsec ) / 1000000 ;
if ( jiffies_ms > LATENCY_WARNING_THRESHOLD_MS )
{
2023-07-14 19:38:18 +08:00
TFE_LOG_INFO ( mgr - > logger , " Warning: ssl connect server latency %ld ms: addr=%s, sni=%s " ,
2019-09-05 11:37:37 +08:00
jiffies_ms ,
2019-06-21 16:10:26 +08:00
s_stream - > tcp_stream - > str_stream_info ,
s_upstream - > client_hello - > sni ) ;
2018-11-21 18:56:04 +08:00
}
2019-06-01 20:28:07 +08:00
s_stream - > connect_latency_ms = jiffies_ms ;
2019-06-02 18:17:53 +08:00
ssl_stream_set_cmsg_integer ( s_stream , TFE_CMSG_SSL_SERVER_SIDE_LATENCY , jiffies_ms ) ;
2018-10-08 15:06:01 +08:00
if ( ! SSL_session_reused ( s_stream - > ssl ) )
{
2019-01-14 18:23:46 +06:00
if ( mgr - > no_cert_verify )
{
2019-05-24 11:26:41 +08:00
s_upstream - > is_server_cert_verify_passed = 1 ;
2019-01-14 18:23:46 +06:00
}
else
2019-09-05 11:37:37 +08:00
{
2023-04-23 16:55:30 +08:00
s_upstream - > is_server_cert_verify_passed = ! ! ssl_trusted_cert_storage_verify_conn ( s_stream - > mgr - > trust_CA_store ,
2019-05-15 20:09:12 +08:00
s_stream - > ssl , s_stream - > up_parts . client_hello - > sni , & ( s_stream - > up_parts . verify_param ) ,
error_str , sizeof ( error_str ) , & ( s_stream - > up_parts . verify_result ) ) ;
2021-11-20 18:24:28 +03:00
TFE_LOG_DEBUG ( g_default_logger ,
" addr:%s, sni:%s, is_cert_verify_passed:%d, cet_real_untrust:%d, verify_host_fail:%d, verify_issure_fail:%d, verify_self_signed_fail:%d, verify_expiry_date_fail:%d, verify_other_fail:%d, %s " ,
s_stream - > tcp_stream - > str_stream_info ,
s_upstream - > client_hello - > sni ,
s_upstream - > is_server_cert_verify_passed ,
( ( s_upstream - > verify_param . real_untrust & 0xff ) ? 1 : 0 ) ,
( ( s_upstream - > verify_param . real_untrust & 0x01 ) ? 1 : 0 ) ,
( ( s_upstream - > verify_param . real_untrust & 0x02 ) ? 1 : 0 ) ,
( ( s_upstream - > verify_param . real_untrust & 0x04 ) ? 1 : 0 ) ,
( ( s_upstream - > verify_param . real_untrust & 0x08 ) ? 1 : 0 ) ,
( ( s_upstream - > verify_param . real_untrust & 0x10 ) ? 1 : 0 ) ,
( s_upstream - > is_server_cert_verify_passed = = 0 ? error_str : " " ) ) ;
2019-05-24 11:26:41 +08:00
s_upstream - > svc_status . is_ct = s_upstream - > verify_result . is_ct ;
s_upstream - > svc_status . is_ev = s_upstream - > verify_result . is_ev ;
2020-08-24 17:52:55 +08:00
ssl_service_cache_write ( mgr - > svc_cache , s_upstream - > client_hello , s_stream - > tcp_stream , & ( s_upstream - > svc_status ) ) ;
2019-06-01 20:28:07 +08:00
TFE_LOG_DEBUG ( mgr - > logger , " stream:%s sni:%s hostmatch:%d, ct:%d, ev:%d " ,
s_stream - > tcp_stream - > str_stream_info ,
2019-05-15 20:09:12 +08:00
s_upstream - > client_hello - > sni ,
2019-05-24 11:26:41 +08:00
s_upstream - > verify_result . is_hostmatched ,
s_upstream - > verify_result . is_ct ,
s_upstream - > verify_result . is_ev ) ;
if ( ( ! s_upstream - > is_server_cert_verify_passed | | ! s_upstream - > verify_result . is_hostmatched ) & & s_upstream - > block_fake_cert )
2019-05-17 21:35:20 +08:00
{
s_stream - > up_parts . action = SSL_ACTION_SHUTDOWN ;
}
2019-01-14 18:23:46 +06:00
}
2019-05-24 11:26:41 +08:00
if ( s_upstream - > is_server_cert_verify_passed )
2018-10-08 15:06:01 +08:00
{
2019-05-24 11:26:41 +08:00
if ( ! mgr - > no_sesscache & & s_stream - > up_parts . action = = SSL_ACTION_INTERCEPT )
2019-02-18 15:47:29 +06:00
{
//ONLY verified session is cacheable.
//The reference count of the SSL_SESSION is not incremented, so no need to free.
ssl_sess = SSL_get0_session ( s_stream - > ssl ) ;
up_session_set ( mgr - > up_sess_cache , ( struct sockaddr * ) & ( ctx - > addr ) ,
2019-05-17 21:35:20 +08:00
ctx - > addrlen , s_upstream - > client_hello - > sni , SSL_version ( s_stream - > ssl ) , ssl_sess ) ;
2019-02-18 15:47:29 +06:00
}
2018-10-08 15:06:01 +08:00
}
else
{
ATOMIC_INC ( & ( mgr - > stat_val [ SSL_FAKE_CRT ] ) ) ;
2018-10-21 20:34:39 +08:00
char * addr_str = tfe_string_addr_create_by_fd ( ctx - > fd_upstream , CONN_DIR_UPSTREAM ) ;
2019-05-14 19:58:23 +08:00
TFE_LOG_INFO ( mgr - > logger , " Fake Cert %s %s : %s " , addr_str , s_upstream - > client_hello - > sni , error_str ) ;
2018-10-21 20:34:39 +08:00
free ( addr_str ) ;
2018-10-08 15:06:01 +08:00
}
}
else
{
2019-05-14 19:58:23 +08:00
//Do not perform cert verification on reused session.
2019-09-05 11:37:37 +08:00
s_upstream - > is_server_cert_verify_passed = 1 ;
2018-10-08 15:06:01 +08:00
}
2018-10-18 12:13:41 +08:00
if ( mgr - > log_master_key )
{
2021-04-28 18:01:32 +08:00
log_ssl_master_key ( s_stream , CONN_DIR_UPSTREAM , mgr - > fp_master_key ) ;
2018-10-18 12:13:41 +08:00
}
2018-10-29 17:30:22 +08:00
const unsigned char * alpn_data = NULL ;
unsigned int alpn_len = 0 ;
SSL_get0_alpn_selected ( s_stream - > ssl , & alpn_data , & alpn_len ) ;
if ( alpn_len > 0 & & alpn_data ! = NULL )
{
if ( 0 = = memcmp ( alpn_data , SSL_ALPN_HTTP_1_1 + 1 , alpn_len ) )
{
s_stream - > alpn_selected = SSL_ALPN_HTTP_1_1 ;
}
else if ( 0 = = memcmp ( alpn_data , SSL_ALPN_HTTP_2 + 1 , alpn_len ) )
{
s_stream - > alpn_selected = SSL_ALPN_HTTP_2 ;
}
else
{
s_stream - > alpn_selected = NULL ;
}
}
2019-05-18 18:27:13 +08:00
s_stream - > negotiated_version = SSL_version ( s_stream - > ssl ) ;
2019-06-02 18:17:53 +08:00
ssl_stream_set_cmsg_string ( s_stream , TFE_CMSG_SSL_SERVER_SIDE_VERSION , SSL_get_version ( s_stream - > ssl ) ) ;
2023-04-23 16:55:30 +08:00
ssl_stream_set_cmsg_uint8 ( s_stream , TFE_CMSG_SSL_CERT_VERIFY , s_upstream - > is_server_cert_verify_passed ) ;
2018-10-18 12:13:41 +08:00
promise_success ( p , ctx ) ;
2018-08-21 16:11:50 +08:00
}
2019-06-01 20:28:07 +08:00
if ( s_stream - > error )
{
ssl_stream_set_cmsg_string ( s_stream , TFE_CMSG_SSL_ERROR , ssl_stream_get_error_string ( s_stream - > error ) ) ;
2019-06-21 16:10:26 +08:00
snprintf ( error_str , sizeof ( error_str ) , " %s, sni=%s " , ssl_stream_get_error_string ( s_stream - > error ) , s_upstream - > client_hello - > sni ) ;
2019-06-01 20:28:07 +08:00
promise_failed ( p , FUTURE_ERROR_EXCEPTION , error_str ) ;
}
2018-10-18 12:13:41 +08:00
wrap_ssl_connect_server_ctx_free ( ctx ) ;
2018-08-27 21:10:45 +08:00
return ;
2018-08-21 16:11:50 +08:00
}
2018-08-26 14:30:26 +08:00
static void peek_chello_on_succ ( future_result_t * result , void * user )
{
2018-08-27 21:10:45 +08:00
struct promise * p = ( struct promise * ) user ;
2019-05-17 21:35:20 +08:00
struct ssl_connect_server_ctx * ctx = ( struct ssl_connect_server_ctx * ) promise_get_ctx ( p ) ;
2019-06-01 20:28:07 +08:00
struct event_base * evbase = tfe_proxy_get_work_thread_evbase ( ctx - > tcp_stream - > thread_id ) ;
2019-05-17 21:35:20 +08:00
struct ssl_stream * s_stream = NULL ;
struct ssl_chello * chello = ssl_peek_result_release_chello ( result ) ; //chello has been saved in ssl_stream.
2018-08-31 19:59:22 +08:00
if ( chello - > sni = = NULL )
{
ATOMIC_INC ( & ( ctx - > mgr - > stat_val [ SSL_NO_SNI ] ) ) ;
}
2019-05-16 20:33:42 +08:00
int ret = 0 ;
struct ssl_service_status * svc_status = NULL ;
2018-11-21 18:56:04 +08:00
clock_gettime ( CLOCK_MONOTONIC , & ( ctx - > start ) ) ;
2019-06-01 20:28:07 +08:00
s_stream = ssl_stream_new ( ctx - > mgr , ctx - > fd_upstream , CONN_DIR_UPSTREAM , chello , NULL , NULL , ctx - > tcp_stream ) ;
2019-05-17 21:35:20 +08:00
svc_status = & s_stream - > up_parts . svc_status ;
2020-08-24 17:52:55 +08:00
ret = ssl_service_cache_read ( ctx - > mgr - > svc_cache , chello , s_stream - > tcp_stream , svc_status ) ;
2019-05-16 20:33:42 +08:00
if ( ret = = 1 )
{
2020-12-25 21:52:14 +06:00
TFE_LOG_DEBUG ( ctx - > mgr - > logger , " %s %s service status pinning:%d, mauth:%d, err:%d, ct:%d, ev:%d, ja3_pinning_status:%d " ,
2021-04-28 18:01:32 +08:00
s_stream - > tcp_stream - > str_stream_info ,
2019-05-16 20:33:42 +08:00
chello - > sni ,
2019-07-26 12:28:17 +06:00
svc_status - > cli_pinning_status ,
2019-05-16 20:33:42 +08:00
svc_status - > is_mutual_auth ,
2019-05-21 11:47:09 +08:00
svc_status - > has_protocol_errors ,
2019-05-16 20:33:42 +08:00
svc_status - > is_ct ,
2020-08-24 17:52:55 +08:00
svc_status - > is_ev ,
2020-12-25 21:52:14 +06:00
svc_status - > ja3_pinning_status ) ;
2019-05-16 20:33:42 +08:00
}
2020-12-25 21:52:14 +06:00
switch ( svc_status - > ja3_pinning_status )
{
case JA3_PINNING_STATUS_NOT_PINNING :
ctx - > mgr - > svc_cache - > stat . app_not_pinning_cnt + + ;
2023-04-23 16:55:30 +08:00
ssl_stream_set_cmsg_uint8 ( s_stream , TFE_CMSG_SSL_PINNING_STATE , PINNING_ST_NOT_PINNING ) ;
2020-12-25 21:52:14 +06:00
break ;
case JA3_PINNING_STATUS_IS_PINNING :
2023-04-23 16:55:30 +08:00
ssl_stream_set_cmsg_uint8 ( s_stream , TFE_CMSG_SSL_PINNING_STATE , PINNING_ST_PINNING ) ;
2020-12-25 21:52:14 +06:00
break ;
case JA3_PINNING_STATUS_UNKNOWN :
/* fall through */
default :
2023-04-23 16:55:30 +08:00
ssl_stream_set_cmsg_uint8 ( s_stream , TFE_CMSG_SSL_PINNING_STATE , svc_status - > cli_pinning_status ) ;
2020-12-25 21:52:14 +06:00
break ;
}
2019-05-19 17:45:16 +08:00
if ( ctx - > mgr - > on_new_upstream_cb )
{
s_stream - > up_parts . action = ctx - > mgr - > on_new_upstream_cb ( s_stream , ctx - > mgr - > upstream_cb_param ) ;
}
else
{
s_stream - > up_parts . action = SSL_ACTION_INTERCEPT ;
}
2020-05-18 20:32:38 +08:00
if ( ATOMIC_READ ( & certstore_is_unavailable ) > 3 )
{
s_stream - > up_parts . action = SSL_ACTION_PASSTHROUGH ;
2021-12-31 14:06:19 +08:00
ssl_stream_set_cmsg_string ( s_stream , TFE_CMSG_SSL_PASSTHROUGH_REASON , " Certstore Unavailable " ) ;
2020-05-18 20:32:38 +08:00
TFE_LOG_ERROR ( ctx - > mgr - > logger , " CertStore is unavailable, PASSTHROUGH " ) ;
}
2023-05-30 19:25:26 +08:00
ssl_stream_set_cmsg_uint8 ( s_stream , TFE_CMSG_SSL_INTERCEPT_STATE , s_stream - > up_parts . action ) ;
2019-05-17 21:35:20 +08:00
ctx - > s_stream = s_stream ;
if ( s_stream - > up_parts . action = = SSL_ACTION_PASSTHROUGH )
{
2019-05-18 12:39:19 +08:00
promise_dettach_ctx ( p ) ;
2019-05-17 21:35:20 +08:00
promise_success ( p , ctx ) ;
wrap_ssl_connect_server_ctx_free ( ctx ) ;
}
else
{
2019-08-28 14:17:21 +08:00
if ( upstream_ossl_init ( s_stream ) )
{
promise_dettach_ctx ( p ) ;
promise_failed ( p , FUTURE_ERROR_EXCEPTION , " upstream ossl init failed " ) ;
wrap_ssl_connect_server_ctx_free ( ctx ) ;
return ;
}
2019-05-17 21:35:20 +08:00
ctx - > bev = bufferevent_openssl_socket_new ( evbase , ctx - > fd_upstream ,
ctx - > s_stream - > ssl , BUFFEREVENT_SSL_CONNECTING , BEV_OPT_DEFER_CALLBACKS | BEV_OPT_THREADSAFE ) ;
2018-08-27 21:10:45 +08:00
2019-05-17 21:35:20 +08:00
bufferevent_openssl_set_allow_dirty_shutdown ( ctx - > bev , 1 ) ;
bufferevent_setcb ( ctx - > bev , NULL , NULL , ssl_server_connected_eventcb , p ) ;
bufferevent_enable ( ctx - > bev , EV_READ | EV_WRITE ) ; //waiting for connect event only
2018-08-27 21:10:45 +08:00
2019-05-17 21:35:20 +08:00
future_destroy ( ctx - > f_peek_chello ) ;
ctx - > f_peek_chello = NULL ;
}
2018-08-26 14:30:26 +08:00
return ;
}
static void peek_chello_on_fail ( enum e_future_error err , const char * what , void * user )
{
2018-08-27 21:10:45 +08:00
struct promise * p = ( struct promise * ) user ;
2018-10-18 12:13:41 +08:00
struct ssl_connect_server_ctx * ctx = ( struct ssl_connect_server_ctx * ) promise_dettach_ctx ( p ) ;
2018-08-31 19:59:22 +08:00
ATOMIC_INC ( & ( ctx - > mgr - > stat_val [ SSL_NO_CHELLO ] ) ) ;
2018-08-26 14:30:26 +08:00
promise_failed ( p , FUTURE_ERROR_EXCEPTION , " upstream create failed for no client hello in downstream. " ) ;
2018-10-18 12:13:41 +08:00
wrap_ssl_connect_server_ctx_free ( ctx ) ;
2018-08-26 14:30:26 +08:00
return ;
}
2018-10-31 19:44:13 +08:00
void ssl_async_upstream_create ( struct future * f , struct ssl_mgr * mgr , evutil_socket_t fd_upstream ,
2019-06-01 20:28:07 +08:00
evutil_socket_t fd_downstream , struct tfe_stream * tcp_stream )
2018-08-26 14:30:26 +08:00
{
struct promise * p = future_to_promise ( f ) ;
2018-10-18 12:13:41 +08:00
struct ssl_connect_server_ctx * ctx = ALLOC ( struct ssl_connect_server_ctx , 1 ) ;
2018-08-27 21:10:45 +08:00
int ret = 0 ;
2018-08-26 14:30:26 +08:00
2018-08-28 15:25:09 +08:00
ctx - > addrlen = sizeof ( ctx - > addr ) ;
2018-10-05 18:30:58 +08:00
ret = getpeername ( fd_upstream , ( struct sockaddr * ) & ( ctx - > addr ) , & ( ctx - > addrlen ) ) ;
2018-10-21 20:09:23 +08:00
if ( ret ! = 0 )
{
ssl_connect_server_ctx_free ( ctx ) ;
promise_failed ( p , FUTURE_ERROR_EXCEPTION , " upstream fd closed " ) ;
return ;
}
2019-06-01 20:28:07 +08:00
struct event_base * evbase = tfe_proxy_get_work_thread_evbase ( tcp_stream - > thread_id ) ;
2018-08-27 21:10:45 +08:00
ctx - > fd_downstream = fd_downstream ;
ctx - > fd_upstream = fd_upstream ;
2019-06-01 20:28:07 +08:00
ctx - > tcp_stream = tcp_stream ;
2018-08-27 21:10:45 +08:00
ctx - > mgr = mgr ;
2018-10-18 12:13:41 +08:00
promise_set_ctx ( p , ctx , wrap_ssl_connect_server_ctx_free ) ;
2018-08-27 21:10:45 +08:00
2018-09-02 15:46:39 +08:00
ctx - > f_peek_chello = future_create ( " peek_sni " , peek_chello_on_succ , peek_chello_on_fail , p ) ;
2019-05-25 15:54:28 +08:00
ssl_async_peek_client_hello ( ctx - > f_peek_chello , fd_downstream , evbase , mgr - > logger ) ;
2018-08-21 16:11:50 +08:00
}
2019-09-05 11:37:37 +08:00
2018-08-21 16:11:50 +08:00
2018-10-05 21:34:57 +08:00
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 )
{
2019-05-24 17:58:43 +08:00
enum STEK_GET_RET ret = STEK_NOT_FOUND ;
2018-10-08 10:55:03 +08:00
const EVP_MD * digest = EVP_sha256 ( ) ;
const EVP_CIPHER * cipher = EVP_aes_256_cbc ( ) ;
2019-05-24 17:58:43 +08:00
size_t size = 32 ;
struct ssl_stream * s_stream = ( struct ssl_stream * ) SSL_get_ex_data ( ssl_conn , SSL_EX_DATA_IDX_SSLSTREAM ) ;
struct ssl_mgr * mgr = s_stream - > mgr ;
void * logger = s_stream - > mgr - > logger ;
const char * sni = s_stream - > peer - > up_parts . client_hello - > sni ;
struct sess_ticket_box * stek_box = s_stream - > mgr - > down_stek_box ;
struct sess_ticket_key cur_stek ;
2019-09-05 11:37:37 +08:00
unsigned char buf [ 33 ] = { 0 } ;
2019-05-24 17:58:43 +08:00
ATOMIC_INC ( & ( mgr - > stat_val [ SSL_DOWN_TIKCET_QUERY ] ) ) ;
2018-10-05 21:34:57 +08:00
if ( enc = = 1 )
2019-05-24 17:58:43 +08:00
{
2019-09-05 11:37:37 +08:00
2019-05-24 17:58:43 +08:00
sess_ticket_box_get_key_for_enc ( stek_box , sni , & cur_stek ) ;
2019-09-05 11:37:37 +08:00
/* encrypt session stek */
2019-05-24 17:58:43 +08:00
if ( RAND_bytes ( iv , EVP_CIPHER_iv_length ( cipher ) ) ! = 1 )
{
TFE_LOG_ERROR ( mgr - > logger , " Session Ticket RAND_bytes() failed " ) ;
ret = STEK_ERROR ;
goto leave ;
2018-10-05 21:34:57 +08:00
}
2019-05-24 17:58:43 +08:00
if ( EVP_EncryptInit_ex ( ectx , cipher , NULL , cur_stek . aes_key , iv ) ! = 1 )
{
TFE_LOG_ERROR ( mgr - > logger , " EVP_EncryptInit_ex() failed " ) ;
ret = STEK_ERROR ;
goto leave ;
2018-10-05 21:34:57 +08:00
}
2019-09-05 11:37:37 +08:00
if ( HMAC_Init_ex ( hctx , cur_stek . hmac_key , size , digest , NULL ) ! = 1 )
2019-05-24 17:58:43 +08:00
{
2018-10-05 21:34:57 +08:00
TFE_LOG_ERROR ( mgr - > logger , " HMAC_Init_ex() failed " ) ;
2019-05-24 17:58:43 +08:00
ret = STEK_ERROR ;
goto leave ;
2018-10-05 21:34:57 +08:00
}
2019-05-24 17:58:43 +08:00
memcpy ( name , cur_stek . name , sizeof ( cur_stek . name ) ) ;
ATOMIC_INC ( & ( mgr - > stat_val [ SSL_DOWN_TICKET_NEW ] ) ) ;
ret = STEK_FOUND_FRESH ;
2019-09-05 11:37:37 +08:00
}
else
2019-05-24 17:58:43 +08:00
{
2019-09-05 11:37:37 +08:00
/* decrypt session stek */
2019-05-24 17:58:43 +08:00
ret = sess_ticket_box_get_key_for_dec ( stek_box , sni , name , & cur_stek ) ;
2018-10-05 21:34:57 +08:00
2019-05-24 17:58:43 +08:00
if ( ret = = STEK_FOUND_FRESH | | ret = = STEK_FOUND_STALED )
2018-10-05 21:34:57 +08:00
{
2019-05-24 17:58:43 +08:00
if ( HMAC_Init_ex ( hctx , cur_stek . hmac_key , size , digest , NULL ) ! = 1 )
{
TFE_LOG_ERROR ( logger , " HMAC_Init_ex() failed " ) ;
ret = STEK_ERROR ;
goto leave ;
2019-09-05 11:37:37 +08:00
}
if ( EVP_DecryptInit_ex ( ectx , cipher , NULL , cur_stek . aes_key , iv ) ! = 1 )
2019-05-24 17:58:43 +08:00
{
TFE_LOG_ERROR ( logger , " EVP_DecryptInit_ex() failed " ) ;
ret = STEK_ERROR ;
goto leave ;
}
ATOMIC_INC ( & ( mgr - > stat_val [ SSL_DOWN_TICKET_REUSE ] ) ) ;
}
else
{
// full handshake and update the session stek_box
TFE_LOG_INFO ( logger , " ssl session stek_box decrypt, key: \" %*s \" not found " , ( int ) ( tfe_hexdump ( buf , name , 16 ) - buf ) , buf ) ;
ATOMIC_INC ( & ( mgr - > stat_val [ SSL_DOWN_TICKET_NOTFOUND ] ) ) ;
}
2018-10-05 21:34:57 +08:00
}
2019-09-05 11:37:37 +08:00
2019-05-24 17:58:43 +08:00
leave :
return ( int ) ret ;
2018-10-05 21:34:57 +08:00
}
2018-08-21 16:11:50 +08:00
/*
* Called by OpenSSL when a new src SSL session is created .
* OpenSSL increments the refcount before calling the callback and will
* decrement it again if we return 0. Returning 1 will make OpenSSL skip
* the refcount decrementing . In other words , return 0 if we did not
* keep a pointer to the object ( which we never do here ) .
*/
2019-05-17 21:35:20 +08:00
static int ossl_downsess_new_cb ( SSL * ssl , SSL_SESSION * sess )
2018-08-21 16:11:50 +08:00
{
2019-05-16 20:33:42 +08:00
struct ssl_mgr * mgr = ( struct ssl_mgr * ) SSL_get_ex_data ( ssl , SSL_CTX_EX_DATA_IDX_SSLMGR ) ;
2018-08-23 19:46:38 +08:00
2018-08-21 16:11:50 +08:00
# ifdef HAVE_SSLV2
2018-08-26 14:30:26 +08:00
2018-08-27 21:10:45 +08:00
/* Session resumption seems to fail for SSLv2 with protocol
* parsing errors , so we disable caching for SSLv2 . */
if ( SSL_version ( ssl ) = = SSL2_VERSION ) {
return 0 ;
}
2018-08-26 14:30:26 +08:00
2018-08-21 16:11:50 +08:00
# endif /* HAVE_SSLV2 */
2018-08-26 14:30:26 +08:00
2019-02-18 15:47:29 +06:00
if ( sess & & ! mgr - > no_sesscache )
2018-08-27 21:10:45 +08:00
{
2018-08-23 19:46:38 +08:00
down_session_set ( mgr - > down_sess_cache , sess ) ;
2018-08-21 16:11:50 +08:00
}
2018-08-26 14:30:26 +08:00
2018-08-21 16:11:50 +08:00
return 0 ;
}
/*
* Called by OpenSSL when a src SSL session should be removed .
* OpenSSL calls SSL_SESSION_free ( ) after calling the callback ;
* we do not need to free the reference here .
*/
2019-05-17 21:35:20 +08:00
static void ossl_downsess_remove_cb ( SSL_CTX * sslctx , SSL_SESSION * sess )
2018-08-21 16:11:50 +08:00
{
2019-05-16 20:33:42 +08:00
struct ssl_mgr * mgr = ( struct ssl_mgr * ) SSL_CTX_get_ex_data ( sslctx , SSL_CTX_EX_DATA_IDX_SSLMGR ) ;
2018-08-26 14:30:26 +08:00
assert ( mgr ! = NULL ) ;
2019-02-18 15:47:29 +06:00
if ( sess & & ! mgr - > no_sesscache )
2018-08-27 21:10:45 +08:00
{
down_session_del ( mgr - > down_sess_cache , sess ) ;
2018-08-21 16:11:50 +08:00
}
2018-08-26 14:30:26 +08:00
2018-08-23 19:46:38 +08:00
return ;
2018-08-21 16:11:50 +08:00
}
/*
* Called by OpenSSL when a src SSL session is requested by the client .
2018-08-26 14:30:26 +08:00
OPENSSL_VERSION_NUMBER > = 0x10100000L required .
2018-08-21 16:11:50 +08:00
*/
2019-05-17 21:35:20 +08:00
static SSL_SESSION * ossl_downsess_get_cb ( SSL * ssl , const unsigned char * id , int idlen , int * copy )
2018-08-21 16:11:50 +08:00
{
2019-05-24 17:58:43 +08:00
struct ssl_stream * s_stream = ( struct ssl_stream * ) SSL_get_ex_data ( ssl , SSL_EX_DATA_IDX_SSLSTREAM ) ;
struct ssl_mgr * mgr = s_stream - > mgr ;
2019-02-18 15:47:29 +06:00
SSL_SESSION * sess = NULL ;
if ( ! mgr - > no_sesscache )
{
* copy = 0 ; /* SSL should not increment reference count of session */
sess = ( SSL_SESSION * ) down_session_get ( mgr - > down_sess_cache , id , idlen ) ;
}
2018-08-21 16:11:50 +08:00
return sess ;
}
/*
* Set SSL_CTX options that are the same for incoming and outgoing SSL_CTX .
*/
2018-08-26 14:30:26 +08:00
static void sslctx_set_opts ( SSL_CTX * sslctx , struct ssl_mgr * mgr )
2018-08-21 16:11:50 +08:00
{
SSL_CTX_set_options ( sslctx , SSL_OP_ALL ) ;
2018-08-26 14:30:26 +08:00
2018-08-21 16:11:50 +08:00
SSL_CTX_set_options ( sslctx , SSL_OP_TLS_ROLLBACK_BUG ) ;
2018-08-26 14:30:26 +08:00
2018-08-21 16:11:50 +08:00
SSL_CTX_set_options ( sslctx , SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION ) ;
2018-08-26 14:30:26 +08:00
2018-08-21 16:11:50 +08:00
SSL_CTX_set_options ( sslctx , SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS ) ;
2018-10-05 21:34:57 +08:00
if ( mgr - > no_ssl2 )
{
SSL_CTX_set_options ( sslctx , SSL_OP_NO_SSLv2 ) ;
2018-08-21 16:11:50 +08:00
}
2019-09-05 11:37:37 +08:00
if ( mgr - > no_ssl3 )
2018-10-05 21:34:57 +08:00
{
2018-08-27 21:10:45 +08:00
SSL_CTX_set_options ( sslctx , SSL_OP_NO_SSLv3 ) ;
}
2018-08-26 14:30:26 +08:00
2018-08-27 21:10:45 +08:00
if ( mgr - > no_tls10 )
{
2018-08-21 16:11:50 +08:00
SSL_CTX_set_options ( sslctx , SSL_OP_NO_TLSv1 ) ;
}
2018-08-27 21:10:45 +08:00
if ( mgr - > no_tls11 )
{
2018-08-21 16:11:50 +08:00
SSL_CTX_set_options ( sslctx , SSL_OP_NO_TLSv1_1 ) ;
}
2018-08-27 21:10:45 +08:00
if ( mgr - > no_tls12 )
{
2018-08-21 16:11:50 +08:00
SSL_CTX_set_options ( sslctx , SSL_OP_NO_TLSv1_2 ) ;
}
2018-10-08 10:55:03 +08:00
if ( mgr - > no_sessticket )
{
SSL_CTX_set_options ( sslctx , SSL_OP_NO_TICKET ) ;
}
2018-08-27 21:10:45 +08:00
if ( ! mgr - > sslcomp )
{
2018-08-21 16:11:50 +08:00
SSL_CTX_set_options ( sslctx , SSL_OP_NO_COMPRESSION ) ;
}
}
2018-10-29 17:30:22 +08:00
static int alpn_select_proto_cb ( SSL * ssl , const unsigned char * * out ,
unsigned char * outlen , const unsigned char * in ,
unsigned int inlen , void * arg ) {
int rv ;
const unsigned char * selected_alpn = ( const unsigned char * ) arg ;
( void ) ssl ;
unsigned char * _out = NULL ;
unsigned char _outlen = 0 ;
rv = SSL_select_next_proto ( & _out , & _outlen , in , inlen , selected_alpn , strlen ( ( const char * ) selected_alpn ) ) ;
if ( rv = = OPENSSL_NPN_NEGOTIATED )
{
* out = _out ;
* outlen = _outlen ;
return SSL_TLSEXT_ERR_OK ;
}
else //rv==OPENSSL_NPN_NO_OVERLAP
{
return SSL_TLSEXT_ERR_NOACK ;
}
}
2018-08-23 19:46:38 +08:00
/*
* Create and set up a new SSL_CTX instance for terminating SSL .
2018-08-26 18:26:24 +08:00
* Set up all the necessary callbacks , the keyring , the keyring chain and key .
2018-08-23 19:46:38 +08:00
*/
2019-05-24 14:20:44 +08:00
void downstream_ossl_init ( struct ssl_stream * s_stream )
2018-08-23 19:46:38 +08:00
{
2019-05-24 14:20:44 +08:00
struct ssl_mgr * mgr = s_stream - > mgr ;
2018-08-27 21:10:45 +08:00
SSL_CTX * sslctx = SSL_CTX_new ( mgr - > sslmethod ( ) ) ;
2019-05-24 14:20:44 +08:00
if ( ! sslctx ) return ;
struct keyring * crt = s_stream - > down_parts . keyring ;
int negotiated_version = s_stream - > peer - > negotiated_version ;
const unsigned char * selected_alpn = s_stream - > peer - > alpn_selected ;
2018-08-27 21:10:45 +08:00
SSL * ssl = NULL ;
2018-11-26 16:30:51 +08:00
UNUSED int ret = 0 ;
2018-08-26 14:30:26 +08:00
sslctx_set_opts ( sslctx , mgr ) ;
2018-09-14 18:43:28 +08:00
SSL_CTX_set_cipher_list ( sslctx , mgr - > default_ciphers ) ;
2018-08-26 14:30:26 +08:00
//TFE's OPENSSL_VERSION_NUMBER >= 0x10100000L
2019-05-18 18:27:13 +08:00
if ( negotiated_version )
{
if ( SSL_CTX_set_min_proto_version ( sslctx , negotiated_version ) = = 0 | |
SSL_CTX_set_max_proto_version ( sslctx , negotiated_version ) = = 0 )
{
SSL_CTX_free ( sslctx ) ;
2019-05-24 14:20:44 +08:00
return ;
2019-05-18 18:27:13 +08:00
}
}
else if ( mgr - > ssl_min_version )
2018-08-27 21:10:45 +08:00
{
2018-09-14 18:43:28 +08:00
if ( SSL_CTX_set_min_proto_version ( sslctx , mgr - > ssl_min_version ) = = 0 | |
2018-09-18 10:54:07 +08:00
SSL_CTX_set_max_proto_version ( sslctx , mgr - > ssl_max_version ) = = 0 )
2018-08-27 21:10:45 +08:00
{
2018-08-26 14:30:26 +08:00
SSL_CTX_free ( sslctx ) ;
2019-05-24 14:20:44 +08:00
return ;
2018-08-26 14:30:26 +08:00
}
}
2019-05-17 21:35:20 +08:00
SSL_CTX_sess_set_new_cb ( sslctx , ossl_downsess_new_cb ) ;
SSL_CTX_sess_set_remove_cb ( sslctx , ossl_downsess_remove_cb ) ;
SSL_CTX_sess_set_get_cb ( sslctx , ossl_downsess_get_cb ) ;
2019-06-21 16:10:26 +08:00
if ( ! mgr - > no_sessticket & & s_stream - > peer - > up_parts . client_hello - > sni )
2018-10-08 10:55:03 +08:00
{
SSL_CTX_set_tlsext_ticket_key_cb ( sslctx , ossl_session_ticket_key_callback ) ;
}
2018-08-26 14:30:26 +08:00
SSL_CTX_set_session_cache_mode ( sslctx , SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL ) ;
2018-08-28 15:25:09 +08:00
SSL_CTX_set_session_id_context ( sslctx , ( const unsigned char * ) mgr - > ssl_session_context ,
sizeof ( mgr - > ssl_session_context ) ) ;
2019-05-24 17:58:43 +08:00
ret = SSL_CTX_set_ex_data ( sslctx , SSL_CTX_EX_DATA_IDX_SSLMGR , mgr ) ; //used by down session cache get
2018-09-18 18:47:02 +08:00
assert ( ret = = 1 ) ;
2018-08-27 21:10:45 +08:00
if ( mgr - > dh )
{
2018-08-26 14:30:26 +08:00
SSL_CTX_set_tmp_dh ( sslctx , mgr - > dh ) ;
}
2018-08-27 21:10:45 +08:00
else
{
2018-08-26 14:30:26 +08:00
SSL_CTX_set_tmp_dh_callback ( sslctx , ssl_tmp_dh_callback ) ;
}
2018-08-27 21:10:45 +08:00
if ( mgr - > ecdhcurve )
{
EC_KEY * ecdh = ssl_ec_by_name ( mgr - > ecdhcurve ) ;
2018-08-26 14:30:26 +08:00
SSL_CTX_set_tmp_ecdh ( sslctx , ecdh ) ;
EC_KEY_free ( ecdh ) ;
}
2018-08-27 21:10:45 +08:00
else
{
EC_KEY * ecdh = ssl_ec_by_name ( NULL ) ;
2018-08-26 14:30:26 +08:00
SSL_CTX_set_tmp_ecdh ( sslctx , ecdh ) ;
EC_KEY_free ( ecdh ) ;
}
2019-05-27 14:17:52 +08:00
if ( s_stream - > peer - > up_parts . apln_enabled & & selected_alpn )
2018-10-29 17:30:22 +08:00
{
SSL_CTX_set_alpn_select_cb ( sslctx , alpn_select_proto_cb , ( void * ) selected_alpn ) ;
}
2018-08-26 18:26:24 +08:00
SSL_CTX_use_certificate ( sslctx , crt - > cert ) ;
2018-08-26 14:30:26 +08:00
SSL_CTX_use_PrivateKey ( sslctx , crt - > key ) ;
2018-08-27 21:10:45 +08:00
for ( int i = 0 ; i < sk_X509_num ( crt - > chain ) ; i + + )
{
X509 * c = sk_X509_value ( crt - > chain , i ) ;
ssl_x509_refcount_inc ( c ) ; /* next call consumes a reference */
2018-08-26 14:30:26 +08:00
SSL_CTX_add_extra_chain_cert ( sslctx , c ) ;
}
2018-08-27 21:10:45 +08:00
ssl = SSL_new ( sslctx ) ;
SSL_CTX_free ( sslctx ) ; // SSL_new() increments refcount
sslctx = NULL ;
2019-05-24 17:58:43 +08:00
ret = SSL_set_ex_data ( ssl , SSL_EX_DATA_IDX_SSLSTREAM , s_stream ) ;
2018-08-26 18:26:24 +08:00
assert ( ret = = 1 ) ;
2019-09-05 11:37:37 +08:00
2018-08-27 21:10:45 +08:00
if ( mgr - > ssl_mode_release_buffers = = 1 )
2018-08-26 18:26:24 +08:00
{
/* lower memory footprint for idle connections */
SSL_set_mode ( ssl , SSL_get_mode ( ssl ) | SSL_MODE_RELEASE_BUFFERS ) ;
}
2019-05-24 14:20:44 +08:00
s_stream - > ssl = ssl ;
return ;
2018-08-23 19:46:38 +08:00
}
2018-08-21 16:11:50 +08:00
2018-10-18 12:13:41 +08:00
void ssl_connect_client_ctx_free ( struct ssl_connect_client_ctx * ctx )
2018-08-23 19:46:38 +08:00
{
2018-08-26 14:30:26 +08:00
X509_free ( ctx - > origin_crt ) ;
2018-10-08 15:06:01 +08:00
ctx - > origin_crt = NULL ;
2019-09-05 11:37:37 +08:00
2018-10-08 15:06:01 +08:00
if ( ctx - > f_ask_keyring ! = NULL )
2018-08-27 21:10:45 +08:00
{
2018-10-08 15:06:01 +08:00
future_destroy ( ctx - > f_ask_keyring ) ;
ctx - > f_ask_keyring = NULL ;
2018-08-26 14:30:26 +08:00
}
2018-09-05 10:38:27 +08:00
//on success, bev_down and downstream has been transfered to caller by release**
2018-08-27 21:10:45 +08:00
if ( ctx - > bev_down ! = NULL )
2018-08-21 16:11:50 +08:00
{
2018-08-26 14:30:26 +08:00
bufferevent_free ( ctx - > bev_down ) ;
2018-08-21 16:11:50 +08:00
}
2018-08-27 21:10:45 +08:00
if ( ctx - > downstream ! = NULL )
2018-08-21 16:11:50 +08:00
{
2018-08-26 14:30:26 +08:00
ssl_stream_free ( ctx - > downstream ) ;
2018-08-21 16:11:50 +08:00
}
2018-11-29 16:24:45 +08:00
free ( ctx ) ;
2018-08-26 14:30:26 +08:00
return ;
}
2018-10-18 12:13:41 +08:00
void wrap_ssl_connect_client_ctx_free ( void * p )
2018-08-27 21:10:45 +08:00
{
2018-10-18 12:13:41 +08:00
struct ssl_connect_client_ctx * ctx = ( struct ssl_connect_client_ctx * ) p ;
ssl_connect_client_ctx_free ( ctx ) ;
2018-08-27 21:10:45 +08:00
}
struct ssl_stream * ssl_downstream_create_result_release_stream ( future_result_t * result )
2018-08-26 14:30:26 +08:00
{
2018-10-18 12:13:41 +08:00
struct ssl_connect_client_ctx * ctx = ( struct ssl_connect_client_ctx * ) result ;
2018-08-27 21:10:45 +08:00
struct ssl_stream * ret = ctx - > downstream ;
ctx - > downstream = NULL ;
2018-08-26 14:30:26 +08:00
return ret ;
}
2018-08-27 21:10:45 +08:00
struct bufferevent * ssl_downstream_create_result_release_bev ( future_result_t * result )
2018-08-26 14:30:26 +08:00
{
2018-10-18 12:13:41 +08:00
struct ssl_connect_client_ctx * ctx = ( struct ssl_connect_client_ctx * ) result ;
2018-08-27 21:10:45 +08:00
struct bufferevent * ret = ctx - > bev_down ;
ctx - > bev_down = NULL ;
2018-08-26 14:30:26 +08:00
return ret ;
}
2019-06-10 21:27:27 +08:00
2018-10-18 12:13:41 +08:00
static void ssl_client_connected_eventcb ( struct bufferevent * bev , short events , void * arg )
{
struct promise * p = ( struct promise * ) arg ;
struct ssl_connect_client_ctx * ctx = ( struct ssl_connect_client_ctx * ) promise_dettach_ctx ( p ) ;
struct ssl_stream * s_stream = ctx - > downstream ;
2019-06-01 20:28:07 +08:00
struct ssl_upstream_parts * s_upstream = & ( ctx - > peer - > up_parts ) ;
2019-09-05 11:37:37 +08:00
struct ssl_mgr * mgr = s_stream - > mgr ;
2018-11-02 20:38:06 +08:00
char error_str [ TFE_STRING_MAX ] = { 0 } ;
2019-09-05 11:37:37 +08:00
uint64_t jiffies_ms = 0 ;
2019-05-16 20:33:42 +08:00
unsigned long sslerr = 0 ;
2018-10-18 12:13:41 +08:00
if ( events & BEV_EVENT_ERROR )
{
ATOMIC_INC ( & ( mgr - > stat_val [ SSL_DOWN_ERR ] ) ) ;
2019-05-16 20:33:42 +08:00
sslerr = ssl_stream_log_error ( bev , CONN_DIR_DOWNSTREAM , mgr ) ;
2019-06-10 21:27:27 +08:00
if ( sslerr )
2019-05-21 11:47:09 +08:00
{
2019-06-10 21:27:27 +08:00
ssl_stream_process_error ( s_stream , sslerr , mgr ) ;
2019-05-21 11:47:09 +08:00
}
2019-06-01 20:28:07 +08:00
s_stream - > error = SSL_STREAM_R_CLIENT_PROTOCOL_ERROR ;
2018-10-18 12:13:41 +08:00
}
else if ( events & BEV_EVENT_EOF )
2019-09-05 11:37:37 +08:00
{
2019-09-03 19:00:54 +08:00
ATOMIC_INC ( & ( mgr - > stat_val [ SSL_DOWN_ERR ] ) ) ;
2019-06-14 22:49:41 +08:00
ssl_stream_process_zero_eof ( s_stream , mgr ) ;
2018-10-18 12:13:41 +08:00
}
else if ( events & BEV_EVENT_TIMEOUT )
{
ATOMIC_INC ( & ( mgr - > stat_val [ SSL_DOWN_ERR ] ) ) ;
2019-06-01 20:28:07 +08:00
s_stream - > error = SSL_STREAM_R_CONNECT_CLIENT_TIMEOUT ;
2018-10-18 12:13:41 +08:00
}
else if ( events & BEV_EVENT_CONNECTED )
2018-11-21 18:56:04 +08:00
{
2019-09-05 11:37:37 +08:00
2018-11-21 18:56:04 +08:00
clock_gettime ( CLOCK_MONOTONIC , & ( ctx - > end ) ) ;
jiffies_ms = ( ctx - > end . tv_sec - ctx - > start . tv_sec ) * 1000 + ( ctx - > end . tv_nsec - ctx - > start . tv_nsec ) / 1000000 ;
if ( jiffies_ms > LATENCY_WARNING_THRESHOLD_MS )
{
2023-07-14 19:38:18 +08:00
TFE_LOG_INFO ( mgr - > logger , " Warning: ssl connect client latency %ld ms: addr=%s, sni=%s " ,
2019-09-05 11:37:37 +08:00
jiffies_ms ,
s_stream - > tcp_stream - > str_stream_info ,
2019-06-21 16:10:26 +08:00
s_upstream - > client_hello - > sni ) ;
2018-11-21 18:56:04 +08:00
}
2019-06-01 20:28:07 +08:00
s_stream - > connect_latency_ms = jiffies_ms ;
2019-06-02 18:17:53 +08:00
ssl_stream_set_cmsg_integer ( s_stream , TFE_CMSG_SSL_CLIENT_SIDE_LATENCY , jiffies_ms ) ;
2018-10-18 12:13:41 +08:00
bufferevent_disable ( ctx - > bev_down , EV_READ | EV_WRITE ) ;
bufferevent_setcb ( ctx - > bev_down , NULL , NULL , NULL , NULL ) ; //leave a clean bev for on_success
if ( mgr - > log_master_key )
{
2021-04-28 18:01:32 +08:00
log_ssl_master_key ( s_stream , CONN_DIR_DOWNSTREAM , mgr - > fp_master_key ) ;
2018-10-18 12:13:41 +08:00
}
2019-06-01 20:28:07 +08:00
s_stream - > negotiated_version = SSL_version ( s_stream - > ssl ) ;
2019-06-02 18:17:53 +08:00
ssl_stream_set_cmsg_string ( s_stream , TFE_CMSG_SSL_CLIENT_SIDE_VERSION , SSL_get_version ( s_stream - > ssl ) ) ;
2018-10-18 12:13:41 +08:00
promise_success ( p , ctx ) ;
}
2019-09-05 11:37:37 +08:00
2019-06-01 20:28:07 +08:00
if ( s_stream - > error )
{
ssl_stream_set_cmsg_string ( s_stream , TFE_CMSG_SSL_ERROR , ssl_stream_get_error_string ( s_stream - > error ) ) ;
2019-06-21 16:10:26 +08:00
snprintf ( error_str , sizeof ( error_str ) , " %s : sni=%s " , ssl_stream_get_error_string ( s_stream - > error ) , s_upstream - > client_hello - > sni ) ;
2019-06-01 20:28:07 +08:00
promise_failed ( p , FUTURE_ERROR_EXCEPTION , error_str ) ;
}
2018-10-18 12:13:41 +08:00
ssl_connect_client_ctx_free ( ctx ) ;
return ;
}
2018-08-26 14:30:26 +08:00
2018-08-26 18:26:24 +08:00
void ask_keyring_on_succ ( void * result , void * user )
2018-08-26 14:30:26 +08:00
{
2018-08-27 21:10:45 +08:00
struct promise * p = ( struct promise * ) user ;
2018-10-18 12:13:41 +08:00
struct ssl_connect_client_ctx * ctx = ( struct ssl_connect_client_ctx * ) promise_get_ctx ( p ) ;
2018-08-27 21:10:45 +08:00
2018-09-04 18:13:05 +08:00
struct keyring * kyr = NULL ;
2018-08-27 21:10:45 +08:00
struct ssl_mgr * mgr = ctx - > ssl_mgr ;
2019-06-01 20:28:07 +08:00
struct event_base * evbase = tfe_proxy_get_work_thread_evbase ( ctx - > tcp_stream - > thread_id ) ;
2018-09-05 10:38:27 +08:00
kyr = key_keeper_release_keyring ( result ) ; //kyr will be freed at ssl downstream closing.
2019-09-05 11:37:37 +08:00
2018-11-21 18:56:04 +08:00
clock_gettime ( CLOCK_MONOTONIC , & ( ctx - > start ) ) ;
2019-05-18 18:27:13 +08:00
ctx - > downstream = ssl_stream_new ( mgr , ctx - > fd_downstream , CONN_DIR_DOWNSTREAM , NULL ,
2019-06-01 20:28:07 +08:00
kyr , ctx - > peer , ctx - > tcp_stream ) ;
2019-05-24 14:20:44 +08:00
downstream_ossl_init ( ctx - > downstream ) ;
2018-11-26 14:54:20 +08:00
ctx - > bev_down = bufferevent_openssl_socket_new ( evbase , ctx - > fd_downstream , ctx - > downstream - > ssl ,
2018-12-14 03:06:34 +06:00
BUFFEREVENT_SSL_ACCEPTING , BEV_OPT_DEFER_CALLBACKS | BEV_OPT_THREADSAFE ) ;
2018-08-26 14:30:26 +08:00
bufferevent_openssl_set_allow_dirty_shutdown ( ctx - > bev_down , 1 ) ;
2019-09-05 11:37:37 +08:00
2018-10-18 12:13:41 +08:00
bufferevent_setcb ( ctx - > bev_down , NULL , NULL , ssl_client_connected_eventcb , p ) ;
bufferevent_enable ( ctx - > bev_down , EV_READ | EV_WRITE ) ; //waiting for connect event only
future_destroy ( ctx - > f_ask_keyring ) ;
ctx - > f_ask_keyring = NULL ;
2018-08-26 14:30:26 +08:00
}
2018-08-26 18:26:24 +08:00
void ask_keyring_on_fail ( enum e_future_error error , const char * what , void * user )
2018-08-26 14:30:26 +08:00
{
2018-08-27 21:10:45 +08:00
struct promise * p = ( struct promise * ) user ;
2018-10-18 12:13:41 +08:00
struct ssl_connect_client_ctx * ctx = ( struct ssl_connect_client_ctx * ) promise_dettach_ctx ( p ) ;
2018-08-26 14:30:26 +08:00
promise_failed ( p , error , what ) ;
2018-10-18 12:13:41 +08:00
ssl_connect_client_ctx_free ( ctx ) ;
2018-08-26 14:30:26 +08:00
return ;
}
/*
2018-08-26 18:26:24 +08:00
* Create a SSL stream for the incoming connection , based on the upstream .
2018-08-26 14:30:26 +08:00
*/
2018-10-31 19:44:13 +08:00
void ssl_async_downstream_create ( struct future * f , struct ssl_mgr * mgr , struct ssl_stream * upstream ,
2019-06-01 20:28:07 +08:00
evutil_socket_t fd_downstream , struct tfe_stream * tcp_stream )
2018-08-26 14:30:26 +08:00
{
assert ( upstream - > dir = = CONN_DIR_UPSTREAM ) ;
2018-09-04 18:13:05 +08:00
const char * sni = NULL ;
2019-06-01 20:28:07 +08:00
struct ssl_connect_client_ctx * ctx = ALLOC ( struct ssl_connect_client_ctx , 1 ) ;
2018-08-27 21:10:45 +08:00
ctx - > ssl_mgr = mgr ;
ctx - > fd_downstream = fd_downstream ;
2019-06-01 20:28:07 +08:00
ctx - > tcp_stream = tcp_stream ;
struct event_base * evbase = tfe_proxy_get_work_thread_evbase ( tcp_stream - > thread_id ) ;
struct evdns_base * dnsbase = tfe_proxy_get_work_thread_dnsbase ( tcp_stream - > thread_id ) ;
2019-09-16 14:01:14 +08:00
struct evhttp_connection * evhttp = tfe_proxy_get_work_thread_evhttp ( tcp_stream - > thread_id ) ;
2018-11-26 14:54:20 +08:00
2018-08-27 21:10:45 +08:00
if ( upstream ! = NULL )
2018-08-26 18:26:24 +08:00
{
2019-06-01 20:28:07 +08:00
ctx - > peer = upstream ;
2018-08-27 21:10:45 +08:00
ctx - > origin_crt = SSL_get_peer_certificate ( upstream - > ssl ) ;
2019-05-14 19:58:23 +08:00
sni = upstream - > up_parts . client_hello - > sni ;
2018-08-26 18:26:24 +08:00
}
2018-08-27 21:10:45 +08:00
struct promise * p = future_to_promise ( f ) ;
2018-10-18 12:13:41 +08:00
promise_set_ctx ( p , ctx , wrap_ssl_connect_client_ctx_free ) ;
2018-10-08 15:06:01 +08:00
ctx - > f_ask_keyring = future_create ( " ask_kyr " , ask_keyring_on_succ , ask_keyring_on_fail , p ) ;
2019-05-14 19:58:23 +08:00
ctx - > is_origin_crt_verify_passed = upstream - > up_parts . is_server_cert_verify_passed ;
2022-11-08 10:53:05 +08:00
int keyring_id = 0 ;
if ( ctx - > is_origin_crt_verify_passed )
{
keyring_id = upstream - > up_parts . keyring_for_trusted ;
}
else
{
keyring_id = upstream - > up_parts . keyring_for_untrusted ;
}
key_keeper_async_ask ( ctx - > f_ask_keyring , mgr - > key_keeper , sni , keyring_id , ctx - > origin_crt , ctx - > is_origin_crt_verify_passed ,
2019-09-16 14:01:14 +08:00
evbase , dnsbase , evhttp ) ;
2018-08-26 14:30:26 +08:00
return ;
2018-08-21 16:11:50 +08:00
}
2018-08-24 10:55:47 +08:00
/*
* Cleanly shutdown an SSL session on file descriptor fd using low - level
* file descriptor readiness events on event base evbase .
* Guarantees that SSL and the corresponding SSL_CTX are freed and the
* socket is closed , eventually , or in the case of fatal errors , immediately .
*/
2019-09-05 16:16:51 +08:00
void ssl_stream_free ( struct ssl_stream * s_stream , struct event_base * evbase , struct bufferevent * bev )
2018-08-24 10:55:47 +08:00
{
2019-09-02 11:39:19 +08:00
UNUSED struct ssl_shutdown_ctx * sslshutctx = NULL ;
2019-06-10 21:27:27 +08:00
evutil_socket_t fd = - 1 ;
fd = bufferevent_getfd ( bev ) ;
2018-08-31 19:59:22 +08:00
assert ( fd = = s_stream - > _do_not_use . fd ) ;
2019-06-10 21:27:27 +08:00
unsigned long sslerr = 0 ;
2019-09-03 11:07:09 +08:00
2019-09-03 19:00:54 +08:00
if ( s_stream - > dir = = CONN_DIR_UPSTREAM )
2019-09-03 11:07:09 +08:00
{
2019-09-03 19:00:54 +08:00
size_t rx_offset_this_time = 0 ;
2021-08-20 11:32:33 +08:00
tfe_stream_info_get ( s_stream - > tcp_stream , INFO_FROM_UPSTREAM_RX_OFFSET , & rx_offset_this_time , sizeof ( rx_offset_this_time ) ) ;
2019-09-03 19:00:54 +08:00
const char * sni = ( s_stream - > up_parts . client_hello & & s_stream - > up_parts . client_hello - > sni ) ? s_stream - > up_parts . client_hello - > sni : " null " ;
2023-07-11 16:28:52 +08:00
TFE_LOG_DEBUG ( g_default_logger , " ssl up stream close, rx_offset:%zu, sni:%s " , rx_offset_this_time , sni ) ;
2019-09-03 11:07:09 +08:00
}
2019-06-10 21:27:27 +08:00
if ( errno )
{
sslerr = ssl_stream_log_error ( bev , s_stream - > dir , s_stream - > mgr ) ;
if ( sslerr )
{
ssl_stream_process_error ( s_stream , sslerr , s_stream - > mgr ) ;
}
}
2019-07-19 20:10:23 +08:00
//sslshutctx = ssl_shutdown_ctx_new(s_stream, evbase);
//pxy_ssl_shutdown_cb(fd, 0, sslshutctx);
2019-07-19 20:52:11 +08:00
bufferevent_setcb ( bev , NULL , NULL , NULL , NULL ) ;
2019-07-19 20:10:23 +08:00
SSL_set_shutdown ( s_stream - > ssl , SSL_RECEIVED_SHUTDOWN ) ;
SSL_shutdown ( s_stream - > ssl ) ;
2019-07-19 20:37:35 +08:00
bufferevent_disable ( bev , EV_READ | EV_WRITE ) ;
struct bufferevent * ubev = bufferevent_get_underlying ( bev ) ;
if ( ubev ) {
bufferevent_disable ( ubev , EV_READ | EV_WRITE ) ;
bufferevent_setfd ( ubev , - 1 ) ;
bufferevent_setcb ( ubev , NULL , NULL , NULL , NULL ) ;
bufferevent_free ( ubev ) ;
}
2019-09-05 16:16:51 +08:00
2019-07-19 20:10:23 +08:00
ssl_stream_free ( s_stream ) ;
2018-08-21 16:11:50 +08:00
}
2018-10-31 19:44:13 +08:00
int ssl_manager_add_trust_ca ( struct ssl_mgr * mgr , const char * pem_file )
{
2020-09-29 10:51:37 +08:00
int ret = ssl_trusted_cert_storage_add ( mgr - > trust_CA_store , SSL_X509_OBJ_CERT , pem_file ) ;
if ( ret = = 1 )
{
ATOMIC_INC ( & ( ( * ( mgr - > svc_cache ) ) . stat . trusted_cert_cnt ) ) ;
}
return ret ;
2018-10-31 19:44:13 +08:00
}
int ssl_manager_del_trust_ca ( struct ssl_mgr * mgr , const char * pem_file )
{
2020-09-29 10:51:37 +08:00
int ret = ssl_trusted_cert_storage_del ( mgr - > trust_CA_store , SSL_X509_OBJ_CERT , pem_file ) ;
if ( ret = = 1 )
{
ATOMIC_DEC ( & ( ( * ( mgr - > svc_cache ) ) . stat . trusted_cert_cnt ) ) ;
}
return ret ;
2018-10-31 19:44:13 +08:00
}
int ssl_manager_add_crl ( struct ssl_mgr * mgr , const char * pem_file )
{
return ssl_trusted_cert_storage_add ( mgr - > trust_CA_store , SSL_X509_OBJ_CRL , pem_file ) ;
}
int ssl_manager_del_crl ( struct ssl_mgr * mgr , const char * pem_file )
{
return ssl_trusted_cert_storage_del ( mgr - > trust_CA_store , SSL_X509_OBJ_CRL , pem_file ) ;
}
void ssl_manager_reset_trust_ca ( struct ssl_mgr * mgr )
{
2020-01-08 14:16:23 +08:00
ATOMIC_ZERO ( & ( ( * ( mgr - > svc_cache ) ) . stat . trusted_cert_cnt ) ) ;
2018-10-31 19:44:13 +08:00
ssl_trusted_cert_storage_reset ( mgr - > trust_CA_store ) ;
return ;
}
2020-09-28 14:33:50 +08:00
void ssl_manager_reset_trust_ca_finish ( struct ssl_mgr * mgr )
{
ssl_trusted_cert_storage_reset_finish ( mgr - > trust_CA_store ) ;
return ;
}
2019-05-17 21:35:20 +08:00
int ssl_stream_set_integer_opt ( struct ssl_stream * upstream , enum SSL_STREAM_OPT opt_type , int opt_val )
{
struct cert_verify_param * verify_param = & ( upstream - > up_parts . verify_param ) ;
2019-05-27 14:17:52 +08:00
assert ( upstream - > dir = = CONN_DIR_UPSTREAM ) ;
2019-05-17 21:35:20 +08:00
switch ( opt_type )
{
case SSL_STREAM_OPT_NO_VERIFY_SELF_SIGNED :
verify_param - > no_verify_self_signed = opt_val ;
break ;
case SSL_STREAM_OPT_NO_VERIFY_COMMON_NAME :
verify_param - > no_verify_cn = opt_val ;
break ;
case SSL_STREAM_OPT_NO_VERIFY_ISSUER :
verify_param - > no_verify_issuer = opt_val ;
break ;
case SSL_STREAM_OPT_NO_VERIFY_EXPIRY_DATE :
verify_param - > no_verify_expiry_date = opt_val ;
break ;
2019-05-19 17:45:16 +08:00
case SSL_STREAM_OPT_BLOCK_FAKE_CERT :
2019-05-17 21:35:20 +08:00
upstream - > up_parts . block_fake_cert = opt_val ;
break ;
case SSL_STREAM_OPT_PROTOCOL_MIN_VERSION :
2019-05-18 18:27:13 +08:00
upstream - > ssl_min_version = opt_val ;
break ;
2019-05-17 21:35:20 +08:00
case SSL_STREAM_OPT_PROTOCOL_MAX_VERSION :
2019-05-18 18:27:13 +08:00
upstream - > ssl_max_version = opt_val ;
2019-05-17 21:35:20 +08:00
break ;
2019-05-27 14:17:52 +08:00
case SSL_STREAM_OPT_ENABLE_ALPN :
upstream - > up_parts . apln_enabled = opt_val ;
break ;
2022-11-08 10:53:05 +08:00
case SSL_STREAM_OPT_KEYRING_FOR_TRUSTED :
upstream - > up_parts . keyring_for_trusted = opt_val ;
break ;
case SSL_STREAM_OPT_KEYRING_FOR_UNTRUSTED :
upstream - > up_parts . keyring_for_untrusted = opt_val ;
2019-05-20 16:56:37 +08:00
break ;
2019-05-17 21:35:20 +08:00
default :
2019-05-19 17:45:16 +08:00
assert ( 0 ) ;
2019-05-17 21:35:20 +08:00
return 0 ;
}
return 1 ;
}
2019-06-01 20:28:07 +08:00
int ssl_stream_get_integer_opt ( struct ssl_stream * upstream , enum SSL_STREAM_OPT opt_type , int * opt_val )
2019-05-17 21:35:20 +08:00
{
struct ssl_service_status * svc = & upstream - > up_parts . svc_status ;
2019-09-02 11:39:19 +08:00
UNUSED int ret = 0 ;
2019-05-17 21:35:20 +08:00
switch ( opt_type )
{
case SSL_STREAM_OPT_IS_EV_CERT :
* opt_val = svc - > is_ev ;
break ;
case SSL_STREAM_OPT_IS_CT_CERT :
* opt_val = svc - > is_ct ;
break ;
case SSL_STREAM_OPT_IS_MUTUAL_AUTH :
* opt_val = svc - > is_mutual_auth ;
break ;
case SSL_STREAM_OPT_PINNING_STATUS :
2020-05-19 18:07:04 +08:00
* opt_val = svc - > cli_pinning_status ;
break ;
2020-12-25 21:52:14 +06:00
case SSL_STREAM_OPT_JA3_PINNING_STATUS :
* opt_val = svc - > ja3_pinning_status ;
2019-05-17 21:35:20 +08:00
break ;
2019-05-21 11:47:09 +08:00
case SSL_STREAM_OPT_HAS_PROTOCOL_ERRORS :
* opt_val = svc - > has_protocol_errors ;
break ;
2019-05-17 21:35:20 +08:00
default :
2019-06-01 20:28:07 +08:00
return - 1 ;
2019-05-17 21:35:20 +08:00
}
2019-06-01 20:28:07 +08:00
return 0 ;
2019-05-17 21:35:20 +08:00
}
2023-04-11 15:19:22 +08:00
uint64_t ssl_stream_get_policy_id ( struct ssl_stream * upstream )
{
uint16_t out_size ;
uint64_t policy_id = 0 ;
struct tfe_cmsg * cmsg = tfe_stream_get0_cmsg ( upstream - > tcp_stream ) ;
2023-04-23 16:55:30 +08:00
int ret = tfe_cmsg_get_value ( cmsg , TFE_CMSG_POLICY_ID , ( unsigned char * ) & policy_id , sizeof ( policy_id ) , & out_size ) ;
2023-04-11 15:19:22 +08:00
assert ( ret = = 0 ) ;
return policy_id ;
}
2023-04-23 16:35:42 +08:00
int ssl_stream_get_decrypted_profile_id ( struct ssl_stream * upstream )
{
uint16_t out_size ;
int profile_id = 0 ;
struct tfe_cmsg * cmsg = tfe_stream_get0_cmsg ( upstream - > tcp_stream ) ;
2023-04-23 16:55:30 +08:00
int ret = tfe_cmsg_get_value ( cmsg , TFE_CMSG_DECRYPTION_PROFILE_ID , ( unsigned char * ) & profile_id , sizeof ( profile_id ) , & out_size ) ;
2023-04-23 16:35:42 +08:00
assert ( ret = = 0 ) ;
return profile_id ;
}
int ssl_stream_get_trusted_keyring_profile_id ( struct ssl_stream * upstream )
{
uint16_t out_size ;
int keyring_id = 0 ;
struct tfe_cmsg * cmsg = tfe_stream_get0_cmsg ( upstream - > tcp_stream ) ;
2023-04-23 16:55:30 +08:00
int ret = tfe_cmsg_get_value ( cmsg , TFE_CMSG_KEYRING_FOR_TRUSTED_ID , ( unsigned char * ) & keyring_id , sizeof ( keyring_id ) , & out_size ) ;
2023-04-23 16:35:42 +08:00
assert ( ret = = 0 ) ;
return keyring_id ;
}
int ssl_stream_get_untrusted_keyring_profile_id ( struct ssl_stream * upstream )
{
uint16_t out_size ;
int keyring_id = 0 ;
struct tfe_cmsg * cmsg = tfe_stream_get0_cmsg ( upstream - > tcp_stream ) ;
2023-04-23 16:55:30 +08:00
int ret = tfe_cmsg_get_value ( cmsg , TFE_CMSG_KEYRING_FOR_UNTRUSTED , ( unsigned char * ) & keyring_id , sizeof ( keyring_id ) , & out_size ) ;
2023-04-23 16:35:42 +08:00
assert ( ret = = 0 ) ;
return keyring_id ;
}
2019-06-14 18:58:03 +08:00
int ssl_stream_get_string_opt ( struct ssl_stream * upstream , enum SSL_STREAM_OPT opt_type , char * in_buff , size_t sz )
{
const char * sni = upstream - > up_parts . client_hello - > sni ? upstream - > up_parts . client_hello - > sni : " null " ;
switch ( opt_type )
{
case SSL_STREAM_OPT_SNI :
strncpy ( in_buff , sni , sz ) ;
break ;
case SSL_STREAM_OPT_ADDR :
strncpy ( in_buff , upstream - > tcp_stream - > str_stream_info , sz ) ;
break ;
default :
assert ( 0 ) ;
return - 1 ;
}
return 0 ;
2019-09-05 11:37:37 +08:00
}