Loading CHANGES +6 −0 Original line number Diff line number Diff line Loading @@ -681,6 +681,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 Loading ssl/s3_lib.c +7 −0 Original line number Diff line number Diff line Loading @@ -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); Loading ssl/s3_srvr.c +30 −10 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading ssl/ssl.h +8 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 */ Loading Loading @@ -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) \ Loading ssl/t1_lib.c +33 −19 Original line number Diff line number Diff line Loading @@ -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; /* Initialize session ticket encryption and HMAC contexts */ HMAC_CTX_init(&hctx); 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; /* Check HMAC of encrypted ticket */ HMAC_CTX_init(&hctx); 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) { Loading @@ -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 Loading Loading
CHANGES +6 −0 Original line number Diff line number Diff line Loading @@ -681,6 +681,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 Loading
ssl/s3_lib.c +7 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
ssl/s3_srvr.c +30 −10 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading
ssl/ssl.h +8 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 */ Loading Loading @@ -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) \ Loading
ssl/t1_lib.c +33 −19 Original line number Diff line number Diff line Loading @@ -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; /* Initialize session ticket encryption and HMAC contexts */ HMAC_CTX_init(&hctx); 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; /* Check HMAC of encrypted ticket */ HMAC_CTX_init(&hctx); 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) { Loading @@ -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 Loading