Update from stable branch.
This commit is contained in:
parent
2f63ad5b35
commit
8a2062fefe
6 changed files with 88 additions and 30 deletions
6
CHANGES
6
CHANGES
|
@ -680,6 +680,12 @@
|
|||
[NTT]
|
||||
|
||||
Changes between 0.9.8g and 0.9.8h [xx XXX xxxx]
|
||||
|
||||
*) Add TLS session ticket callback. This allows an application to set
|
||||
TLS ticket cipher and HMAC keys rather than relying on hardcoded fixed
|
||||
values. This is useful for key rollover for example where several key
|
||||
sets may exist with different names.
|
||||
[Steve Henson]
|
||||
|
||||
*) Reverse ENGINE-internal logic for caching default ENGINE handles.
|
||||
This was broken until now in 0.9.8 releases, such that the only way
|
||||
|
|
|
@ -2770,6 +2770,13 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
|
|||
ctx->tlsext_status_cb=(int (*)(SSL *,void *))fp;
|
||||
break;
|
||||
|
||||
case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB:
|
||||
ctx->tlsext_ticket_key_cb=(int (*)(SSL *,unsigned char *,
|
||||
unsigned char *,
|
||||
EVP_CIPHER_CTX *,
|
||||
HMAC_CTX *, int))fp;
|
||||
break;
|
||||
|
||||
#endif
|
||||
default:
|
||||
return(0);
|
||||
|
|
|
@ -2853,6 +2853,8 @@ int ssl3_send_newsession_ticket(SSL *s)
|
|||
unsigned int hlen;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
HMAC_CTX hctx;
|
||||
unsigned char iv[EVP_MAX_IV_LENGTH];
|
||||
unsigned char key_name[16];
|
||||
|
||||
/* get session encoding length */
|
||||
slen = i2d_SSL_SESSION(s->session, NULL);
|
||||
|
@ -2883,29 +2885,47 @@ int ssl3_send_newsession_ticket(SSL *s)
|
|||
*(p++)=SSL3_MT_NEWSESSION_TICKET;
|
||||
/* Skip message length for now */
|
||||
p += 3;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
HMAC_CTX_init(&hctx);
|
||||
/* Initialize HMAC and cipher contexts. If callback present
|
||||
* it does all the work otherwise use generated values
|
||||
* from parent ctx.
|
||||
*/
|
||||
if (s->ctx->tlsext_ticket_key_cb)
|
||||
{
|
||||
if (s->ctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
|
||||
&hctx, 1) < 0)
|
||||
{
|
||||
OPENSSL_free(senc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RAND_pseudo_bytes(iv, 16);
|
||||
EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
|
||||
s->ctx->tlsext_tick_aes_key, iv);
|
||||
HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16,
|
||||
tlsext_tick_md(), NULL);
|
||||
memcpy(key_name, s->ctx->tlsext_tick_key_name, 16);
|
||||
}
|
||||
l2n(s->session->tlsext_tick_lifetime_hint, p);
|
||||
/* Skip ticket length for now */
|
||||
p += 2;
|
||||
/* Output key name */
|
||||
macstart = p;
|
||||
memcpy(p, s->ctx->tlsext_tick_key_name, 16);
|
||||
memcpy(p, key_name, 16);
|
||||
p += 16;
|
||||
/* Generate and output IV */
|
||||
RAND_pseudo_bytes(p, 16);
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
/* output IV */
|
||||
memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx));
|
||||
p += EVP_CIPHER_CTX_iv_length(&ctx);
|
||||
/* Encrypt session data */
|
||||
EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
|
||||
s->ctx->tlsext_tick_aes_key, p);
|
||||
p += 16;
|
||||
EVP_EncryptUpdate(&ctx, p, &len, senc, slen);
|
||||
p += len;
|
||||
EVP_EncryptFinal(&ctx, p, &len);
|
||||
p += len;
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
|
||||
HMAC_CTX_init(&hctx);
|
||||
HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16,
|
||||
tlsext_tick_md(), NULL);
|
||||
HMAC_Update(&hctx, macstart, p - macstart);
|
||||
HMAC_Final(&hctx, p, &hlen);
|
||||
HMAC_CTX_cleanup(&hctx);
|
||||
|
|
|
@ -160,6 +160,7 @@
|
|||
#include <openssl/buffer.h>
|
||||
#endif
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#include <openssl/kssl.h>
|
||||
#include <openssl/safestack.h>
|
||||
|
@ -807,6 +808,11 @@ struct ssl_ctx_st
|
|||
unsigned char tlsext_tick_key_name[16];
|
||||
unsigned char tlsext_tick_hmac_key[16];
|
||||
unsigned char tlsext_tick_aes_key[16];
|
||||
/* Callback to support customisation of ticket key setting */
|
||||
int (*tlsext_ticket_key_cb)(SSL *ssl,
|
||||
unsigned char *name, unsigned char *iv,
|
||||
EVP_CIPHER_CTX *ectx,
|
||||
HMAC_CTX *hctx, int enc);
|
||||
|
||||
/* certificate status request info */
|
||||
/* Callback for status request */
|
||||
|
@ -1351,6 +1357,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
|||
#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69
|
||||
#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70
|
||||
#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71
|
||||
|
||||
#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72
|
||||
#endif
|
||||
|
||||
#define SSL_session_reused(ssl) \
|
||||
|
|
54
ssl/t1_lib.c
54
ssl/t1_lib.c
|
@ -1442,39 +1442,53 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
|
|||
SSL_SESSION *sess;
|
||||
unsigned char *sdec;
|
||||
const unsigned char *p;
|
||||
int slen, mlen;
|
||||
int slen, mlen, renew_ticket = 0;
|
||||
unsigned char tick_hmac[EVP_MAX_MD_SIZE];
|
||||
HMAC_CTX hctx;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
/* Attempt to process session ticket, first conduct sanity and
|
||||
* integrity checks on ticket.
|
||||
*/
|
||||
mlen = EVP_MD_size(tlsext_tick_md());
|
||||
eticklen -= mlen;
|
||||
/* Need at least keyname + iv + some encrypted data */
|
||||
if (eticklen < 48)
|
||||
goto tickerr;
|
||||
/* Check key name matches */
|
||||
if (memcmp(etick, s->ctx->tlsext_tick_key_name, 16))
|
||||
goto tickerr;
|
||||
/* Check HMAC of encrypted ticket */
|
||||
/* Initialize session ticket encryption and HMAC contexts */
|
||||
HMAC_CTX_init(&hctx);
|
||||
HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16,
|
||||
tlsext_tick_md(), NULL);
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
if (s->ctx->tlsext_ticket_key_cb)
|
||||
{
|
||||
unsigned char *nctick = (unsigned char *)etick;
|
||||
int rv = s->ctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
|
||||
&ctx, &hctx, 0);
|
||||
if (rv < 0)
|
||||
return -1;
|
||||
if (rv == 0)
|
||||
goto tickerr;
|
||||
if (rv == 2)
|
||||
renew_ticket = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check key name matches */
|
||||
if (memcmp(etick, s->ctx->tlsext_tick_key_name, 16))
|
||||
goto tickerr;
|
||||
HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16,
|
||||
tlsext_tick_md(), NULL);
|
||||
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
|
||||
s->ctx->tlsext_tick_aes_key, etick + 16);
|
||||
}
|
||||
/* Attempt to process session ticket, first conduct sanity and
|
||||
* integrity checks on ticket.
|
||||
*/
|
||||
mlen = HMAC_size(&hctx);
|
||||
eticklen -= mlen;
|
||||
/* Check HMAC of encrypted ticket */
|
||||
HMAC_Update(&hctx, etick, eticklen);
|
||||
HMAC_Final(&hctx, tick_hmac, NULL);
|
||||
HMAC_CTX_cleanup(&hctx);
|
||||
if (memcmp(tick_hmac, etick + eticklen, mlen))
|
||||
goto tickerr;
|
||||
/* Set p to start of IV */
|
||||
p = etick + 16;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
/* Attempt to decrypt session data */
|
||||
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
|
||||
s->ctx->tlsext_tick_aes_key, p);
|
||||
/* Move p after IV to start of encrypted ticket, update length */
|
||||
p += 16;
|
||||
eticklen -= 32;
|
||||
p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
|
||||
eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
|
||||
sdec = OPENSSL_malloc(eticklen);
|
||||
if (!sdec)
|
||||
{
|
||||
|
@ -1501,7 +1515,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
|
|||
memcpy(sess->session_id, sess_id, sesslen);
|
||||
sess->session_id_length = sesslen;
|
||||
*psess = sess;
|
||||
s->tlsext_ticket_expected = 0;
|
||||
s->tlsext_ticket_expected = renew_ticket;
|
||||
return 1;
|
||||
}
|
||||
/* If session decrypt failure indicate a cache miss and set state to
|
||||
|
|
|
@ -279,6 +279,9 @@ SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(voi
|
|||
#define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)
|
||||
|
||||
#define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
|
||||
SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
|
||||
|
||||
#endif
|
||||
|
||||
/* PSK ciphersuites from 4279 */
|
||||
|
|
Loading…
Reference in a new issue