Enable use of OpenSSL 3 without deprecated functions (#2083)

This commit is contained in:
Thad House 2021-10-28 10:11:14 -07:00 коммит произвёл GitHub
Родитель f3af503f37
Коммит 390f88bce4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 382 добавлений и 20 удалений

Просмотреть файл

@ -436,6 +436,148 @@ tracepoint(CLOG_CRYPT_OPENSSL_C, AllocFailure , arg2, arg3);\
#ifndef _clog_4_ARGS_TRACE_AllocFailure
/*----------------------------------------------------------
// Decoder Ring for AllocFailure
// Allocation of '%s' failed. (%llu bytes)
// QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"Crypt Hash Context",
sizeof(CXPLAT_HASH) + SaltLength);
// arg2 = arg2 = "Crypt Hash Context"
// arg3 = arg3 = sizeof(CXPLAT_HASH) + SaltLength
----------------------------------------------------------*/
#define _clog_4_ARGS_TRACE_AllocFailure(uniqueId, encoded_arg_string, arg2, arg3)\
#endif
#ifndef _clog_3_ARGS_TRACE_LibraryError
/*----------------------------------------------------------
// Decoder Ring for LibraryError
// [ lib] ERROR, %s.
// QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"EVP_MAC_fetch failed");
// arg2 = arg2 = "EVP_MAC_fetch failed"
----------------------------------------------------------*/
#define _clog_3_ARGS_TRACE_LibraryError(uniqueId, encoded_arg_string, arg2)\
#endif
#ifndef _clog_3_ARGS_TRACE_LibraryError
/*----------------------------------------------------------
// Decoder Ring for LibraryError
// [ lib] ERROR, %s.
// QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"EVP_MAC_CTX_new failed");
// arg2 = arg2 = "EVP_MAC_CTX_new failed"
----------------------------------------------------------*/
#define _clog_3_ARGS_TRACE_LibraryError(uniqueId, encoded_arg_string, arg2)\
#endif
#ifndef _clog_3_ARGS_TRACE_LibraryError
/*----------------------------------------------------------
// Decoder Ring for LibraryError
// [ lib] ERROR, %s.
// QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"EVP_MAC_CTX_set_params failed");
// arg2 = arg2 = "EVP_MAC_CTX_set_params failed"
----------------------------------------------------------*/
#define _clog_3_ARGS_TRACE_LibraryError(uniqueId, encoded_arg_string, arg2)\
#endif
#ifndef _clog_3_ARGS_TRACE_LibraryError
/*----------------------------------------------------------
// Decoder Ring for LibraryError
// [ lib] ERROR, %s.
// QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"EVP_MAC_init failed");
// arg2 = arg2 = "EVP_MAC_init failed"
----------------------------------------------------------*/
#define _clog_3_ARGS_TRACE_LibraryError(uniqueId, encoded_arg_string, arg2)\
#endif
#ifndef _clog_3_ARGS_TRACE_LibraryError
/*----------------------------------------------------------
// Decoder Ring for LibraryError
// [ lib] ERROR, %s.
// QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"EVP_MAC_update failed");
// arg2 = arg2 = "EVP_MAC_update failed"
----------------------------------------------------------*/
#define _clog_3_ARGS_TRACE_LibraryError(uniqueId, encoded_arg_string, arg2)\
#endif
#ifndef _clog_3_ARGS_TRACE_LibraryError
/*----------------------------------------------------------
// Decoder Ring for LibraryError
// [ lib] ERROR, %s.
// QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"EVP_MAC_final failed");
// arg2 = arg2 = "EVP_MAC_final failed"
----------------------------------------------------------*/
#define _clog_3_ARGS_TRACE_LibraryError(uniqueId, encoded_arg_string, arg2)\
#endif
#ifndef _clog_3_ARGS_TRACE_LibraryError

Просмотреть файл

@ -11,14 +11,22 @@ Abstract:
#include "platform_internal.h"
#define OPENSSL_SUPPRESS_DEPRECATED 1 // For hmac.h, which was deprecated in 3.0
#include "openssl/opensslv.h"
#if OPENSSL_VERSION_MAJOR >= 3
#define IS_OPENSSL_3
#endif
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable:4100) // Unreferenced parameter errcode in inline function
#endif
#include "openssl/bio.h"
#include "openssl/err.h"
#ifdef IS_OPENSSL_3
#include "openssl/core_names.h"
#else
#include "openssl/hmac.h"
#endif
#include "openssl/err.h"
#include "openssl/kdf.h"
#include "openssl/pem.h"
#include "openssl/pkcs12.h"
@ -414,19 +422,165 @@ CxPlatHpComputeMask(
// Hash abstraction
//
#ifdef IS_OPENSSL_3
//
// OpenSSL 3.0 Hash implementation
//
typedef struct CXPLAT_HASH {
//
// The message digest.
//
const EVP_MD *Md;
//
// Context used for hashing.
//
HMAC_CTX* HashContext;
EVP_MAC* Mac;
EVP_MAC_CTX* Ctx;
uint32_t SaltLength;
uint8_t Salt[0];
} CXPLAT_HASH;
_IRQL_requires_max_(DISPATCH_LEVEL)
QUIC_STATUS
CxPlatHashCreate(
_In_ CXPLAT_HASH_TYPE HashType,
_In_reads_(SaltLength)
const uint8_t* const Salt,
_In_ uint32_t SaltLength,
_Out_ CXPLAT_HASH** NewHash
)
{
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
CXPLAT_HASH* Hash;
const char* HashString;
OSSL_PARAM AlgParam[2];
Hash = CXPLAT_ALLOC_NONPAGED(sizeof(CXPLAT_HASH) + SaltLength, QUIC_POOL_TLS_HASH);
if (Hash == NULL) {
QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"Crypt Hash Context",
sizeof(CXPLAT_HASH) + SaltLength);
Status = QUIC_STATUS_OUT_OF_MEMORY;
goto Exit;
}
CxPlatZeroMemory(Hash, sizeof(CXPLAT_HASH) + SaltLength);
Hash->SaltLength = SaltLength;
CxPlatCopyMemory(Hash->Salt, Salt, SaltLength);
Hash->Mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
if (Hash->Mac == NULL) {
QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"EVP_MAC_fetch failed");
Status = QUIC_STATUS_TLS_ERROR;
goto Exit;
}
Hash->Ctx = EVP_MAC_CTX_new(Hash->Mac);
if (Hash->Ctx == NULL) {
QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"EVP_MAC_CTX_new failed");
Status = QUIC_STATUS_OUT_OF_MEMORY;
goto Exit;
}
switch (HashType) {
case CXPLAT_HASH_SHA256:
HashString = "sha256";
break;
case CXPLAT_HASH_SHA384:
HashString = "sha384";
break;
case CXPLAT_HASH_SHA512:
HashString = "sha512";
break;
default:
Status = QUIC_STATUS_NOT_SUPPORTED;
goto Exit;
}
AlgParam[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, (char*)HashString, 0);
AlgParam[1] = OSSL_PARAM_construct_end();
if (!EVP_MAC_CTX_set_params(Hash->Ctx, AlgParam)) {
QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"EVP_MAC_CTX_set_params failed");
Status = QUIC_STATUS_TLS_ERROR;
goto Exit;
}
*NewHash = Hash;
Hash = NULL;
Exit:
CxPlatHashFree(Hash);
return Status;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
void
CxPlatHashFree(
_In_opt_ CXPLAT_HASH* Hash
)
{
if (Hash) {
if (Hash->Ctx) {
EVP_MAC_CTX_free(Hash->Ctx);
}
if (Hash->Mac) {
EVP_MAC_free(Hash->Mac);
}
CXPLAT_FREE(Hash, QUIC_POOL_TLS_HASH);
}
}
_IRQL_requires_max_(DISPATCH_LEVEL)
QUIC_STATUS
CxPlatHashCompute(
_In_ CXPLAT_HASH* Hash,
_In_reads_(InputLength)
const uint8_t* const Input,
_In_ uint32_t InputLength,
_In_ uint32_t OutputLength, // CxPlatHashLength(HashType)
_Out_writes_all_(OutputLength)
uint8_t* const Output
)
{
if (!EVP_MAC_init(Hash->Ctx, Hash->Salt, Hash->SaltLength, NULL)) {
QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"EVP_MAC_init failed");
return QUIC_STATUS_INTERNAL_ERROR;
}
if (!EVP_MAC_update(Hash->Ctx, Input, InputLength)) {
QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"EVP_MAC_update failed");
return QUIC_STATUS_INTERNAL_ERROR;
}
size_t ActualOutputSize = OutputLength;
if (!EVP_MAC_final(Hash->Ctx, Output, &ActualOutputSize, OutputLength)) {
QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"EVP_MAC_final failed");
return QUIC_STATUS_INTERNAL_ERROR;
}
CXPLAT_FRE_ASSERT(ActualOutputSize == OutputLength);
return QUIC_STATUS_SUCCESS;
}
#else
//
// OpenSSL 1.1 Hash implementation
//
_IRQL_requires_max_(DISPATCH_LEVEL)
QUIC_STATUS
CxPlatHashCreate(
@ -535,3 +689,4 @@ CxPlatHashCompute(
CXPLAT_FRE_ASSERT(ActualOutputSize == OutputLength);
return QUIC_STATUS_SUCCESS;
}
#endif

Просмотреть файл

@ -11,14 +11,22 @@ Abstract:
#include "platform_internal.h"
#define OPENSSL_SUPPRESS_DEPRECATED 1 // For hmac.h, which was deprecated in 3.0
#include "openssl/opensslv.h"
#if OPENSSL_VERSION_MAJOR >= 3
#define IS_OPENSSL_3
#endif
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable:4100) // Unreferenced parameter errcode in inline function
#endif
#include "openssl/bio.h"
#include "openssl/err.h"
#ifdef IS_OPENSSL_3
#include "openssl/core_names.h"
#else
#include "openssl/hmac.h"
#endif
#include "openssl/err.h"
#include "openssl/kdf.h"
#include "openssl/pem.h"
#include "openssl/pkcs12.h"
@ -727,10 +735,17 @@ CxPlatTlsOnSessionTicketKeyNeeded(
_When_(!enc, _In_reads_bytes_(EVP_MAX_IV_LENGTH))
unsigned char iv[EVP_MAX_IV_LENGTH],
_Inout_ EVP_CIPHER_CTX *ctx,
#ifdef IS_OPENSSL_3
_Inout_ EVP_MAC_CTX *hctx,
#else
_Inout_ HMAC_CTX *hctx,
#endif
_In_ int enc // Encryption or decryption
)
{
#ifdef IS_OPENSSL_3
OSSL_PARAM params[3];
#endif
CXPLAT_TLS* TlsContext = SSL_get_app_data(Ssl);
QUIC_TICKET_KEY_CONFIG* TicketKey = TlsContext->SecConfig->TicketKey;
@ -754,8 +769,24 @@ CxPlatTlsOnSessionTicketKeyNeeded(
}
CxPlatCopyMemory(key_name, TicketKey->Id, 16);
EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, TicketKey->Material, iv);
HMAC_Init_ex(hctx, TicketKey->Material, 32, EVP_sha256(), NULL);
#ifdef IS_OPENSSL_3
params[0] =
OSSL_PARAM_construct_octet_string(
OSSL_MAC_PARAM_KEY,
TicketKey->Material,
32);
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);
#else
HMAC_Init_ex(hctx, TicketKey->Material, 32, EVP_sha256(), NULL);
#endif
} else {
if (memcmp(key_name, TicketKey->Id, 16) != 0) {
QuicTraceEvent(
@ -765,7 +796,23 @@ CxPlatTlsOnSessionTicketKeyNeeded(
"Ticket key_name mismatch");
return 0; // No match
}
#ifdef IS_OPENSSL_3
params[0] =
OSSL_PARAM_construct_octet_string(
OSSL_MAC_PARAM_KEY,
TicketKey->Material,
32);
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);
#else
HMAC_Init_ex(hctx, TicketKey->Material, 32, EVP_sha256(), NULL);
#endif
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, TicketKey->Material, iv);
}
@ -1531,9 +1578,15 @@ CxPlatTlsSecConfigSetTicketKeys(
KeyConfig,
sizeof(QUIC_TICKET_KEY_CONFIG));
#ifdef IS_OPENSSL_3
SSL_CTX_set_tlsext_ticket_key_evp_cb(
SecurityConfig->SSLCtx,
CxPlatTlsOnSessionTicketKeyNeeded);
#else
SSL_CTX_set_tlsext_ticket_key_cb(
SecurityConfig->SSLCtx,
CxPlatTlsOnSessionTicketKeyNeeded);
#endif
return QUIC_STATUS_SUCCESS;
}
@ -1850,7 +1903,11 @@ CxPlatTlsProcessData(
char buf[256];
const char* file;
int line;
#ifdef IS_OPENSSL_3
ERR_error_string_n(ERR_get_error_all(&file, &line, NULL, NULL, NULL), buf, sizeof(buf));
#else
ERR_error_string_n(ERR_get_error_line(&file, &line), buf, sizeof(buf));
#endif
QuicTraceLogConnError(
OpenSslHandshakeErrorStr,
TlsContext->Connection,

Просмотреть файл

@ -14,14 +14,18 @@ set(QUIC_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(OPENSSL_DIR ${QUIC_BUILD_DIR}/openssl)
option(QUIC_USE_SYSTEM_LIBCRYPTO "Use system libcrypto if openssl TLS" OFF)
# Newer versions of OpenSSL switched to Markdown, so we can use that to detect
# the openssl version cloned
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/openssl/CHANGES")
message(STATUS "Configuring for OpenSSL 1.1")
else()
set(QUIC_USE_OPENSSL3 ON)
message(STATUS "Configuring for OpenSSL 3.0")
endif()
set(OPENSSL_CONFIG_FLAGS
enable-tls1_3 no-makedepend no-dgram no-ssl3 no-psk no-srp
#
# The following line is needed for the 3.0 branch.
#
# no-uplink no-cmp no-acvp_tests no-fips no-padlockeng no-siv
no-zlib no-egd no-idea no-rc5 no-rc4 no-afalgeng
no-comp no-cms no-ct no-srp no-srtp no-ts no-gost no-dso no-ec2m
no-tls1 no-tls1_1 no-tls1_2 no-dtls no-dtls1 no-dtls1_2 no-ssl
@ -29,6 +33,10 @@ set(OPENSSL_CONFIG_FLAGS
no-siphash no-whirlpool no-aria no-bf no-blake2 no-sm2 no-sm3 no-sm4 no-camellia no-cast no-md4 no-mdc2 no-ocb no-rc2 no-rmd160 no-scrypt
no-weak-ssl-ciphers no-shared no-tests)
if (QUIC_USE_OPENSSL3)
list(APPEND OPENSSL_CONFIG_FLAGS no-uplink no-cmp no-fips no-padlockeng no-siv)
endif()
if (WIN32)
if (DEFINED ENV{CommonProgramFiles})