mirror of
				https://github.com/openresty/openresty.git
				synced 2024-10-13 00:29:41 +00:00 
			
		
		
		
	also added an openssl patch to support yieldable callback set by SSL_CTX_sess_set_get_cb().
		
			
				
	
	
		
			234 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| diff -urp openssl-1.0.2h/ssl/s3_srvr.c openssl-1.0.2h-patched/ssl/s3_srvr.c
 | |
| --- openssl-1.0.2h/ssl/s3_srvr.c	2016-05-03 06:44:42.000000000 -0700
 | |
| +++ openssl-1.0.2h-patched/ssl/s3_srvr.c	2016-07-19 19:18:03.779159083 -0700
 | |
| @@ -358,14 +358,20 @@ int ssl3_accept(SSL *s)
 | |
|          case SSL3_ST_SR_CLNT_HELLO_A:
 | |
|          case SSL3_ST_SR_CLNT_HELLO_B:
 | |
|          case SSL3_ST_SR_CLNT_HELLO_C:
 | |
| +        case SSL3_ST_SR_CLNT_HELLO_D:
 | |
|  
 | |
|              s->shutdown = 0;
 | |
|              ret = ssl3_get_client_hello(s);
 | |
| +            if (ret == PENDING_SESSION) {
 | |
| +                s->state = SSL3_ST_SR_CLNT_HELLO_D;
 | |
| +                s->rwstate = SSL_PENDING_SESSION;
 | |
| +                goto end;
 | |
| +            }
 | |
|              if (ret <= 0)
 | |
|                  goto end;
 | |
|  #ifndef OPENSSL_NO_SRP
 | |
| -            s->state = SSL3_ST_SR_CLNT_HELLO_D;
 | |
| -        case SSL3_ST_SR_CLNT_HELLO_D:
 | |
| +            s->state = SSL3_ST_SR_CLNT_HELLO_E;
 | |
| +        case SSL3_ST_SR_CLNT_HELLO_E:
 | |
|              {
 | |
|                  int al;
 | |
|                  if ((ret = ssl_check_srp_ext_ClientHello(s, &al)) < 0) {
 | |
| @@ -925,16 +931,25 @@ int ssl3_get_client_hello(SSL *s)
 | |
|      if (s->state == SSL3_ST_SR_CLNT_HELLO_A) {
 | |
|          s->state = SSL3_ST_SR_CLNT_HELLO_B;
 | |
|      }
 | |
| -    s->first_packet = 1;
 | |
| -    n = s->method->ssl_get_message(s,
 | |
| -                                   SSL3_ST_SR_CLNT_HELLO_B,
 | |
| -                                   SSL3_ST_SR_CLNT_HELLO_C,
 | |
| -                                   SSL3_MT_CLIENT_HELLO,
 | |
| -                                   SSL3_RT_MAX_PLAIN_LENGTH, &ok);
 | |
| -
 | |
| -    if (!ok)
 | |
| -        return ((int)n);
 | |
| -    s->first_packet = 0;
 | |
| +
 | |
| +    if (s->state != SSL3_ST_SR_CLNT_HELLO_D) {
 | |
| +        s->first_packet = 1;
 | |
| +        n = s->method->ssl_get_message(s,
 | |
| +                                       SSL3_ST_SR_CLNT_HELLO_B,
 | |
| +                                       SSL3_ST_SR_CLNT_HELLO_C,
 | |
| +                                       SSL3_MT_CLIENT_HELLO,
 | |
| +                                       SSL3_RT_MAX_PLAIN_LENGTH, &ok);
 | |
| + 
 | |
| +        if (!ok)
 | |
| +            return ((int)n);
 | |
| +        s->first_packet = 0;
 | |
| +    } else {
 | |
| +        /* We have previously parsed the ClientHello message, and can't
 | |
| +         * call ssl_get_message again without hashing the message into
 | |
| +         * the Finished digest again. */
 | |
| +        n = s->init_num;
 | |
| +    }
 | |
| +
 | |
|      d = p = (unsigned char *)s->init_msg;
 | |
|  
 | |
|      /*
 | |
| @@ -1041,15 +1056,26 @@ int ssl3_get_client_hello(SSL *s)
 | |
|          if (i == 1 && s->version == s->session->ssl_version) { /* previous
 | |
|                                                                  * session */
 | |
|              s->hit = 1;
 | |
| -        } else if (i == -1)
 | |
| +        } else if (i == -1) {
 | |
| +            goto err;
 | |
| +        } else if (i == PENDING_SESSION) {
 | |
| +            ret = PENDING_SESSION;
 | |
|              goto err;
 | |
| -        else {                  /* i == 0 */
 | |
| +        } else {                /* i == 0 */
 | |
|  
 | |
|              if (!ssl_get_new_session(s, 1))
 | |
|                  goto err;
 | |
|          }
 | |
|      }
 | |
|  
 | |
| +    /*
 | |
| +     * Switch to server state ClientHello C once the session lookup
 | |
| +     * is finished so it can proceed with original state loop.
 | |
| +     */
 | |
| +    if (s->state == SSL3_ST_SR_CLNT_HELLO_D) {
 | |
| +        s->state = SSL3_ST_SR_CLNT_HELLO_C;
 | |
| +    }
 | |
| +
 | |
|      p += j;
 | |
|  
 | |
|      if (SSL_IS_DTLS(s)) {
 | |
| diff -urp openssl-1.0.2h/ssl/ssl3.h openssl-1.0.2h-patched/ssl/ssl3.h
 | |
| --- openssl-1.0.2h/ssl/ssl3.h	2016-05-03 06:44:42.000000000 -0700
 | |
| +++ openssl-1.0.2h-patched/ssl/ssl3.h	2016-07-19 19:15:54.117778328 -0700
 | |
| @@ -698,6 +698,7 @@ typedef struct ssl3_state_st {
 | |
|  # define SSL3_ST_SR_CLNT_HELLO_B         (0x111|SSL_ST_ACCEPT)
 | |
|  # define SSL3_ST_SR_CLNT_HELLO_C         (0x112|SSL_ST_ACCEPT)
 | |
|  # define SSL3_ST_SR_CLNT_HELLO_D         (0x115|SSL_ST_ACCEPT)
 | |
| +# define SSL3_ST_SR_CLNT_HELLO_E         (0x116|SSL_ST_ACCEPT)
 | |
|  /* write to client */
 | |
|  # define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
 | |
|  # define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
 | |
| diff -urp openssl-1.0.2h/ssl/ssl.h openssl-1.0.2h-patched/ssl/ssl.h
 | |
| --- openssl-1.0.2h/ssl/ssl.h	2016-05-03 06:44:42.000000000 -0700
 | |
| +++ openssl-1.0.2h-patched/ssl/ssl.h	2016-07-19 19:19:44.699562938 -0700
 | |
| @@ -1243,6 +1243,13 @@ void SSL_CTX_sess_set_get_cb(SSL_CTX *ct
 | |
|  SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl,
 | |
|                                                         unsigned char *Data,
 | |
|                                                         int len, int *copy);
 | |
| +
 | |
| +/* SSL_magic_pending_session_ptr returns a magic SSL_SESSION* which indicates
 | |
| + * that the session isn't currently unavailable. SSL_get_error will then return
 | |
| + * SSL_ERROR_PENDING_SESSION and the handshake can be retried later when the
 | |
| + * lookup has completed. */
 | |
| +SSL_SESSION *SSL_magic_pending_session_ptr(void);
 | |
| +
 | |
|  void SSL_CTX_set_info_callback(SSL_CTX *ctx,
 | |
|                                 void (*cb) (const SSL *ssl, int type,
 | |
|                                             int val));
 | |
| @@ -1408,11 +1415,14 @@ int SSL_extension_supported(unsigned int
 | |
|  # define SSL_READING     3
 | |
|  # define SSL_X509_LOOKUP 4
 | |
|  
 | |
| +# define SSL_PENDING_SESSION 7
 | |
| +
 | |
|  /* These will only be used when doing non-blocking IO */
 | |
|  # define SSL_want_nothing(s)     (SSL_want(s) == SSL_NOTHING)
 | |
|  # define SSL_want_read(s)        (SSL_want(s) == SSL_READING)
 | |
|  # define SSL_want_write(s)       (SSL_want(s) == SSL_WRITING)
 | |
|  # define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
 | |
| +# define SSL_want_session(s)     (SSL_want(s) == SSL_PENDING_SESSION)
 | |
|  
 | |
|  # define SSL_MAC_FLAG_READ_MAC_STREAM 1
 | |
|  # define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
 | |
| @@ -1865,6 +1875,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 | |
|  # define SSL_ERROR_ZERO_RETURN           6
 | |
|  # define SSL_ERROR_WANT_CONNECT          7
 | |
|  # define SSL_ERROR_WANT_ACCEPT           8
 | |
| +# define SSL_ERROR_PENDING_SESSION       11
 | |
|  # define SSL_CTRL_NEED_TMP_RSA                   1
 | |
|  # define SSL_CTRL_SET_TMP_RSA                    2
 | |
|  # define SSL_CTRL_SET_TMP_DH                     3
 | |
| diff -urp openssl-1.0.2h/ssl/ssl_lib.c openssl-1.0.2h-patched/ssl/ssl_lib.c
 | |
| --- openssl-1.0.2h/ssl/ssl_lib.c	2016-05-03 06:44:42.000000000 -0700
 | |
| +++ openssl-1.0.2h-patched/ssl/ssl_lib.c	2016-07-19 19:21:04.032021549 -0700
 | |
| @@ -2709,6 +2709,9 @@ int SSL_get_error(const SSL *s, int i)
 | |
|              return (SSL_ERROR_SSL);
 | |
|      }
 | |
|  
 | |
| +    if ((i < 0) && SSL_want_session(s))
 | |
| +        return (SSL_ERROR_PENDING_SESSION);
 | |
| +
 | |
|      if ((i < 0) && SSL_want_read(s)) {
 | |
|          bio = SSL_get_rbio(s);
 | |
|          if (BIO_should_read(bio))
 | |
| diff -urp openssl-1.0.2h/ssl/ssl_locl.h openssl-1.0.2h-patched/ssl/ssl_locl.h
 | |
| --- openssl-1.0.2h/ssl/ssl_locl.h	2016-05-03 06:44:42.000000000 -0700
 | |
| +++ openssl-1.0.2h-patched/ssl/ssl_locl.h	2016-07-19 19:15:54.117778328 -0700
 | |
| @@ -518,6 +518,8 @@
 | |
|  #define CERT_PRIVATE_KEY        2
 | |
|  */
 | |
|  
 | |
| +# define PENDING_SESSION        -10000
 | |
| +
 | |
|  # ifndef OPENSSL_NO_EC
 | |
|  /*
 | |
|   * From ECC-TLS draft, used in encoding the curve type in ECParameters
 | |
| diff -urp openssl-1.0.2h/ssl/ssl_sess.c openssl-1.0.2h-patched/ssl/ssl_sess.c
 | |
| --- openssl-1.0.2h/ssl/ssl_sess.c	2016-05-03 06:44:42.000000000 -0700
 | |
| +++ openssl-1.0.2h-patched/ssl/ssl_sess.c	2016-07-19 19:15:54.118778298 -0700
 | |
| @@ -143,10 +143,20 @@
 | |
|  #endif
 | |
|  #include "ssl_locl.h"
 | |
|  
 | |
| +/* The address of this is a magic value, a pointer to which is returned by
 | |
| + * SSL_magic_pending_session_ptr(). It allows a session callback to indicate
 | |
| + * that it needs to asynchronously fetch session information. */
 | |
| +static char g_pending_session_magic;
 | |
| +
 | |
|  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);
 | |
|  
 | |
| +SSL_SESSION *SSL_magic_pending_session_ptr()
 | |
| +{
 | |
| +    return (SSL_SESSION*) &g_pending_session_magic;
 | |
| +}
 | |
| +
 | |
|  SSL_SESSION *SSL_get_session(const SSL *ssl)
 | |
|  /* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
 | |
|  {
 | |
| @@ -626,6 +636,12 @@ int ssl_get_prev_session(SSL *s, unsigne
 | |
|          int copy = 1;
 | |
|  
 | |
|          if ((ret = s->session_ctx->get_session_cb(s, session_id, len, ©))) {
 | |
| +            if (ret == SSL_magic_pending_session_ptr()) {
 | |
| +                /* This is a magic value which indicates that
 | |
| +                 * the callback needs to unwind the stack and
 | |
| +                 * figure out the session asynchronously. */
 | |
| +                return PENDING_SESSION;
 | |
| +            }
 | |
|              s->session_ctx->stats.sess_cb_hit++;
 | |
|  
 | |
|              /*
 | |
| diff -urp openssl-1.0.2h/ssl/ssl_stat.c openssl-1.0.2h-patched/ssl/ssl_stat.c
 | |
| --- openssl-1.0.2h/ssl/ssl_stat.c	2016-05-03 06:44:42.000000000 -0700
 | |
| +++ openssl-1.0.2h-patched/ssl/ssl_stat.c	2016-07-19 19:15:54.118778298 -0700
 | |
| @@ -353,6 +353,12 @@ const char *SSL_state_string_long(const
 | |
|      case SSL3_ST_SR_CLNT_HELLO_C:
 | |
|          str = "SSLv3 read client hello C";
 | |
|          break;
 | |
| +    case SSL3_ST_SR_CLNT_HELLO_D:
 | |
| +        str = "SSLv3 read client hello D";
 | |
| +        break;
 | |
| +    case SSL3_ST_SR_CLNT_HELLO_E:
 | |
| +        str = "SSLv3 read client hello E";
 | |
| +        break;
 | |
|      case SSL3_ST_SW_HELLO_REQ_A:
 | |
|          str = "SSLv3 write hello request A";
 | |
|          break;
 | |
| @@ -737,6 +743,12 @@ const char *SSL_state_string(const SSL *
 | |
|      case SSL3_ST_SR_CLNT_HELLO_C:
 | |
|          str = "3RCH_C";
 | |
|          break;
 | |
| +    case SSL3_ST_SR_CLNT_HELLO_D:
 | |
| +        str = "3RCH_D";
 | |
| +        break;
 | |
| +    case SSL3_ST_SR_CLNT_HELLO_E:
 | |
| +        str = "3RCH_E";
 | |
| +        break;
 | |
|      case SSL3_ST_SW_SRVR_HELLO_A:
 | |
|          str = "3WSH_A";
 | |
|          break;
 |