summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/man3/SSL_CTX_set_tlsext_ticket_key_cb.pod67
-rw-r--r--include/openssl/ssl.h4
-rw-r--r--include/openssl/tls1.h7
-rw-r--r--ssl/s3_lib.c10
-rw-r--r--ssl/ssl_local.h32
-rw-r--r--ssl/statem/statem_srvr.c47
-rw-r--r--ssl/t1_lib.c160
-rw-r--r--test/bad_dtls_test.c34
-rw-r--r--test/handshake_helper.c14
-rw-r--r--test/sslapitest.c68
-rw-r--r--util/libssl.num1
11 files changed, 375 insertions, 69 deletions
diff --git a/doc/man3/SSL_CTX_set_tlsext_ticket_key_cb.pod b/doc/man3/SSL_CTX_set_tlsext_ticket_key_cb.pod
index 88e70c5fa2..ae812097c5 100644
--- a/doc/man3/SSL_CTX_set_tlsext_ticket_key_cb.pod
+++ b/doc/man3/SSL_CTX_set_tlsext_ticket_key_cb.pod
@@ -2,20 +2,31 @@
=head1 NAME
-SSL_CTX_set_tlsext_ticket_key_cb - set a callback for session ticket processing
+SSL_CTX_set_tlsext_ticket_key_evp_cb,
+SSL_CTX_set_tlsext_ticket_key_cb
+- set a callback for session ticket processing
=head1 SYNOPSIS
#include <openssl/tls1.h>
- long SSL_CTX_set_tlsext_ticket_key_cb(SSL_CTX sslctx,
+ int SSL_CTX_set_tlsext_ticket_key_evp_cb(SSL_CTX sslctx,
+ int (*cb)(SSL *s, unsigned char key_name[16],
+ unsigned char iv[EVP_MAX_IV_LENGTH],
+ EVP_CIPHER_CTX *ctx, EVP_MAC_CTX *hctx, int enc));
+
+Deprecated since OpenSSL 3.0, can be hidden entirely by defining
+B<OPENSSL_API_COMPAT> with a suitable version value, see
+L<openssl_user_macros(7)>:
+
+ int SSL_CTX_set_tlsext_ticket_key_cb(SSL_CTX sslctx,
int (*cb)(SSL *s, unsigned char key_name[16],
unsigned char iv[EVP_MAX_IV_LENGTH],
EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc));
=head1 DESCRIPTION
-SSL_CTX_set_tlsext_ticket_key_cb() sets a callback function I<cb> for handling
+SSL_CTX_set_tlsext_ticket_key_evp_cb() sets a callback function I<cb> for handling
session tickets for the ssl context I<sslctx>. Session tickets, defined in
RFC5077 provide an enhanced session resumption capability where the server
implementation is not required to maintain per session state. It only applies
@@ -38,7 +49,8 @@ ticket information or it starts a full TLS handshake to create a new session
ticket.
Before the callback function is started I<ctx> and I<hctx> have been
-initialised with L<EVP_CIPHER_CTX_reset(3)> and L<HMAC_CTX_reset(3)> respectively.
+initialised with L<EVP_CIPHER_CTX_reset(3)> and L<EVP_MAC_CTX_new(3)>
+respectively.
For new sessions tickets, when the client doesn't present a session ticket, or
an attempted retrieval of the ticket failed, or a renew option was indicated,
@@ -53,8 +65,9 @@ maximum IV length is B<EVP_MAX_IV_LENGTH> bytes defined in B<evp.h>.
The initialization vector I<iv> should be a random value. The cipher context
I<ctx> should use the initialisation vector I<iv>. The cipher context can be
-set using L<EVP_EncryptInit_ex(3)>. The hmac context can be set using
-L<HMAC_Init_ex(3)>.
+set using L<EVP_EncryptInit_ex(3)>. The hmac context and digest can be set using
+L<EVP_MAC_CTX_set_params(3)> with the B<OSSL_MAC_PARAM_KEY> and
+B<OSSL_MAC_PARAM_DIGEST> parameters respectively.
When the client presents a session ticket, the callback function with be called
with I<enc> set to 0 indicating that the I<cb> function should retrieve a set
@@ -62,8 +75,9 @@ of parameters. In this case I<name> and I<iv> have already been parsed out of
the session ticket. The OpenSSL library expects that the I<name> will be used
to retrieve a cryptographic parameters and that the cryptographic context
I<ctx> will be set with the retrieved parameters and the initialization vector
-I<iv>. using a function like L<EVP_DecryptInit_ex(3)>. The I<hctx> needs to be
-set using L<HMAC_Init_ex(3)>.
+I<iv>. using a function like L<EVP_DecryptInit_ex(3)>. The key material and
+digest for I<hctx> need to be set using L<EVP_MAC_CTX_set_params(3)> with the
+B<OSSL_MAC_PARAM_KEY> and B<OSSL_MAC_PARAM_DIGEST> parameters respectively.
If the I<name> is still valid but a renewal of the ticket is required the
callback function should return 2. The library will call the callback again
@@ -102,6 +116,14 @@ This indicates an error.
=back
+The SSL_CTX_set_tlsext_ticket_key_cb() function is identical to
+SSL_CTX_set_tlsext_ticket_key_evp_cb() except that it takes a deprecated
+HMAC_CTX pointer instead of an EVP_MAC_CTX one.
+Before this callback function is started I<hctx> will have been
+initialised with L<EVP_MAC_CTX_new(3)> and the digest set with
+L<EVP_MAC_CTX_set_params(3)>.
+The I<hctx> key material can be set using L<HMAC_Init_ex(3)>.
+
=head1 NOTES
Session resumption shortcuts the TLS so that the client certificate
@@ -129,13 +151,15 @@ returns 0 to indicate the callback function was set.
Reference Implementation:
- SSL_CTX_set_tlsext_ticket_key_cb(SSL, ssl_tlsext_ticket_key_cb);
+ SSL_CTX_set_tlsext_ticket_key_evp_cb(SSL, ssl_tlsext_ticket_key_cb);
...
static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16],
unsigned char *iv, EVP_CIPHER_CTX *ctx,
- HMAC_CTX *hctx, int enc)
+ EVP_MAC_CTX *hctx, int enc)
{
+ OSSL_PARAM params[3];
+
if (enc) { /* create new session */
if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) <= 0)
return -1; /* insufficient random */
@@ -155,7 +179,13 @@ Reference Implementation:
memcpy(key_name, key->name, 16);
EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key->aes_key, iv);
- HMAC_Init_ex(&hctx, key->hmac_key, 16, EVP_sha256(), NULL);
+
+ params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+ key->hmac_key, 16);
+ params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ "sha256", 0);
+ params[2] = OSSL_PARAM_construct_end();
+ EVP_MAC_CTX_set_params(hctx, params);
return 1;
@@ -165,7 +195,13 @@ Reference Implementation:
if (key == NULL || key->expire < now())
return 0;
- HMAC_Init_ex(&hctx, key->hmac_key, 16, EVP_sha256(), NULL);
+ params[0] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
+ key->hmac_key, 16);
+ params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ "sha256", 0);
+ params[2] = OSSL_PARAM_construct_end();
+ EVP_MAC_CTX_set_params(hctx, params);
+
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key->aes_key, iv);
if (key->expire < now() - RENEW_TIME) {
@@ -188,6 +224,13 @@ L<SSL_CTX_sess_number(3)>,
L<SSL_CTX_sess_set_get_cb(3)>,
L<SSL_CTX_set_session_id_context(3)>,
+=head1 HISTORY
+
+The SSL_CTX_set_tlsext_ticket_key_cb() function was deprecated in OpenSSL 3.0.
+
+The SSL_CTX_set_tlsext_ticket_key_evp_cb() function was introduced in
+OpenSSL 3.0.
+
=head1 COPYRIGHT
Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved.
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 3b52f86412..c1b6b8e5dc 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1269,7 +1269,9 @@ 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
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+# define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72
+# endif
# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75
# define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76
# define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77
diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
index 9a1683e0fd..9181e0d2c1 100644
--- a/include/openssl/tls1.h
+++ b/include/openssl/tls1.h
@@ -327,9 +327,14 @@ __owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
# define SSL_CTX_get_tlsext_status_type(ssl) \
SSL_CTX_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE,0,NULL)
-# define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+# 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
+int SSL_CTX_set_tlsext_ticket_key_evp_cb
+ (SSL_CTX *ctx, int (*fp)(SSL *, unsigned char *, unsigned char *,
+ EVP_CIPHER_CTX *, EVP_MAC_CTX *, int));
/* PSK ciphersuites from 4279 */
# define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 745bccc836..a1a61cf328 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -4008,12 +4008,14 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
ctx->ext.status_cb = (int (*)(SSL *, void *))fp;
break;
+# ifndef OPENSSL_NO_DEPRECATED_3_0
case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB:
ctx->ext.ticket_key_cb = (int (*)(SSL *, unsigned char *,
unsigned char *,
EVP_CIPHER_CTX *,
HMAC_CTX *, int))fp;
break;
+#endif
#ifndef OPENSSL_NO_SRP
case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB:
@@ -4042,6 +4044,14 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
return 1;
}
+int SSL_CTX_set_tlsext_ticket_key_evp_cb
+ (SSL_CTX *ctx, int (*fp)(SSL *, unsigned char *, unsigned char *,
+ EVP_CIPHER_CTX *, EVP_MAC_CTX *, int))
+{
+ ctx->ext.ticket_key_evp_cb = fp;
+ return 1;
+}
+
const SSL_CIPHER *ssl3_get_cipher_by_id(uint32_t id)
{
SSL_CIPHER c;
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
index 43b0623a0b..680afa070a 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -737,6 +737,32 @@ typedef struct ssl_ctx_ext_secure_st {
unsigned char tick_aes_key[TLSEXT_TICK_KEY_LENGTH];
} SSL_CTX_EXT_SECURE;
+/*
+ * Helper function for HMAC
+ * The structure should be considered opaque, it will change once the low
+ * level deprecated calls are removed. At that point it can be replaced
+ * by EVP_MAC_CTX and most of the functions converted to macros or inlined
+ * directly.
+ */
+typedef struct ssl_hmac_st {
+ EVP_MAC_CTX *ctx;
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+ HMAC_CTX *old_ctx;
+# endif
+} SSL_HMAC;
+
+SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx);
+void ssl_hmac_free(SSL_HMAC *ctx);
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+HMAC_CTX *ssl_hmac_get0_HMAC_CTX(SSL_HMAC *ctx);
+# endif
+EVP_MAC_CTX *ssl_hmac_get0_EVP_MAC_CTX(SSL_HMAC *ctx);
+int ssl_hmac_init(SSL_HMAC *ctx, void *key, size_t len, char *md);
+int ssl_hmac_update(SSL_HMAC *ctx, const unsigned char *data, size_t len);
+int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len,
+ size_t max_size);
+size_t ssl_hmac_size(const SSL_HMAC *ctx);
+
struct ssl_ctx_st {
OPENSSL_CTX *libctx;
@@ -936,10 +962,16 @@ struct ssl_ctx_st {
/* RFC 4507 session ticket keys */
unsigned char tick_key_name[TLSEXT_KEYNAME_LENGTH];
SSL_CTX_EXT_SECURE *secure;
+# ifndef OPENSSL_NO_DEPRECATED_3_0
/* Callback to support customisation of ticket key setting */
int (*ticket_key_cb) (SSL *ssl,
unsigned char *name, unsigned char *iv,
EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc);
+#endif
+ int (*ticket_key_evp_cb) (SSL *ssl,
+ unsigned char *name, unsigned char *iv,
+ EVP_CIPHER_CTX *ectx, EVP_MAC_CTX *hctx,
+ int enc);
/* certificate status request info */
/* Callback for status request */
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index 4a18ad416d..50eaf69da4 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -18,7 +18,6 @@
#include <openssl/rand.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
-#include <openssl/hmac.h>
#include <openssl/x509.h>
#include <openssl/dh.h>
#include <openssl/bn.h>
@@ -3779,12 +3778,12 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add,
{
unsigned char *senc = NULL;
EVP_CIPHER_CTX *ctx = NULL;
- HMAC_CTX *hctx = NULL;
+ SSL_HMAC *hctx = NULL;
unsigned char *p, *encdata1, *encdata2, *macdata1, *macdata2;
const unsigned char *const_p;
int len, slen_full, slen, lenfinal;
SSL_SESSION *sess;
- unsigned int hlen;
+ size_t hlen;
SSL_CTX *tctx = s->session_ctx;
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char key_name[TLSEXT_KEYNAME_LENGTH];
@@ -3810,7 +3809,7 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add,
}
ctx = EVP_CIPHER_CTX_new();
- hctx = HMAC_CTX_new();
+ hctx = ssl_hmac_new(tctx);
if (ctx == NULL || hctx == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET,
ERR_R_MALLOC_FAILURE);
@@ -3856,10 +3855,24 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add,
* Initialize HMAC and cipher contexts. If callback present it does
* all the work otherwise use generated values from parent ctx.
*/
- if (tctx->ext.ticket_key_cb) {
- /* if 0 is returned, write an empty ticket */
- int ret = tctx->ext.ticket_key_cb(s, key_name, iv, ctx,
- hctx, 1);
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ if (tctx->ext.ticket_key_evp_cb != NULL || tctx->ext.ticket_key_cb != NULL)
+#else
+ if (tctx->ext.ticket_key_evp_cb != NULL)
+#endif
+ {
+ int ret = 0;
+
+ if (tctx->ext.ticket_key_evp_cb != NULL)
+ ret = tctx->ext.ticket_key_evp_cb(s, key_name, iv, ctx,
+ ssl_hmac_get0_EVP_MAC_CTX(hctx),
+ 1);
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ else if (tctx->ext.ticket_key_cb != NULL)
+ /* if 0 is returned, write an empty ticket */
+ ret = tctx->ext.ticket_key_cb(s, key_name, iv, ctx,
+ ssl_hmac_get0_HMAC_CTX(hctx), 1);
+#endif
if (ret == 0) {
@@ -3873,7 +3886,7 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add,
}
OPENSSL_free(senc);
EVP_CIPHER_CTX_free(ctx);
- HMAC_CTX_free(hctx);
+ ssl_hmac_free(hctx);
return 1;
}
if (ret < 0) {
@@ -3889,9 +3902,9 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add,
if (RAND_bytes_ex(s->ctx->libctx, iv, iv_len) <= 0
|| !EVP_EncryptInit_ex(ctx, cipher, NULL,
tctx->ext.secure->tick_aes_key, iv)
- || !HMAC_Init_ex(hctx, tctx->ext.secure->tick_hmac_key,
- sizeof(tctx->ext.secure->tick_hmac_key),
- EVP_sha256(), NULL)) {
+ || !ssl_hmac_init(hctx, tctx->ext.secure->tick_hmac_key,
+ sizeof(tctx->ext.secure->tick_hmac_key),
+ "SHA256")) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET,
ERR_R_INTERNAL_ERROR);
goto err;
@@ -3921,11 +3934,11 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add,
|| encdata1 + len != encdata2
|| len + lenfinal > slen + EVP_MAX_BLOCK_LENGTH
|| !WPACKET_get_total_written(pkt, &macendoffset)
- || !HMAC_Update(hctx,
- (unsigned char *)s->init_buf->data + macoffset,
- macendoffset - macoffset)
+ || !ssl_hmac_update(hctx,
+ (unsigned char *)s->init_buf->data + macoffset,
+ macendoffset - macoffset)
|| !WPACKET_reserve_bytes(pkt, EVP_MAX_MD_SIZE, &macdata1)
- || !HMAC_Final(hctx, macdata1, &hlen)
+ || !ssl_hmac_final(hctx, macdata1, &hlen, EVP_MAX_MD_SIZE)
|| hlen > EVP_MAX_MD_SIZE
|| !WPACKET_allocate_bytes(pkt, hlen, &macdata2)
|| macdata1 != macdata2) {
@@ -3945,7 +3958,7 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add,
err:
OPENSSL_free(senc);
EVP_CIPHER_CTX_free(ctx);
- HMAC_CTX_free(hctx);
+ ssl_hmac_free(hctx);
return ok;
}
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 0504f6bba1..fa2d6e0154 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -7,11 +7,15 @@
* https://www.openssl.org/source/license.html
*/
+/* We need access to the deprecated low level HMAC APIs */
+#define OPENSSL_SUPPRESS_DEPRECATED
+
#include <stdio.h>
#include <stdlib.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
+#include <openssl/core_names.h>
#include <openssl/ocsp.h>
#include <openssl/conf.h>
#include <openssl/x509v3.h>
@@ -1417,7 +1421,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick,
SSL_TICKET_STATUS ret = SSL_TICKET_FATAL_ERR_OTHER;
size_t mlen;
unsigned char tick_hmac[EVP_MAX_MD_SIZE];
- HMAC_CTX *hctx = NULL;
+ SSL_HMAC *hctx = NULL;
EVP_CIPHER_CTX *ctx = NULL;
SSL_CTX *tctx = s->session_ctx;
@@ -1447,7 +1451,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick,
}
/* Initialize session ticket encryption and HMAC contexts */
- hctx = HMAC_CTX_new();
+ hctx = ssl_hmac_new(tctx);
if (hctx == NULL) {
ret = SSL_TICKET_FATAL_ERR_MALLOC;
goto end;
@@ -1457,11 +1461,28 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick,
ret = SSL_TICKET_FATAL_ERR_MALLOC;
goto end;
}
- if (tctx->ext.ticket_key_cb) {
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ if (tctx->ext.ticket_key_evp_cb != NULL || tctx->ext.ticket_key_cb != NULL)
+#else
+ if (tctx->ext.ticket_key_evp_cb != NULL)
+#endif
+ {
unsigned char *nctick = (unsigned char *)etick;
- int rv = tctx->ext.ticket_key_cb(s, nctick,
+ int rv = 0;
+
+ if (tctx->ext.ticket_key_evp_cb != NULL)
+ rv = tctx->ext.ticket_key_evp_cb(s, nctick,
+ nctick + TLSEXT_KEYNAME_LENGTH,
+ ctx,
+ ssl_hmac_get0_EVP_MAC_CTX(hctx),
+ 0);
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ else if (tctx->ext.ticket_key_cb != NULL)
+ /* if 0 is returned, write an empty ticket */
+ rv = tctx->ext.ticket_key_cb(s, nctick,
nctick + TLSEXT_KEYNAME_LENGTH,
- ctx, hctx, 0);
+ ctx, ssl_hmac_get0_HMAC_CTX(hctx), 0);
+#endif
if (rv < 0) {
ret = SSL_TICKET_FATAL_ERR_OTHER;
goto end;
@@ -1479,9 +1500,9 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick,
ret = SSL_TICKET_NO_DECRYPT;
goto end;
}
- if (HMAC_Init_ex(hctx, tctx->ext.secure->tick_hmac_key,
- sizeof(tctx->ext.secure->tick_hmac_key),
- EVP_sha256(), NULL) <= 0
+ if (ssl_hmac_init(hctx, tctx->ext.secure->tick_hmac_key,
+ sizeof(tctx->ext.secure->tick_hmac_key),
+ "SHA256") <= 0
|| EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL,
tctx->ext.secure->tick_aes_key,
etick + TLSEXT_KEYNAME_LENGTH) <= 0) {
@@ -1495,7 +1516,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick,
* Attempt to process session ticket, first conduct sanity and integrity
* checks on ticket.
*/
- mlen = HMAC_size(hctx);
+ mlen = ssl_hmac_size(hctx);
if (mlen == 0) {
ret = SSL_TICKET_FATAL_ERR_OTHER;
goto end;
@@ -1509,8 +1530,8 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick,
}
eticklen -= mlen;
/* Check HMAC of encrypted ticket */
- if (HMAC_Update(hctx, etick, eticklen) <= 0
- || HMAC_Final(hctx, tick_hmac, NULL) <= 0) {
+ if (ssl_hmac_update(hctx, etick, eticklen) <= 0
+ || ssl_hmac_final(hctx, tick_hmac, NULL, sizeof(tick_hmac)) <= 0) {
ret = SSL_TICKET_FATAL_ERR_OTHER;
goto end;
}
@@ -1573,7 +1594,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick,
end:
EVP_CIPHER_CTX_free(ctx);
- HMAC_CTX_free(hctx);
+ ssl_hmac_free(hctx);
/*
* If set, the decrypt_ticket_cb() is called unless a fatal error was
@@ -2979,3 +3000,118 @@ uint8_t SSL_SESSION_get_max_fragment_length(const SSL_SESSION *session)
{
return session->ext.max_fragment_len_mode;
}
+
+/*
+ * Helper functions for HMAC access with legacy support included.
+ */
+SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx)
+{
+ SSL_HMAC *ret = OPENSSL_zalloc(sizeof(*ret));
+ EVP_MAC *mac = NULL;
+
+ if (ret == NULL)
+ return NULL;
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ if (ctx->ext.ticket_key_evp_cb == NULL
+ && ctx->ext.ticket_key_cb != NULL) {
+ ret->old_ctx = HMAC_CTX_new();
+ if (ret->old_ctx == NULL)
+ goto err;
+ return ret;
+ }
+#endif
+ mac = EVP_MAC_fetch(ctx->libctx, "HMAC", NULL);
+ if (mac == NULL || (ret->ctx = EVP_MAC_CTX_new(mac)) == NULL)
+ goto err;
+ EVP_MAC_free(mac);
+ return ret;
+ err:
+ EVP_MAC_CTX_free(ret->ctx);
+ EVP_MAC_free(mac);
+ OPENSSL_free(ret);
+ return NULL;
+}
+
+void ssl_hmac_free(SSL_HMAC *ctx)
+{
+ if (ctx != NULL) {
+ EVP_MAC_CTX_free(ctx->ctx);
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ HMAC_CTX_free(ctx->old_ctx);
+#endif
+ OPENSSL_free(ctx);
+ }
+}
+
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+HMAC_CTX *ssl_hmac_get0_HMAC_CTX(SSL_HMAC *ctx)
+{
+ return ctx->old_ctx;
+}
+#endif
+
+EVP_MAC_CTX *ssl_hmac_get0_EVP_MAC_CTX(SSL_HMAC *ctx)
+{
+ return ctx->ctx;
+}
+
+int ssl_hmac_init(SSL_HMAC *ctx, void *key, size_t len, char *md)
+{
+ OSSL_PARAM params[3], *p = params;
+
+ if (ctx->ctx != NULL) {
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, md, 0);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, key, len);
+ *p = OSSL_PARAM_construct_end();
+ if (EVP_MAC_CTX_set_params(ctx->ctx, params) && EVP_MAC_init(ctx->ctx))
+ return 1;
+ }
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ if (ctx->old_ctx != NULL)
+ return HMAC_Init_ex(ctx->old_ctx, key, len,
+ EVP_get_digestbyname(md), NULL);
+#endif
+ return 0;
+}
+
+int ssl_hmac_update(SSL_HMAC *ctx, const unsigned char *data, size_t len)
+{
+ if (ctx->ctx != NULL)
+ return EVP_MAC_update(ctx->ctx, data, len);
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ if (ctx->old_ctx != NULL)
+ return HMAC_Update(ctx->old_ctx, data, len);
+#endif
+ return 0;
+}
+
+int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len,
+ size_t max_size)
+{
+ if (ctx->ctx != NULL)
+ return EVP_MAC_final(ctx->ctx, md, len, max_size);
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ if (ctx->old_ctx != NULL) {
+ unsigned int l;
+
+ if (HMAC_Final(ctx->old_ctx, md, &l) > 0) {
+ if (len != NULL)
+ *len = l;
+ return 1;
+ }
+ }
+#endif
+ return 0;
+}
+
+size_t ssl_hmac_size(const SSL_HMAC *ctx)
+{
+ if (ctx->ctx != NULL)
+ return EVP_MAC_size(ctx->ctx);
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ if (ctx->old_ctx != NULL)
+ return HMAC_size(ctx->old_ctx);
+#endif
+ return 0;
+}
+
diff --git a/test/bad_dtls_test.c b/test/bad_dtls_test.c
index 66b5e1d2ed..9716b52193 100644
--- a/test/bad_dtls_test.c
+++ b/test/bad_dtls_test.c
@@ -29,6 +29,8 @@
*/
#include <string.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
#include <openssl/opensslconf.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
@@ -278,11 +280,13 @@ static int send_record(BIO *rbio, unsigned char type, uint64_t seqnr,
static unsigned char seq[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static unsigned char ver[2] = { 0x01, 0x00 }; /* DTLS1_BAD_VER */
unsigned char lenbytes[2];
- HMAC_CTX *ctx;
+ EVP_MAC *hmac;
+ EVP_MAC_CTX *ctx;
EVP_CIPHER_CTX *enc_ctx;
unsigned char iv[16];
unsigned char pad;
unsigned char *enc;
+ OSSL_PARAM params[3];
seq[0] = (seqnr >> 40) & 0xff;
seq[1] = (seqnr >> 32) & 0xff;
@@ -300,18 +304,26 @@ static int send_record(BIO *rbio, unsigned char type, uint64_t seqnr,
memcpy(enc, msg, len);
/* Append HMAC to data */
- ctx = HMAC_CTX_new();
- HMAC_Init_ex(ctx, mac_key, 20, EVP_sha1(), NULL);
- HMAC_Update(ctx, epoch, 2);
- HMAC_Update(ctx, seq, 6);
- HMAC_Update(ctx, &type, 1);
- HMAC_Update(ctx, ver, 2); /* Version */
+ hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+ ctx = EVP_MAC_CTX_new(hmac);
+ EVP_MAC_free(hmac);
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ "SHA1", 0);
+ params[1] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
+ mac_key, 20);
+ params[2] = OSSL_PARAM_construct_end();
+ EVP_MAC_CTX_set_params(ctx, params);
+ EVP_MAC_init(ctx);
+ EVP_MAC_update(ctx, epoch, 2);
+ EVP_MAC_update(ctx, seq, 6);
+ EVP_MAC_update(ctx, &type, 1);
+ EVP_MAC_update(ctx, ver, 2); /* Version */
lenbytes[0] = (unsigned char)(len >> 8);
lenbytes[1] = (unsigned char)(len);
- HMAC_Update(ctx, lenbytes, 2); /* Length */
- HMAC_Update(ctx, enc, len); /* Finally the data itself */
- HMAC_Final(ctx, enc + len, NULL);
- HMAC_CTX_free(ctx);
+ EVP_MAC_update(ctx, lenbytes, 2); /* Length */
+ EVP_MAC_update(ctx, enc, len); /* Finally the data itself */
+ EVP_MAC_final(ctx, enc + len, NULL, SHA_DIGEST_LENGTH);
+ EVP_MAC_CTX_free(ctx);
/* Append padding bytes */
len += SHA_DIGEST_LENGTH;
diff --git a/test/handshake_helper.c b/test/handshake_helper.c
index e8249a7ce2..86313c9e3c 100644
--- a/test/handshake_helper.c
+++ b/test/handshake_helper.c
@@ -317,8 +317,9 @@ static int verify_accept_cb(X509_STORE_CTX *ctx, void *arg) {
return 1;
}
-static int broken_session_ticket_cb(SSL *s, unsigned char *key_name, unsigned char *iv,
- EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)
+static int broken_session_ticket_cb(SSL *s, unsigned char *key_name,
+ unsigned char *iv, EVP_CIPHER_CTX *ctx,
+ EVP_MAC_CTX *hctx, int enc)
{
return 0;
}
@@ -326,7 +327,7 @@ static int broken_session_ticket_cb(SSL *s, unsigned char *key_name, unsigned ch
static int do_not_call_session_ticket_cb(SSL *s, unsigned char *key_name,
unsigned char *iv,
EVP_CIPHER_CTX *ctx,
- HMAC_CTX *hctx, int enc)
+ EVP_MAC_CTX *hctx, int enc)
{
HANDSHAKE_EX_DATA *ex_data =
(HANDSHAKE_EX_DATA*)(SSL_get_ex_data(s, ex_data_idx));
@@ -585,11 +586,12 @@ static int configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
* session (assigned via SNI), and should never be invoked
*/
if (server2_ctx != NULL)
- SSL_CTX_set_tlsext_ticket_key_cb(server2_ctx,
- do_not_call_session_ticket_cb);
+ SSL_CTX_set_tlsext_ticket_key_evp_cb(server2_ctx,
+ do_not_call_session_ticket_cb);
if (extra->server.broken_session_ticket) {
- SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, broken_session_ticket_cb);
+ SSL_CTX_set_tlsext_ticket_key_evp_cb(server_ctx,
+ broken_session_ticket_cb);
}
#ifndef OPENSSL_NO_NEXTPROTONEG
if (extra->server.npn_protocols != NULL) {
diff --git a/test/sslapitest.c b/test/sslapitest.c
index 4993f16f4c..cf0fd3f37d 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -7,6 +7,14 @@
* https://www.openssl.org/source/license.html
*/
+/*
+ * We need access to the deprecated low level HMAC APIs for legacy purposes
+ * when the deprecated calls are not hidden
+ */
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+# define OPENSSL_SUPPRESS_DEPRECATED
+#endif
+
#include <stdio.h>
#include <string.h>
@@ -19,6 +27,7 @@
#include <openssl/txt_db.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
+#include <openssl/core_names.h>
#include "ssltestlib.h"
#include "testutil.h"
@@ -6077,6 +6086,7 @@ static SSL_TICKET_RETURN dec_tick_cb(SSL *s, SSL_SESSION *ss,
}
+#ifndef OPENSSL_NO_DEPRECATED_3_0
static int tick_key_cb(SSL *s, unsigned char key_name[16],
unsigned char iv[EVP_MAX_IV_LENGTH], EVP_CIPHER_CTX *ctx,
HMAC_CTX *hctx, int enc)
@@ -6094,6 +6104,32 @@ static int tick_key_cb(SSL *s, unsigned char key_name[16],
return tick_key_renew ? 2 : 1;
}
+#endif
+
+static int tick_key_evp_cb(SSL *s, unsigned char key_name[16],
+ unsigned char iv[EVP_MAX_IV_LENGTH],
+ EVP_CIPHER_CTX *ctx, EVP_MAC_CTX *hctx, int enc)
+{
+ const unsigned char tick_aes_key[16] = "0123456789abcdef";
+ unsigned char tick_hmac_key[16] = "0123456789abcdef";
+ OSSL_PARAM params[3];
+
+ tick_key_cb_called = 1;
+ memset(iv, 0, AES_BLOCK_SIZE);
+ memset(key_name, 0, 16);
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ "SHA256", 0);
+ params[1] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
+ tick_hmac_key,
+ sizeof(tick_hmac_key));
+ params[2] = OSSL_PARAM_construct_end();
+ if (!EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, tick_aes_key, iv, enc)
+ || !EVP_MAC_CTX_set_params(hctx, params)
+ || !EVP_MAC_init(hctx))
+ return -1;
+
+ return tick_key_renew ? 2 : 1;
+}
/*
* Test the various ticket callbacks
@@ -6105,10 +6141,14 @@ static int tick_key_cb(SSL *s, unsigned char key_name[16],
* Test 5: TLSv1.3, no ticket key callback, ticket, no renewal
* Test 6: TLSv1.2, no ticket key callback, ticket, renewal
* Test 7: TLSv1.3, no ticket key callback, ticket, renewal
- * Test 8: TLSv1.2, ticket key callback, ticket, no renewal
- * Test 9: TLSv1.3, ticket key callback, ticket, no renewal
- * Test 10: TLSv1.2, ticket key callback, ticket, renewal
- * Test 11: TLSv1.3, ticket key callback, ticket, renewal
+ * Test 8: TLSv1.2, old ticket key callback, ticket, no renewal
+ * Test 9: TLSv1.3, old ticket key callback, ticket, no renewal
+ * Test 10: TLSv1.2, old ticket key callback, ticket, renewal
+ * Test 11: TLSv1.3, old ticket key callback, ticket, renewal
+ * Test 12: TLSv1.2, ticket key callback, ticket, no renewal
+ * Test 13: TLSv1.3, ticket key callback, ticket, no renewal
+ * Test 14: TLSv1.2, ticket key callback, ticket, renewal
+ * Test 15: TLSv1.3, ticket key callback, ticket, renewal
*/
static int test_ticket_callbacks(int tst)
{
@@ -6125,11 +6165,15 @@ static int test_ticket_callbacks(int tst)
if (tst % 2 == 1)
return 1;
#endif
+#ifdef OPENSSL_NO_DEPRECATED_3_0
+ if (tst >= 8 && tst <= 11)
+ return 1;
+#endif
gen_tick_called = dec_tick_called = tick_key_cb_called = 0;
/* Which tests the ticket key callback should request renewal for */
- if (tst == 10 || tst == 11)
+ if (tst == 10 || tst == 11 || tst == 14 || tst == 15)
tick_key_renew = 1;
else
tick_key_renew = 0;
@@ -6179,9 +6223,15 @@ static int test_ticket_callbacks(int tst)
NULL)))
goto end;
- if (tst >= 8
- && !TEST_true(SSL_CTX_set_tlsext_ticket_key_cb(sctx, tick_key_cb)))
- goto end;
+ if (tst >= 12) {
+ if (!TEST_true(SSL_CTX_set_tlsext_ticket_key_evp_cb(sctx, tick_key_evp_cb)))
+ goto end;
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ } else if (tst >= 8) {
+ if (!TEST_true(SSL_CTX_set_tlsext_ticket_key_cb(sctx, tick_key_cb)))
+ goto end;
+#endif
+ }
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
NULL, NULL))
@@ -7060,7 +7110,7 @@ int setup_tests(void)
ADD_ALL_TESTS(test_info_callback, 6);
ADD_ALL_TESTS(test_ssl_pending, 2);
ADD_ALL_TESTS(test_ssl_get_shared_ciphers, OSSL_NELEM(shared_ciphers_data));
- ADD_ALL_TESTS(test_ticket_callbacks, 12);
+ ADD_ALL_TESTS(test_ticket_callbacks, 16);
ADD_ALL_TESTS(test_shutdown, 7);
ADD_ALL_TESTS(te