Skip to content

Commit

Permalink
Expand TLS configuration testing (#1742)
Browse files Browse the repository at this point in the history
  • Loading branch information
anrossi authored Jun 24, 2021
1 parent 5473178 commit dcfeeea
Show file tree
Hide file tree
Showing 8 changed files with 293 additions and 30 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ if(QUIC_TELEMETRY_ASSERTS)
endif()

if(QUIC_TLS STREQUAL "schannel")
message(STATUS "Enabling Schannel configuration tests")
list(APPEND QUIC_COMMON_DEFINES QUIC_TEST_SCHANNEL_FLAGS=1)
message(STATUS "Enabling UDP Send Queuing")
list(APPEND QUIC_COMMON_DEFINES CXPLAT_DATAPATH_QUEUE_SENDS=1)
message(STATUS "Disabling PFX tests")
Expand All @@ -224,6 +226,8 @@ if(QUIC_TLS STREQUAL "schannel")
endif()

if(QUIC_TLS STREQUAL "openssl")
message(STATUS "Enabling OpenSsl configuration tests")
list(APPEND QUIC_COMMON_DEFINES QUIC_TEST_OPENSSL_FLAGS=1)
message(STATUS "Disabling client certificate tests")
list(APPEND QUIC_COMMON_DEFINES QUIC_DISABLE_CLIENT_CERT_TESTS)
message(STATUS "Disabling deferred certificate tests")
Expand Down
4 changes: 2 additions & 2 deletions src/inc/msquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,14 @@ typedef enum QUIC_CREDENTIAL_FLAGS {
QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED = 0x00000010,
QUIC_CREDENTIAL_FLAG_DEFER_CERTIFICATE_VALIDATION = 0x00000020, // Schannel only currently
QUIC_CREDENTIAL_FLAG_REQUIRE_CLIENT_AUTHENTICATION = 0x00000040, // Schannel only currently
QUIC_CREDENTIAL_FLAG_USE_TLS_BUILTIN_CERTIFICATE_VALIDATION = 0x00000080,
QUIC_CREDENTIAL_FLAG_USE_TLS_BUILTIN_CERTIFICATE_VALIDATION = 0x00000080, // OpenSSL only currently
QUIC_CREDENTIAL_FLAG_REVOCATION_CHECK_END_CERT = 0x00000100, // Schannel only currently
QUIC_CREDENTIAL_FLAG_REVOCATION_CHECK_CHAIN = 0x00000200, // Schannel only currently
QUIC_CREDENTIAL_FLAG_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x00000400, // Schannel only currently
QUIC_CREDENTIAL_FLAG_IGNORE_NO_REVOCATION_CHECK = 0x00000800, // Schannel only currently
QUIC_CREDENTIAL_FLAG_IGNORE_REVOCATION_OFFLINE = 0x00001000, // Schannel only currently
QUIC_CREDENTIAL_FLAG_SET_ALLOWED_CIPHER_SUITES = 0x00002000,
QUIC_CREDENTIAL_FLAGS_USE_PORTABLE_CERTIFICATES = 0x00004000,
QUIC_CREDENTIAL_FLAGS_USE_PORTABLE_CERTIFICATES = 0x00004000, // OpenSSL only currently
} QUIC_CREDENTIAL_FLAGS;

DEFINE_ENUM_FLAG_OPERATORS(QUIC_CREDENTIAL_FLAGS)
Expand Down
1 change: 1 addition & 0 deletions src/inc/quic_cert.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ BOOLEAN
CxPlatCertValidateChain(
_In_ const QUIC_CERTIFICATE* Certificate,
_In_opt_z_ const char* Host,
_In_ uint32_t CertFlags,
_In_ uint32_t IgnoreFlags
);

Expand Down
11 changes: 9 additions & 2 deletions src/platform/cert_capi.c
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ CxPlatCertVerifyCertChainPolicy(
memset(&HttpsPolicy, 0, sizeof(HTTPSPolicyCallbackData));
HttpsPolicy.cbStruct = sizeof(HTTPSPolicyCallbackData);
HttpsPolicy.dwAuthType = AUTHTYPE_SERVER;
HttpsPolicy.fdwChecks = IgnoreFlags;
HttpsPolicy.fdwChecks = 0;
HttpsPolicy.pwszServerName = ServerName;

memset(&PolicyPara, 0, sizeof(PolicyPara));
Expand All @@ -823,6 +823,12 @@ CxPlatCertVerifyCertChainPolicy(
"CertVerifyCertificateChainPolicy failed");
goto Exit;

} else if (PolicyStatus.dwError == CRYPT_E_NO_REVOCATION_CHECK &&
(IgnoreFlags & QUIC_CREDENTIAL_FLAG_IGNORE_NO_REVOCATION_CHECK)) {
Status = NO_ERROR;
} else if (PolicyStatus.dwError == CRYPT_E_REVOCATION_OFFLINE &&
(IgnoreFlags & QUIC_CREDENTIAL_FLAG_IGNORE_REVOCATION_OFFLINE)) {
Status = NO_ERROR;
} else if (PolicyStatus.dwError != NO_ERROR) {

Status = PolicyStatus.dwError;
Expand Down Expand Up @@ -851,6 +857,7 @@ BOOLEAN
CxPlatCertValidateChain(
_In_ const QUIC_CERTIFICATE* Certificate,
_In_opt_z_ PCSTR Host,
_In_ uint32_t CertFlags,
_In_ uint32_t IgnoreFlags
)
{
Expand Down Expand Up @@ -880,7 +887,7 @@ CxPlatCertValidateChain(
NULL,
LeafCertCtx->hCertStore,
&ChainPara,
0,
CertFlags,
NULL,
&ChainContext)) {
QuicTraceEvent(
Expand Down
24 changes: 21 additions & 3 deletions src/platform/cert_capi_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
BOOLEAN
CxPlatTlsVerifyCertificate(
_In_ X509* X509Cert,
_In_ const char* SNI
_In_ const char* SNI,
_In_ QUIC_CREDENTIAL_FLAGS CredFlags
)
{
// Convert SNI to wide
Expand Down Expand Up @@ -78,11 +79,26 @@ CxPlatTlsVerifyCertificate(
goto Exit;
}

uint32_t CertFlags = 0;
if (CredFlags & QUIC_CREDENTIAL_FLAG_REVOCATION_CHECK_END_CERT) {
CertFlags |= CERT_CHAIN_REVOCATION_CHECK_END_CERT;
}
if (CredFlags & QUIC_CREDENTIAL_FLAG_REVOCATION_CHECK_CHAIN) {
CertFlags |= CERT_CHAIN_REVOCATION_CHECK_CHAIN;
}
if (CredFlags & QUIC_CREDENTIAL_FLAG_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT) {
CertFlags |= CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT;
}

uint32_t IgnoreFlags =
CredFlags & (QUIC_CREDENTIAL_FLAG_IGNORE_REVOCATION_OFFLINE | QUIC_CREDENTIAL_FLAG_IGNORE_NO_REVOCATION_CHECK);

Result =
CxPlatCertValidateChain(
CertContext,
SNI,
0);
CertFlags,
IgnoreFlags);

Exit:

Expand Down Expand Up @@ -351,11 +367,13 @@ CxPlatTlsExtractPrivateKey(
BOOLEAN
CxPlatTlsVerifyCertificate(
_In_ X509* X509Cert,
_In_ const char* SNI
_In_ const char* SNI,
_In_ QUIC_CREDENTIAL_FLAGS CredFlags
)
{
UNREFERENCED_PARAMETER(X509Cert);
UNREFERENCED_PARAMETER(SNI);
UNREFERENCED_PARAMETER(CredFlags);
return 0;
}
#endif
47 changes: 30 additions & 17 deletions src/platform/tls_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ CxPlatTlsAlpnSelectCallback(
BOOLEAN
CxPlatTlsVerifyCertificate(
_In_ X509* X509Cert,
_In_ const char* SNI
_In_ const char* SNI,
_In_ QUIC_CREDENTIAL_FLAGS CredFlags
);

static
Expand All @@ -201,7 +202,7 @@ CxPlatTlsCertificateVerifyCallback(
CXPLAT_TLS* TlsContext = SSL_get_app_data(Ssl);

if (!(TlsContext->SecConfig->Flags & QUIC_CREDENTIAL_FLAG_USE_TLS_BUILTIN_CERTIFICATE_VALIDATION)) {
preverify_ok = CxPlatTlsVerifyCertificate(Cert, TlsContext->SNI);
preverify_ok = CxPlatTlsVerifyCertificate(Cert, TlsContext->SNI, TlsContext->SecConfig->Flags);
}

if (!(TlsContext->SecConfig->Flags & QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION) &&
Expand Down Expand Up @@ -804,21 +805,37 @@ CxPlatTlsSecConfigCreate(
_In_ CXPLAT_SEC_CONFIG_CREATE_COMPLETE_HANDLER CompletionHandler
)
{
if (CredConfig->Flags & QUIC_CREDENTIAL_FLAG_LOAD_ASYNCHRONOUS &&
QUIC_CREDENTIAL_FLAGS CredConfigFlags = CredConfig->Flags;

if (CredConfigFlags & QUIC_CREDENTIAL_FLAG_LOAD_ASYNCHRONOUS &&
CredConfig->AsyncHandler == NULL) {
return QUIC_STATUS_INVALID_PARAMETER;
}

if (CredConfig->Flags & QUIC_CREDENTIAL_FLAG_ENABLE_OCSP ||
CredConfig->Flags & QUIC_CREDENTIAL_FLAG_DEFER_CERTIFICATE_VALIDATION) {
if (CredConfigFlags & QUIC_CREDENTIAL_FLAG_ENABLE_OCSP ||
CredConfigFlags & QUIC_CREDENTIAL_FLAG_DEFER_CERTIFICATE_VALIDATION ||
CredConfigFlags & QUIC_CREDENTIAL_FLAG_REQUIRE_CLIENT_AUTHENTICATION) {
return QUIC_STATUS_NOT_SUPPORTED; // Not supported by this TLS implementation
}

#ifdef CX_PLATFORM_USES_TLS_BUILTIN_CERTIFICATE
CredConfigFlags |= QUIC_CREDENTIAL_FLAG_USE_TLS_BUILTIN_CERTIFICATE_VALIDATION;
#endif

if ((CredConfigFlags & QUIC_CREDENTIAL_FLAG_USE_TLS_BUILTIN_CERTIFICATE_VALIDATION) &&
(CredConfigFlags & QUIC_CREDENTIAL_FLAG_REVOCATION_CHECK_END_CERT ||
CredConfigFlags & QUIC_CREDENTIAL_FLAG_REVOCATION_CHECK_CHAIN ||
CredConfigFlags & QUIC_CREDENTIAL_FLAG_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT ||
CredConfigFlags & QUIC_CREDENTIAL_FLAG_IGNORE_NO_REVOCATION_CHECK ||
CredConfigFlags & QUIC_CREDENTIAL_FLAG_IGNORE_REVOCATION_OFFLINE)) {
return QUIC_STATUS_INVALID_PARAMETER;
}

if (CredConfig->Reserved != NULL) {
return QUIC_STATUS_INVALID_PARAMETER; // Not currently used and should be NULL.
}

if (CredConfig->Flags & QUIC_CREDENTIAL_FLAG_CLIENT) {
if (CredConfigFlags & QUIC_CREDENTIAL_FLAG_CLIENT) {
if (CredConfig->Type != QUIC_CREDENTIAL_TYPE_NONE) {
return QUIC_STATUS_NOT_SUPPORTED; // Not supported for client (yet)
}
Expand Down Expand Up @@ -858,7 +875,7 @@ CxPlatTlsSecConfigCreate(
}
}

if (CredConfig->Flags & QUIC_CREDENTIAL_FLAG_SET_ALLOWED_CIPHER_SUITES &&
if (CredConfigFlags & QUIC_CREDENTIAL_FLAG_SET_ALLOWED_CIPHER_SUITES &&
((CredConfig->AllowedCipherSuites &
(QUIC_ALLOWED_CIPHER_SUITE_AES_128_GCM_SHA256 |
QUIC_ALLOWED_CIPHER_SUITE_AES_256_GCM_SHA384 |
Expand Down Expand Up @@ -896,7 +913,7 @@ CxPlatTlsSecConfigCreate(

CxPlatZeroMemory(SecurityConfig, sizeof(CXPLAT_SEC_CONFIG));
SecurityConfig->Callbacks = *TlsCallbacks;
SecurityConfig->Flags = CredConfig->Flags;
SecurityConfig->Flags = CredConfigFlags;
SecurityConfig->TlsFlags = TlsCredFlags;

//
Expand Down Expand Up @@ -941,7 +958,7 @@ CxPlatTlsSecConfigCreate(
}

char* CipherSuites = CXPLAT_TLS_DEFAULT_SSL_CIPHERS;
if (CredConfig->Flags & QUIC_CREDENTIAL_FLAG_SET_ALLOWED_CIPHER_SUITES) {
if (CredConfigFlags & QUIC_CREDENTIAL_FLAG_SET_ALLOWED_CIPHER_SUITES) {
//
// Calculate allowed cipher suite string length.
//
Expand Down Expand Up @@ -1022,10 +1039,6 @@ CxPlatTlsSecConfigCreate(
goto Exit;
}

#ifdef CX_PLATFORM_USES_TLS_BUILTIN_CERTIFICATE
SecurityConfig->Flags |= QUIC_CREDENTIAL_FLAG_USE_TLS_BUILTIN_CERTIFICATE_VALIDATION;
#endif

if (SecurityConfig->Flags & QUIC_CREDENTIAL_FLAG_USE_TLS_BUILTIN_CERTIFICATE_VALIDATION) {
Ret = SSL_CTX_set_default_verify_paths(SecurityConfig->SSLCtx);
if (Ret != 1) {
Expand Down Expand Up @@ -1064,7 +1077,7 @@ CxPlatTlsSecConfigCreate(
goto Exit;
}

if ((CredConfig->Flags & QUIC_CREDENTIAL_FLAG_CLIENT) &&
if ((CredConfigFlags & QUIC_CREDENTIAL_FLAG_CLIENT) &&
!(TlsCredFlags & CXPLAT_TLS_CREDENTIAL_FLAG_DISABLE_RESUMPTION)) {
SSL_CTX_set_session_cache_mode(
SecurityConfig->SSLCtx,
Expand All @@ -1074,7 +1087,7 @@ CxPlatTlsSecConfigCreate(
CxPlatTlsOnClientSessionTicketReceived);
}

if (!(CredConfig->Flags & QUIC_CREDENTIAL_FLAG_CLIENT)) {
if (!(CredConfigFlags & QUIC_CREDENTIAL_FLAG_CLIENT)) {
if (!(TlsCredFlags & CXPLAT_TLS_CREDENTIAL_FLAG_DISABLE_RESUMPTION)) {
Ret = SSL_CTX_set_max_early_data(SecurityConfig->SSLCtx, 0xFFFFFFFF);
if (Ret != 1) {
Expand Down Expand Up @@ -1115,7 +1128,7 @@ CxPlatTlsSecConfigCreate(
}
}

if (CredConfig->Flags & QUIC_CREDENTIAL_FLAG_CLIENT) {
if (CredConfigFlags & QUIC_CREDENTIAL_FLAG_CLIENT) {
SSL_CTX_set_verify(SecurityConfig->SSLCtx, SSL_VERIFY_PEER, CxPlatTlsCertificateVerifyCallback);
SSL_CTX_set_verify_depth(SecurityConfig->SSLCtx, CXPLAT_TLS_DEFAULT_VERIFY_DEPTH);

Expand Down Expand Up @@ -1320,7 +1333,7 @@ CxPlatTlsSecConfigCreate(
CompletionHandler(CredConfig, Context, Status, SecurityConfig);
SecurityConfig = NULL;

if (CredConfig->Flags & QUIC_CREDENTIAL_FLAG_LOAD_ASYNCHRONOUS) {
if (CredConfigFlags & QUIC_CREDENTIAL_FLAG_LOAD_ASYNCHRONOUS) {
Status = QUIC_STATUS_PENDING;
} else {
Status = QUIC_STATUS_SUCCESS;
Expand Down
4 changes: 4 additions & 0 deletions src/platform/tls_schannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,10 @@ CxPlatTlsSecConfigCreate(
return QUIC_STATUS_INVALID_PARAMETER; // Client authentication is a server-only flag.
}

if (CredConfig->Flags & QUIC_CREDENTIAL_FLAG_USE_TLS_BUILTIN_CERTIFICATE_VALIDATION) {
return QUIC_STATUS_INVALID_PARAMETER;
}

if (CredConfig->Flags & QUIC_CREDENTIAL_FLAGS_USE_PORTABLE_CERTIFICATES) {
return QUIC_STATUS_NOT_SUPPORTED; // Not supported yet.
}
Expand Down
Loading

0 comments on commit dcfeeea

Please sign in to comment.