优化原站证书验证处理流程,不对缓存证书校验不通过的session,重用连接不进行验证。
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user