提交 661dc143 编写于 作者: D Dr. Stephen Henson

Fix statless session resumption so it can coexist with SNI

上级 213f08a6
...@@ -4,6 +4,15 @@ ...@@ -4,6 +4,15 @@
Changes between 0.9.8k and 1.0 [xx XXX xxxx] Changes between 0.9.8k and 1.0 [xx XXX xxxx]
*) Fixes to stateless session resumption handling. Use initial_ctx when
issuing and attempting to decrypt tickets in case it has changed during
servername handling. Use a non-zero length session ID when attempting
stateless session resumption: this makes it possible to determine if
a resumption has occurred immediately after receiving server hello
(several places in OpenSSL subtly assume this) instead of later in
the handshake.
[Steve Henson]
*) Update OCSP request code to permit adding custom headers to the request: *) Update OCSP request code to permit adding custom headers to the request:
some responders need this. some responders need this.
[Steve Henson] [Steve Henson]
......
...@@ -2973,6 +2973,7 @@ int ssl3_send_newsession_ticket(SSL *s) ...@@ -2973,6 +2973,7 @@ int ssl3_send_newsession_ticket(SSL *s)
unsigned int hlen; unsigned int hlen;
EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX ctx;
HMAC_CTX hctx; HMAC_CTX hctx;
SSL_CTX *tctx = s->initial_ctx;
unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char key_name[16]; unsigned char key_name[16];
...@@ -3011,9 +3012,9 @@ int ssl3_send_newsession_ticket(SSL *s) ...@@ -3011,9 +3012,9 @@ int ssl3_send_newsession_ticket(SSL *s)
* it does all the work otherwise use generated values * it does all the work otherwise use generated values
* from parent ctx. * from parent ctx.
*/ */
if (s->ctx->tlsext_ticket_key_cb) if (tctx->tlsext_ticket_key_cb)
{ {
if (s->ctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
&hctx, 1) < 0) &hctx, 1) < 0)
{ {
OPENSSL_free(senc); OPENSSL_free(senc);
...@@ -3024,10 +3025,10 @@ int ssl3_send_newsession_ticket(SSL *s) ...@@ -3024,10 +3025,10 @@ int ssl3_send_newsession_ticket(SSL *s)
{ {
RAND_pseudo_bytes(iv, 16); RAND_pseudo_bytes(iv, 16);
EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
s->ctx->tlsext_tick_aes_key, iv); tctx->tlsext_tick_aes_key, iv);
HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16, HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
tlsext_tick_md(), NULL); tlsext_tick_md(), NULL);
memcpy(key_name, s->ctx->tlsext_tick_key_name, 16); memcpy(key_name, tctx->tlsext_tick_key_name, 16);
} }
l2n(s->session->tlsext_tick_lifetime_hint, p); l2n(s->session->tlsext_tick_lifetime_hint, p);
/* Skip ticket length for now */ /* Skip ticket length for now */
......
...@@ -579,19 +579,26 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, ...@@ -579,19 +579,26 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
ret->tlsext_ticklen = os.length; ret->tlsext_ticklen = os.length;
os.data = NULL; os.data = NULL;
os.length = 0; os.length = 0;
#if 0
/* There are two ways to detect a resumed ticket sesion. /* There are two ways to detect a resumed ticket sesion.
* One is to set a random session ID and then the server * One is to set a random session ID and then the server
* must return a match in ServerHello. This allows the normal * must return a match in ServerHello. This allows the normal
* client session ID matching to work. * client session ID matching to work and we know much
* earlier that the ticket has been accepted.
*
* The other way is to set zero length session ID when the
* ticket is presented and rely on the handshake to determine
* session resumption.
*/ */
if (ret->session_id_length == 0) if (ret->session_id_length == 0)
{ {
ret->session_id_length=SSL3_MAX_SSL_SESSION_ID_LENGTH; EVP_Digest(ret->tlsext_tick, ret->tlsext_ticklen,
RAND_pseudo_bytes(ret->session_id, ret->session_id, &ret->session_id_length,
ret->session_id_length); #ifndef OPENSSL_NO_SHA256
} EVP_sha256(), NULL);
#else
EVP_sha1(), NULL);
#endif #endif
}
} }
else else
ret->tlsext_tick=NULL; ret->tlsext_tick=NULL;
......
...@@ -1516,16 +1516,17 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, ...@@ -1516,16 +1516,17 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
unsigned char tick_hmac[EVP_MAX_MD_SIZE]; unsigned char tick_hmac[EVP_MAX_MD_SIZE];
HMAC_CTX hctx; HMAC_CTX hctx;
EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX ctx;
SSL_CTX *tctx = s->initial_ctx;
/* Need at least keyname + iv + some encrypted data */ /* Need at least keyname + iv + some encrypted data */
if (eticklen < 48) if (eticklen < 48)
goto tickerr; goto tickerr;
/* Initialize session ticket encryption and HMAC contexts */ /* Initialize session ticket encryption and HMAC contexts */
HMAC_CTX_init(&hctx); HMAC_CTX_init(&hctx);
EVP_CIPHER_CTX_init(&ctx); EVP_CIPHER_CTX_init(&ctx);
if (s->ctx->tlsext_ticket_key_cb) if (tctx->tlsext_ticket_key_cb)
{ {
unsigned char *nctick = (unsigned char *)etick; unsigned char *nctick = (unsigned char *)etick;
int rv = s->ctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
&ctx, &hctx, 0); &ctx, &hctx, 0);
if (rv < 0) if (rv < 0)
return -1; return -1;
...@@ -1537,12 +1538,12 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, ...@@ -1537,12 +1538,12 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
else else
{ {
/* Check key name matches */ /* Check key name matches */
if (memcmp(etick, s->ctx->tlsext_tick_key_name, 16)) if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
goto tickerr; goto tickerr;
HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16, HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
tlsext_tick_md(), NULL); tlsext_tick_md(), NULL);
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
s->ctx->tlsext_tick_aes_key, etick + 16); tctx->tlsext_tick_aes_key, etick + 16);
} }
/* Attempt to process session ticket, first conduct sanity and /* Attempt to process session ticket, first conduct sanity and
* integrity checks on ticket. * integrity checks on ticket.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册