优化原站证书验证处理流程,不对缓存证书校验不通过的session,重用连接不进行验证。

This commit is contained in:
zhengchao
2018-10-08 15:06:01 +08:00
parent d63dfaa4d4
commit de94bc645c

View File

@@ -33,6 +33,11 @@
#include <platform.h> #include <platform.h>
int SSL_EX_DATA_IDX_SSLMGR; int SSL_EX_DATA_IDX_SSLMGR;
int SSL_EX_DATA_IDX_VERIFIED;
int SSL_PEER_CERT_VERIFY_PASSED=1;
int SSL_PEER_CERT_VERIFY_FAILED=0;
#define MAX_NET_RETRIES 50 #define MAX_NET_RETRIES 50
/* /*
@@ -142,6 +147,7 @@ struct ssl_stream
struct keyring * keyring; //dir=downstream. struct keyring * keyring; //dir=downstream.
}; };
struct __ssl_stream_debug _do_not_use; struct __ssl_stream_debug _do_not_use;
int is_peer_cert_verify_passed;
}; };
@@ -174,12 +180,12 @@ struct ask_keyring_ctx
int keyring_id; int keyring_id;
struct ssl_stream * origin_ssl; struct ssl_stream * origin_ssl;
X509 * origin_crt; X509 * origin_crt;
int is_origin_crt_vaild; int is_origin_crt_verify_passed;
struct ssl_mgr * ssl_mgr; struct ssl_mgr * ssl_mgr;
evutil_socket_t fd_downstream; evutil_socket_t fd_downstream;
struct event_base * evbase; struct event_base * evbase;
struct future * f_query_cert; struct future * f_ask_keyring;
struct bufferevent * bev_down; struct bufferevent * bev_down;
struct ssl_stream * downstream; struct ssl_stream * downstream;
}; };
@@ -469,7 +475,9 @@ struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section
} }
//tfe2a uses SSLv23_method, it was been deprecated and replaced with the TLS_method() in openssl 1.1.0. //tfe2a uses SSLv23_method, it was been deprecated and replaced with the TLS_method() in openssl 1.1.0.
mgr->sslmethod = TLS_method; mgr->sslmethod = TLS_method;
SSL_EX_DATA_IDX_SSLMGR = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); SSL_EX_DATA_IDX_SSLMGR = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
SSL_EX_DATA_IDX_VERIFIED = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
MESA_load_profile_uint_def(ini_profile, section, "ssl_compression", &(mgr->sslcomp), 1); MESA_load_profile_uint_def(ini_profile, section, "ssl_compression", &(mgr->sslcomp), 1);
MESA_load_profile_uint_def(ini_profile, section, "no_ssl2", &(mgr->no_ssl2), 1); MESA_load_profile_uint_def(ini_profile, section, "no_ssl2", &(mgr->no_ssl2), 1);
MESA_load_profile_uint_def(ini_profile, section, "no_ssl3", &(mgr->no_ssl3), 1); MESA_load_profile_uint_def(ini_profile, section, "no_ssl3", &(mgr->no_ssl3), 1);
@@ -897,6 +905,7 @@ static void ssl_connect_origin_eventcb(struct bufferevent * bev, short events, v
struct ssl_connect_origin_ctx * ctx = (struct ssl_connect_origin_ctx *) promise_dettach_ctx(promise); struct ssl_connect_origin_ctx * ctx = (struct ssl_connect_origin_ctx *) promise_dettach_ctx(promise);
struct ssl_stream * s_stream = ctx->s_stream; struct ssl_stream * s_stream = ctx->s_stream;
struct ssl_mgr* mgr=s_stream->mgr;
SSL_SESSION * ssl_sess = NULL; SSL_SESSION * ssl_sess = NULL;
if (events & BEV_EVENT_ERROR) if (events & BEV_EVENT_ERROR)
@@ -919,10 +928,29 @@ static void ssl_connect_origin_eventcb(struct bufferevent * bev, short events, v
{ {
bufferevent_disable(ctx->bev, EV_READ | EV_WRITE); bufferevent_disable(ctx->bev, EV_READ | EV_WRITE);
bufferevent_setcb(ctx->bev, NULL, NULL, NULL, NULL); //leave a clean bev for on_success bufferevent_setcb(ctx->bev, NULL, NULL, NULL, NULL); //leave a clean bev for on_success
//The reference count of the SSL_SESSION is not incremented, so no need to free.
ssl_sess = SSL_get0_session(s_stream->ssl); if(!SSL_session_reused(s_stream->ssl))
up_session_set(s_stream->mgr->up_sess_cache, (struct sockaddr *)&(ctx->addr), {
ctx->addrlen, s_stream->client_hello->sni, ssl_sess); s_stream->is_peer_cert_verify_passed = ssl_conn_verify_cert(s_stream->mgr->trust_CA_store, s_stream->ssl);
if(s_stream->is_peer_cert_verify_passed)
{
//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),
ctx->addrlen, s_stream->client_hello->sni, ssl_sess);
}
else
{
ATOMIC_INC(&(mgr->stat_val[SSL_FAKE_CRT]));
}
}
else
{
//Do not perform cert check on reused session.
s_stream->is_peer_cert_verify_passed=1;
}
promise_success(promise, ctx); promise_success(promise, ctx);
} }
ssl_connect_origin_ctx_free(ctx); ssl_connect_origin_ctx_free(ctx);
@@ -1260,14 +1288,15 @@ static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt)
return ssl; return ssl;
} }
void query_cert_ctx_free(struct ask_keyring_ctx * ctx) void ask_keyring_ctx_free(struct ask_keyring_ctx * ctx)
{ {
X509_free(ctx->origin_crt); X509_free(ctx->origin_crt);
ctx->origin_crt=NULL;
if (ctx->f_query_cert != NULL) if (ctx->f_ask_keyring != NULL)
{ {
future_destroy(ctx->f_query_cert); future_destroy(ctx->f_ask_keyring);
ctx->f_query_cert = NULL; ctx->f_ask_keyring = NULL;
} }
//on success, bev_down and downstream has been transfered to caller by release** //on success, bev_down and downstream has been transfered to caller by release**
if (ctx->bev_down != NULL) if (ctx->bev_down != NULL)
@@ -1283,10 +1312,10 @@ void query_cert_ctx_free(struct ask_keyring_ctx * ctx)
return; return;
} }
void query_cert_ctx_free_cb(void * p) void ask_keyring_ctx_free_cb(void * p)
{ {
struct ask_keyring_ctx * ctx = (struct ask_keyring_ctx *)p; struct ask_keyring_ctx * ctx = (struct ask_keyring_ctx *)p;
query_cert_ctx_free(ctx); ask_keyring_ctx_free(ctx);
} }
struct ssl_stream * ssl_downstream_create_result_release_stream(future_result_t * result) struct ssl_stream * ssl_downstream_create_result_release_stream(future_result_t * result)
@@ -1315,8 +1344,8 @@ void ask_keyring_on_succ(void * result, void * user)
kyr = key_keeper_release_keyring(result); //kyr will be freed at ssl downstream closing. kyr = key_keeper_release_keyring(result); //kyr will be freed at ssl downstream closing.
future_destroy(ctx->f_query_cert); future_destroy(ctx->f_ask_keyring);
ctx->f_query_cert = NULL; ctx->f_ask_keyring = NULL;
ctx->downstream = ssl_stream_new(mgr, ctx->fd_downstream, CONN_DIR_DOWNSTREAM, NULL, kyr); ctx->downstream = ssl_stream_new(mgr, ctx->fd_downstream, CONN_DIR_DOWNSTREAM, NULL, kyr);
ctx->bev_down = bufferevent_openssl_socket_new(ctx->evbase, ctx->fd_downstream, ctx->downstream->ssl, ctx->bev_down = bufferevent_openssl_socket_new(ctx->evbase, ctx->fd_downstream, ctx->downstream->ssl,
@@ -1324,7 +1353,7 @@ void ask_keyring_on_succ(void * result, void * user)
bufferevent_openssl_set_allow_dirty_shutdown(ctx->bev_down, 1); bufferevent_openssl_set_allow_dirty_shutdown(ctx->bev_down, 1);
promise_success(p, ctx); promise_success(p, ctx);
query_cert_ctx_free(ctx); ask_keyring_ctx_free(ctx);
} }
void ask_keyring_on_fail(enum e_future_error error, const char * what, void * user) void ask_keyring_on_fail(enum e_future_error error, const char * what, void * user)
@@ -1332,7 +1361,7 @@ void ask_keyring_on_fail(enum e_future_error error, const char * what, void * us
struct promise * p = (struct promise *) user; struct promise * p = (struct promise *) user;
struct ask_keyring_ctx * ctx = (struct ask_keyring_ctx *) promise_dettach_ctx(p); struct ask_keyring_ctx * ctx = (struct ask_keyring_ctx *) promise_dettach_ctx(p);
promise_failed(p, error, what); promise_failed(p, error, what);
query_cert_ctx_free(ctx); ask_keyring_ctx_free(ctx);
return; return;
} }
@@ -1344,6 +1373,7 @@ void ssl_async_downstream_create(struct future * f, struct ssl_mgr * mgr, struct
{ {
assert(upstream->dir == CONN_DIR_UPSTREAM); assert(upstream->dir == CONN_DIR_UPSTREAM);
int * previous_verfiy_result=NULL;
const char* sni=NULL; const char* sni=NULL;
struct ask_keyring_ctx * ctx = ALLOC(struct ask_keyring_ctx, 1); struct ask_keyring_ctx * ctx = ALLOC(struct ask_keyring_ctx, 1);
ctx->keyring_id = keyring_id; ctx->keyring_id = keyring_id;
@@ -1359,14 +1389,11 @@ void ssl_async_downstream_create(struct future * f, struct ssl_mgr * mgr, struct
} }
struct promise * p = future_to_promise(f); struct promise * p = future_to_promise(f);
promise_set_ctx(p, ctx, query_cert_ctx_free_cb); promise_set_ctx(p, ctx, ask_keyring_ctx_free_cb);
ctx->is_origin_crt_vaild = ssl_conn_verify_cert(mgr->trust_CA_store, upstream->ssl);
if(!ctx->is_origin_crt_vaild) ctx->f_ask_keyring = future_create("ask_kyr",ask_keyring_on_succ, ask_keyring_on_fail, p);
{ ctx->is_origin_crt_verify_passed = upstream->is_peer_cert_verify_passed;
ATOMIC_INC(&(mgr->stat_val[SSL_FAKE_CRT])); key_keeper_async_ask(ctx->f_ask_keyring, mgr->key_keeper, sni, keyring_id, ctx->origin_crt, ctx->is_origin_crt_verify_passed,
}
ctx->f_query_cert = future_create("ask_kyr",ask_keyring_on_succ, ask_keyring_on_fail, p);
key_keeper_async_ask(ctx->f_query_cert, mgr->key_keeper, sni, keyring_id, ctx->origin_crt, ctx->is_origin_crt_vaild,
evbase); evbase);
return; return;
} }