Update from stable branch.

This commit is contained in:
Dr. Stephen Henson 2008-04-30 16:14:02 +00:00
parent 2f63ad5b35
commit 8a2062fefe
6 changed files with 88 additions and 30 deletions

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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) \

View file

@ -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

View file

@ -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 */