openresty/patches/openssl-1.1.0c-sess_set_get...

217 lines
7.9 KiB
C

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 <openssl/engine.h>
#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),
&copy);
+ 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: