From a0dc14761a7bd0b080817258f60de1fdac16cfcc Mon Sep 17 00:00:00 2001 From: spacewander Date: Wed, 20 Dec 2017 19:22:03 +0800 Subject: [PATCH] feature: added the sess_set_get_cb_yield patch for OpenSSL 1.1.0c and beyond. The patch is based on https://patch-diff.githubusercontent.com/raw/openssl/openssl/pull/1588.patch, with some minor modifications. Thanks Alessandro Ghedini for the ground work. Signed-off-by: Yichun Zhang (agentzh) --- ...openssl-1.1.0c-sess_set_get_cb_yield.patch | 216 ++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 patches/openssl-1.1.0c-sess_set_get_cb_yield.patch diff --git a/patches/openssl-1.1.0c-sess_set_get_cb_yield.patch b/patches/openssl-1.1.0c-sess_set_get_cb_yield.patch new file mode 100644 index 0000000..dc11851 --- /dev/null +++ b/patches/openssl-1.1.0c-sess_set_get_cb_yield.patch @@ -0,0 +1,216 @@ +diff --git a/include/openssl/bio.h b/include/openssl/bio.h +index 9bc941b25f..4f55f1f825 100644 +--- a/include/openssl/bio.h ++++ b/include/openssl/bio.h +@@ -220,6 +220,8 @@ void BIO_clear_flags(BIO *b, int flags); + /* Returned from the accept BIO when an accept would have blocked */ + # define BIO_RR_ACCEPT 0x03 + ++# define BIO_RR_SSL_SESSION_LOOKUP 0x04 ++ + /* These are passed by the BIO callback */ + # define BIO_CB_FREE 0x01 + # define BIO_CB_READ 0x02 +diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h +index 86ab9125de..ab617c4055 100644 +--- a/include/openssl/ssl.h ++++ b/include/openssl/ssl.h +@@ -788,6 +788,7 @@ __owur int SSL_extension_supported(unsigned int ext_type); + # define SSL_X509_LOOKUP 4 + # define SSL_ASYNC_PAUSED 5 + # define SSL_ASYNC_NO_JOBS 6 ++# define SSL_SESS_LOOKUP 7 + + /* These will only be used when doing non-blocking IO */ + # define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +@@ -796,6 +797,7 @@ __owur int SSL_extension_supported(unsigned int ext_type); + # define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) + # define SSL_want_async(s) (SSL_want(s) == SSL_ASYNC_PAUSED) + # define SSL_want_async_job(s) (SSL_want(s) == SSL_ASYNC_NO_JOBS) ++# define SSL_want_sess_lookup(s) (SSL_want(s) == SSL_SESS_LOOKUP) + + # define SSL_MAC_FLAG_READ_MAC_STREAM 1 + # define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 +@@ -1028,6 +1030,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + # define SSL_ERROR_WANT_ACCEPT 8 + # define SSL_ERROR_WANT_ASYNC 9 + # define SSL_ERROR_WANT_ASYNC_JOB 10 ++# define SSL_ERROR_WANT_SESSION_LOOKUP 11 ++# define SSL_ERROR_PENDING_SESSION 11 /* BoringSSL compatibility */ + # define SSL_CTRL_SET_TMP_DH 3 + # define SSL_CTRL_SET_TMP_ECDH 4 + # define SSL_CTRL_SET_TMP_DH_CB 6 +@@ -1424,6 +1428,7 @@ int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses); + int SSL_SESSION_print_keylog(BIO *bp, const SSL_SESSION *x); + int SSL_SESSION_up_ref(SSL_SESSION *ses); + void SSL_SESSION_free(SSL_SESSION *ses); ++SSL_SESSION *SSL_magic_pending_session_ptr(void); + __owur int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp); + __owur int SSL_set_session(SSL *to, SSL_SESSION *session); + __owur int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c); +diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c +index 3dd09cf52d..7ac370fefc 100644 +--- a/ssl/bio_ssl.c ++++ b/ssl/bio_ssl.c +@@ -138,6 +138,10 @@ static int ssl_read(BIO *b, char *out, int outl) + BIO_set_retry_special(b); + retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; ++ case SSL_ERROR_WANT_SESSION_LOOKUP: ++ BIO_set_retry_special(b); ++ retry_reason = BIO_RR_SSL_SESSION_LOOKUP; ++ break; + case SSL_ERROR_WANT_ACCEPT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_ACCEPT; +@@ -210,6 +214,10 @@ static int ssl_write(BIO *b, const char *out, int outl) + BIO_set_retry_special(b); + retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; ++ case SSL_ERROR_WANT_SESSION_LOOKUP: ++ BIO_set_retry_special(b); ++ retry_reason = BIO_RR_SSL_SESSION_LOOKUP; ++ break; + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_CONNECT; +@@ -363,6 +371,10 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr) + BIO_set_retry_special(b); + BIO_set_retry_reason(b, BIO_RR_SSL_X509_LOOKUP); + break; ++ case SSL_ERROR_WANT_SESSION_LOOKUP: ++ BIO_set_retry_special(b); ++ BIO_set_retry_reason(b, BIO_RR_SSL_SESSION_LOOKUP); ++ break; + default: + break; + } +diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c +index bd0fbf8101..fc65b168f0 100644 +--- a/ssl/ssl_lib.c ++++ b/ssl/ssl_lib.c +@@ -2982,6 +2982,9 @@ int SSL_get_error(const SSL *s, int i) + if (SSL_want_async_job(s)) { + return SSL_ERROR_WANT_ASYNC_JOB; + } ++ if (SSL_want_sess_lookup(s)) { ++ return SSL_ERROR_WANT_SESSION_LOOKUP; ++ } + } + + if (i == 0) { +diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c +index eee1ca1f5b..bffd87335d 100644 +--- a/ssl/ssl_sess.c ++++ b/ssl/ssl_sess.c +@@ -40,6 +40,8 @@ + #include + #include "ssl_locl.h" + ++static const char g_pending_session_magic = 0; ++ + static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); + static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s); + static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck); +@@ -502,6 +504,10 @@ int ssl_get_prev_session(SSL *s, const PACKET *ext, const PACKET *session_id) + PACKET_remaining(session_id), + ©); + ++ if (ret == SSL_magic_pending_session_ptr()) { ++ return -2; /* Retry later */ ++ } ++ + if (ret != NULL) { + s->session_ctx->stats.sess_cb_hit++; + +@@ -877,6 +883,11 @@ X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) + return s->peer; + } + ++SSL_SESSION *SSL_magic_pending_session_ptr(void) ++{ ++ return (SSL_SESSION *) &g_pending_session_magic; ++} ++ + int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) + { +diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c +index caaf0687b5..baadc1154d 100644 +--- a/ssl/statem/statem.c ++++ b/ssl/statem/statem.c +@@ -581,16 +581,18 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) + } + + s->first_packet = 0; +- if (!PACKET_buf_init(&pkt, s->init_msg, len)) { ++ ++ st->read_state = READ_STATE_PROCESS; ++ /* Fall through */ ++ ++ case READ_STATE_PROCESS: ++ if (!PACKET_buf_init(&pkt, s->init_msg, s->init_num)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + SSLerr(SSL_F_READ_STATE_MACHINE, ERR_R_INTERNAL_ERROR); + return SUB_STATE_ERROR; + } + ret = process_message(s, &pkt); + +- /* Discard the packet data */ +- s->init_num = 0; +- + switch (ret) { + case MSG_PROCESS_ERROR: + return SUB_STATE_ERROR; +@@ -610,6 +612,9 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) + st->read_state = READ_STATE_HEADER; + break; + } ++ ++ /* Discard the packet data */ ++ s->init_num = 0; + break; + + case READ_STATE_POST_PROCESS: +diff --git a/ssl/statem/statem.h b/ssl/statem/statem.h +index 2fca39b0db..b106f4d069 100644 +--- a/ssl/statem/statem.h ++++ b/ssl/statem/statem.h +@@ -60,6 +60,7 @@ typedef enum { + typedef enum { + READ_STATE_HEADER, + READ_STATE_BODY, ++ READ_STATE_PROCESS, + READ_STATE_POST_PROCESS + } READ_STATE; + +diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c +index 9327654ce5..f05d0c3dce 100644 +--- a/ssl/statem/statem_srvr.c ++++ b/ssl/statem/statem_srvr.c +@@ -1165,11 +1165,16 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) + s->hit = 1; + } else if (i == -1) { + goto err; ++ } else if (i == -2) { ++ s->rwstate = SSL_SESS_LOOKUP; ++ s->statem.read_state_work = WORK_MORE_A; ++ return MSG_PROCESS_ERROR; + } else { + /* i == 0 */ + if (!ssl_get_new_session(s, 1)) + goto err; + } ++ s->rwstate = SSL_NOTHING; + } + + if (ssl_bytes_to_cipher_list(s, &cipher_suites, &(ciphers), +diff --git a/util/libssl.num b/util/libssl.num +index 200629f74b..e580efd2d2 100644 +--- a/util/libssl.num ++++ b/util/libssl.num +@@ -403,3 +403,4 @@ SSL_dane_clear_flags 403 1_1_0 EXIST::FUNCTION: + SSL_SESSION_get0_cipher 404 1_1_0 EXIST::FUNCTION: + SSL_SESSION_get0_id_context 405 1_1_0 EXIST::FUNCTION: + SSL_SESSION_set1_id 406 1_1_0 EXIST::FUNCTION: ++SSL_magic_pending_session_ptr 407 1_1_0 EXIST::FUNCTION: