diff --git a/platform/src/ssl_stream.cpp b/platform/src/ssl_stream.cpp index 8198bcd..e717026 100644 --- a/platform/src/ssl_stream.cpp +++ b/platform/src/ssl_stream.cpp @@ -33,6 +33,11 @@ #include 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 /* @@ -142,6 +147,7 @@ struct ssl_stream struct keyring * keyring; //dir=downstream. }; struct __ssl_stream_debug _do_not_use; + int is_peer_cert_verify_passed; }; @@ -174,12 +180,12 @@ struct ask_keyring_ctx int keyring_id; struct ssl_stream * origin_ssl; X509 * origin_crt; - int is_origin_crt_vaild; + int is_origin_crt_verify_passed; struct ssl_mgr * ssl_mgr; evutil_socket_t fd_downstream; struct event_base * evbase; - struct future * f_query_cert; + struct future * f_ask_keyring; struct bufferevent * bev_down; 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. 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, "no_ssl2", &(mgr->no_ssl2), 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_stream * s_stream = ctx->s_stream; + struct ssl_mgr* mgr=s_stream->mgr; SSL_SESSION * ssl_sess = NULL; 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_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); - up_session_set(s_stream->mgr->up_sess_cache, (struct sockaddr *)&(ctx->addr), - ctx->addrlen, s_stream->client_hello->sni, ssl_sess); + + if(!SSL_session_reused(s_stream->ssl)) + { + 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); } ssl_connect_origin_ctx_free(ctx); @@ -1260,14 +1288,15 @@ static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt) 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); - - if (ctx->f_query_cert != NULL) + ctx->origin_crt=NULL; + + if (ctx->f_ask_keyring != NULL) { - future_destroy(ctx->f_query_cert); - ctx->f_query_cert = NULL; + future_destroy(ctx->f_ask_keyring); + ctx->f_ask_keyring = NULL; } //on success, bev_down and downstream has been transfered to caller by release** if (ctx->bev_down != NULL) @@ -1283,10 +1312,10 @@ void query_cert_ctx_free(struct ask_keyring_ctx * ctx) 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; - query_cert_ctx_free(ctx); + ask_keyring_ctx_free(ctx); } 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. - future_destroy(ctx->f_query_cert); - ctx->f_query_cert = NULL; + future_destroy(ctx->f_ask_keyring); + ctx->f_ask_keyring = NULL; 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, @@ -1324,7 +1353,7 @@ void ask_keyring_on_succ(void * result, void * user) bufferevent_openssl_set_allow_dirty_shutdown(ctx->bev_down, 1); 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) @@ -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 ask_keyring_ctx * ctx = (struct ask_keyring_ctx *) promise_dettach_ctx(p); promise_failed(p, error, what); - query_cert_ctx_free(ctx); + ask_keyring_ctx_free(ctx); return; } @@ -1344,13 +1373,14 @@ void ssl_async_downstream_create(struct future * f, struct ssl_mgr * mgr, struct { assert(upstream->dir == CONN_DIR_UPSTREAM); + int * previous_verfiy_result=NULL; const char* sni=NULL; struct ask_keyring_ctx * ctx = ALLOC(struct ask_keyring_ctx, 1); ctx->keyring_id = keyring_id; ctx->ssl_mgr = mgr; ctx->fd_downstream = fd_downstream; ctx->evbase = evbase; - + if (upstream != NULL) { ctx->origin_ssl = upstream; @@ -1359,14 +1389,11 @@ void ssl_async_downstream_create(struct future * f, struct ssl_mgr * mgr, struct } struct promise * p = future_to_promise(f); - promise_set_ctx(p, ctx, query_cert_ctx_free_cb); - ctx->is_origin_crt_vaild = ssl_conn_verify_cert(mgr->trust_CA_store, upstream->ssl); - if(!ctx->is_origin_crt_vaild) - { - ATOMIC_INC(&(mgr->stat_val[SSL_FAKE_CRT])); - } - 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, + promise_set_ctx(p, ctx, ask_keyring_ctx_free_cb); + + 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; + key_keeper_async_ask(ctx->f_ask_keyring, mgr->key_keeper, sni, keyring_id, ctx->origin_crt, ctx->is_origin_crt_verify_passed, evbase); return; }