From: Fred Morcos Date: Mon, 9 Jan 2023 12:56:37 +0000 (+0100) Subject: OpenSSL 3.0: TLS MAC handling X-Git-Tag: dnsdist-1.8.0-rc1~116^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f5e1b85e40a043c9aec4e6c8859f2db82f7f3a73;p=thirdparty%2Fpdns.git OpenSSL 3.0: TLS MAC handling --- diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index fd993a25d1..443b150083 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -1352,7 +1352,11 @@ static int ocsp_stapling_callback(SSL* ssl, void* arg) } #endif /* DISABLE_OCSP_STAPLING */ +#if OPENSSL_VERSION_MAJOR >= 3 +static int ticket_key_callback(SSL *s, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char *iv, EVP_CIPHER_CTX *ectx, EVP_MAC_CTX *hctx, int enc) +#else static int ticket_key_callback(SSL *s, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc) +#endif { DOHAcceptContext* ctx = reinterpret_cast(libssl_get_ticket_key_callback_data(s)); if (ctx == nullptr || !ctx->d_ticketKeys) { @@ -1386,7 +1390,11 @@ static void setupTLSContext(DOHAcceptContext& acceptCtx, if (tlsConfig.d_enableTickets && tlsConfig.d_numberOfTicketsKeys > 0) { acceptCtx.d_ticketKeys = std::make_unique(tlsConfig.d_numberOfTicketsKeys); +#if OPENSSL_VERSION_MAJOR >= 3 + SSL_CTX_set_tlsext_ticket_key_evp_cb(ctx.get(), &ticket_key_callback); +#else SSL_CTX_set_tlsext_ticket_key_cb(ctx.get(), &ticket_key_callback); +#endif libssl_set_ticket_key_callback_data(ctx.get(), &acceptCtx); } diff --git a/pdns/libssl.cc b/pdns/libssl.cc index 3b9e80ba0e..6026bdba3f 100644 --- a/pdns/libssl.cc +++ b/pdns/libssl.cc @@ -27,6 +27,12 @@ #include #include +#if OPENSSL_VERSION_MAJOR >= 3 +#include +#include +#include +#endif + #ifdef HAVE_LIBSODIUM #include #endif /* HAVE_LIBSODIUM */ @@ -214,7 +220,11 @@ void libssl_set_ticket_key_callback_data(SSL_CTX* ctx, void* data) SSL_CTX_set_ex_data(ctx, s_ticketsKeyIndex, data); } +#if OPENSSL_VERSION_MAJOR >= 3 +int libssl_ticket_key_callback(SSL* s, OpenSSLTLSTicketKeysRing& keyring, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx, int enc) +#else int libssl_ticket_key_callback(SSL* s, OpenSSLTLSTicketKeysRing& keyring, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx, int enc) +#endif { if (enc != 0) { const auto key = keyring.getEncryptionKey(); @@ -695,7 +705,15 @@ bool OpenSSLTLSTicketKey::nameMatches(const unsigned char name[TLS_TICKETS_KEY_N return (memcmp(d_name, name, sizeof(d_name)) == 0); } +#if OPENSSL_VERSION_MAJOR >= 3 +static const std::string sha256KeyName{"sha256"}; +#endif + +#if OPENSSL_VERSION_MAJOR >= 3 +int OpenSSLTLSTicketKey::encrypt(unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx) const +#else int OpenSSLTLSTicketKey::encrypt(unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx) const +#endif { memcpy(keyName, d_name, sizeof(d_name)); @@ -707,18 +725,74 @@ int OpenSSLTLSTicketKey::encrypt(unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE return -1; } +#if OPENSSL_VERSION_MAJOR >= 3 + using ParamsBuilder = std::unique_ptr; + + auto params_build = ParamsBuilder(OSSL_PARAM_BLD_new(), OSSL_PARAM_BLD_free); + if (params_build == nullptr) { + return -1; + } + + if (OSSL_PARAM_BLD_push_utf8_string(params_build.get(), OSSL_MAC_PARAM_DIGEST, sha256KeyName.c_str(), sha256KeyName.size()) == 0) { + return -1; + } + + auto* params = OSSL_PARAM_BLD_to_param(params_build.get()); + if (params == nullptr) { + return -1; + } + + if (EVP_MAC_CTX_set_params(hctx, params) == 0) { + return -1; + } + + if (EVP_MAC_init(hctx, d_hmacKey, sizeof(d_hmacKey), nullptr) == 0) { + return -1; + } +#else if (HMAC_Init_ex(hctx, d_hmacKey, sizeof(d_hmacKey), TLS_TICKETS_MAC_ALGO(), nullptr) != 1) { return -1; } +#endif return 1; } +#if OPENSSL_VERSION_MAJOR >= 3 +bool OpenSSLTLSTicketKey::decrypt(const unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx) const +#else bool OpenSSLTLSTicketKey::decrypt(const unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx) const +#endif { +#if OPENSSL_VERSION_MAJOR >= 3 + using ParamsBuilder = std::unique_ptr; + + auto params_build = ParamsBuilder(OSSL_PARAM_BLD_new(), OSSL_PARAM_BLD_free); + if (params_build == nullptr) { + return false; + } + + if (OSSL_PARAM_BLD_push_utf8_string(params_build.get(), OSSL_MAC_PARAM_DIGEST, sha256KeyName.c_str(), sha256KeyName.size()) == 0) { + return false; + } + + auto* params = OSSL_PARAM_BLD_to_param(params_build.get()); + if (params == nullptr) { + return false; + } + + if (EVP_MAC_CTX_set_params(hctx, params) == 0) { + return false; + } + + if (EVP_MAC_init(hctx, d_hmacKey, sizeof(d_hmacKey), nullptr) == 0) { + return false; + } +#else if (HMAC_Init_ex(hctx, d_hmacKey, sizeof(d_hmacKey), TLS_TICKETS_MAC_ALGO(), nullptr) != 1) { return false; } +#endif if (EVP_DecryptInit_ex(ectx, TLS_TICKETS_CIPHER_ALGO(), nullptr, d_cipherKey, iv) != 1) { return false; diff --git a/pdns/libssl.hh b/pdns/libssl.hh index 3e5e1fe9b2..d8af451112 100644 --- a/pdns/libssl.hh +++ b/pdns/libssl.hh @@ -91,8 +91,14 @@ public: ~OpenSSLTLSTicketKey(); bool nameMatches(const unsigned char name[TLS_TICKETS_KEY_NAME_SIZE]) const; + +#if OPENSSL_VERSION_MAJOR >= 3 + int encrypt(unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx) const; + bool decrypt(const unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx) const; +#else int encrypt(unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx) const; bool decrypt(const unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx) const; +#endif private: unsigned char d_name[TLS_TICKETS_KEY_NAME_SIZE]; @@ -118,7 +124,12 @@ private: void* libssl_get_ticket_key_callback_data(SSL* s); void libssl_set_ticket_key_callback_data(SSL_CTX* ctx, void* data); + +#if OPENSSL_VERSION_MAJOR >= 3 +int libssl_ticket_key_callback(SSL* s, OpenSSLTLSTicketKeysRing& keyring, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx, int enc); +#else int libssl_ticket_key_callback(SSL* s, OpenSSLTLSTicketKeysRing& keyring, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx, int enc); +#endif #ifndef DISABLE_OCSP_STAPLING int libssl_ocsp_stapling_callback(SSL* ssl, const std::map& ocspMap); diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index aaa25ab5f4..fd3a50b7c9 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -585,7 +585,11 @@ public: if (fe.d_tlsConfig.d_enableTickets && fe.d_tlsConfig.d_numberOfTicketsKeys > 0) { /* use our own ticket keys handler so we can rotate them */ +#if OPENSSL_VERSION_MAJOR >= 3 + SSL_CTX_set_tlsext_ticket_key_evp_cb(d_feContext->d_tlsCtx.get(), &OpenSSLTLSIOCtx::ticketKeyCb); +#else SSL_CTX_set_tlsext_ticket_key_cb(d_feContext->d_tlsCtx.get(), &OpenSSLTLSIOCtx::ticketKeyCb); +#endif libssl_set_ticket_key_callback_data(d_feContext->d_tlsCtx.get(), d_feContext.get()); } @@ -704,7 +708,11 @@ public: unregisterOpenSSLUser(); } +#if OPENSSL_VERSION_MAJOR >= 3 + static int ticketKeyCb(SSL* s, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx, int enc) +#else static int ticketKeyCb(SSL* s, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx, int enc) +#endif { auto* ctx = reinterpret_cast(libssl_get_ticket_key_callback_data(s)); if (ctx == nullptr) {