TLS ticket key setting callback: this allows and application to set
its own TLS ticket keys.
This commit is contained in:
parent
8831eb7624
commit
db533c96e3
6
CHANGES
6
CHANGES
@ -4,6 +4,12 @@
|
||||
|
||||
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
|
||||
a registered ENGINE could be used (assuming it initialises
|
||||
|
@ -2255,6 +2255,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);
|
||||
|
@ -2703,6 +2703,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);
|
||||
@ -2733,29 +2735,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);
|
||||
|
10
ssl/ssl.h
10
ssl/ssl.h
@ -187,6 +187,7 @@
|
||||
#include <openssl/buffer.h>
|
||||
#endif
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#include <openssl/kssl.h>
|
||||
#include <openssl/safestack.h>
|
||||
@ -767,7 +768,12 @@ 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 */
|
||||
int (*tlsext_status_cb)(SSL *ssl, void *arg);
|
||||
@ -1252,6 +1258,8 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
|
||||
#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
@ -788,39 +788,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)
|
||||
{
|
||||
@ -847,7 +861,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
|
||||
|
@ -179,6 +179,9 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb)
|
||||
#define SSL_CTX_set_tlsext_status_arg(ssl, arg) \
|
||||
SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)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
|
||||
|
||||
/* Additional TLS ciphersuites from draft-ietf-tls-56-bit-ciphersuites-00.txt
|
||||
|
Loading…
x
Reference in New Issue
Block a user