Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ public enum Flags
SCH_CRED_REVOCATION_CHECK_END_CERT = 0x100,
SCH_CRED_IGNORE_NO_REVOCATION_CHECK = 0x800,
SCH_CRED_IGNORE_REVOCATION_OFFLINE = 0x1000,
SCH_CRED_CACHE_ONLY_URL_RETRIEVAL = 0x8000,
SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE = 0x20000,
SCH_SEND_AUX_RECORD = 0x00200000,
SCH_USE_STRONG_CRYPTO = 0x00400000,
}
Expand Down Expand Up @@ -246,7 +248,8 @@ public enum Flags
SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x400,
SCH_CRED_IGNORE_NO_REVOCATION_CHECK = 0x800,
SCH_CRED_IGNORE_REVOCATION_OFFLINE = 0x1000,
SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE = 0x2000,
SCH_CRED_CACHE_ONLY_URL_RETRIEVAL = 0x8000,
SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE = 0x20000,
SCH_SEND_ROOT_CERT = 0x40000,
SCH_SEND_AUX_RECORD = 0x00200000,
SCH_USE_STRONG_CRYPTO = 0x00400000,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.CompilerServices;
using System.Security.Authentication;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
Expand Down Expand Up @@ -188,7 +189,15 @@ private static MsQuicConfigurationSafeHandle Create(QuicConnectionOptions option
allowedCipherSuites = CipherSuitePolicyToFlags(cipherSuitesPolicy);
}

if (!MsQuicApi.UsesSChannelBackend)
if (MsQuicApi.UsesSChannelBackend)
{
// Either user code passed SslStreamCertificateContext and
// intermediates have already been retrieved, or they will be
// retrieved by the cert context we build internally, there is no
// need for MsQuic to do another AIA fetch
flags |= QUIC_CREDENTIAL_FLAGS.CACHE_ONLY_URL_RETRIEVAL;
}
else
{
flags |= QUIC_CREDENTIAL_FLAGS.USE_PORTABLE_CERTIFICATES;
}
Expand All @@ -203,15 +212,6 @@ private static MsQuicConfigurationSafeHandle Create(QuicConnectionOptions option

private static unsafe MsQuicConfigurationSafeHandle CreateInternal(QUIC_SETTINGS settings, QUIC_CREDENTIAL_FLAGS flags, X509Certificate? certificate, ReadOnlyCollection<X509Certificate2>? intermediates, List<SslApplicationProtocol> alpnProtocols, QUIC_ALLOWED_CIPHER_SUITE_FLAGS allowedCipherSuites)
{
if (!MsQuicApi.UsesSChannelBackend && certificate is X509Certificate2 cert && intermediates is null)
{
// MsQuic will not lookup intermediates in local CA store if not explicitly provided,
// so we build the cert context to get on feature parity with SslStream. Note that this code
// path runs after the MsQuicConfigurationCache check.
SslStreamCertificateContext context = SslStreamCertificateContext.Create(cert, additionalCertificates: null, offline: true, trust: null);
intermediates = context.IntermediateCertificates;
}

QUIC_HANDLE* handle;

using MsQuicBuffers msquicBuffers = new MsQuicBuffers();
Expand All @@ -227,8 +227,18 @@ private static unsafe MsQuicConfigurationSafeHandle CreateInternal(QUIC_SETTINGS
"ConfigurationOpen failed");
MsQuicConfigurationSafeHandle configurationHandle = new MsQuicConfigurationSafeHandle(handle);

SslStreamCertificateContext? context = null;

try
{
if (certificate is X509Certificate2 cert && intermediates is null)
{
// Build the local chain after the configuration cache check. Avoid OCSP fetches
// because we have no way to pass the staple to the MsQuic API anyway.
context = CreateCertificateContext(null, cert, additionalCertificates: null, offline: false, trust: null, noOcspFetch: true);
intermediates = context.IntermediateCertificates;
}

QUIC_CREDENTIAL_CONFIG config = new QUIC_CREDENTIAL_CONFIG
{
Flags = flags,
Expand Down Expand Up @@ -309,10 +319,23 @@ private static unsafe MsQuicConfigurationSafeHandle CreateInternal(QUIC_SETTINGS
configurationHandle.Dispose();
throw;
}
finally
{
if (context is not null)
{
ReleaseResources(context);
}
}

return configurationHandle;
}

[UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = nameof(SslStreamCertificateContext.Create))]
private static extern SslStreamCertificateContext CreateCertificateContext(SslStreamCertificateContext? context, X509Certificate2 target, X509Certificate2Collection? additionalCertificates, bool offline, SslCertificateTrust? trust, bool noOcspFetch);

[UnsafeAccessor(UnsafeAccessorKind.Method)]
private static extern void ReleaseResources(SslStreamCertificateContext context);

private static QUIC_ALLOWED_CIPHER_SUITE_FLAGS CipherSuitePolicyToFlags(CipherSuitesPolicy cipherSuitesPolicy)
{
QUIC_ALLOWED_CIPHER_SUITE_FLAGS flags = QUIC_ALLOWED_CIPHER_SUITE_FLAGS.NONE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,15 +337,15 @@ public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchannelCred(Ss
X509Certificate2? certificate = authOptions.CertificateContext?.TargetCertificate;
bool isServer = authOptions.IsServer;
int protocolFlags = GetProtocolFlagsFromSslProtocols(authOptions.EnabledSslProtocols, isServer);
Interop.SspiCli.SCHANNEL_CRED.Flags flags;
Interop.SspiCli.SCHANNEL_CRED.Flags flags = Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE;
Interop.SspiCli.CredentialUse direction;

bool allowTlsResume = authOptions.AllowTlsResume && !LocalAppContextSwitches.DisableTlsResume;

if (!isServer)
{
direction = Interop.SspiCli.CredentialUse.SECPKG_CRED_OUTBOUND;
flags =
flags |=
Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_CRED_MANUAL_CRED_VALIDATION |
Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_CRED_NO_DEFAULT_CREDS |
Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_SEND_AUX_RECORD;
Expand All @@ -362,7 +362,7 @@ public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchannelCred(Ss
else
{
direction = Interop.SspiCli.CredentialUse.SECPKG_CRED_INBOUND;
flags =
flags |=
Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_SEND_AUX_RECORD |
Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_CRED_NO_SYSTEM_MAPPER;
if (!allowTlsResume)
Expand All @@ -384,7 +384,7 @@ public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchannelCred(Ss
}
#pragma warning restore SYSLIB0040

if (NetEventSource.Log.IsEnabled()) NetEventSource.Info($"flags=({flags}), ProtocolFlags=({protocolFlags}), EncryptionPolicy={policy}");
if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(null, $"flags=({flags}), ProtocolFlags=({protocolFlags}), EncryptionPolicy={policy}");
Interop.SspiCli.SCHANNEL_CRED secureCredential = CreateSecureCredential(
flags,
protocolFlags,
Expand Down Expand Up @@ -412,15 +412,15 @@ public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchCredentials(
X509Certificate2? certificate = authOptions.CertificateContext?.TargetCertificate;
bool isServer = authOptions.IsServer;
int protocolFlags = GetProtocolFlagsFromSslProtocols(authOptions.EnabledSslProtocols, isServer);
Interop.SspiCli.SCH_CREDENTIALS.Flags flags;
Interop.SspiCli.SCH_CREDENTIALS.Flags flags = Interop.SspiCli.SCH_CREDENTIALS.Flags.SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE;
Interop.SspiCli.CredentialUse direction;

bool allowTlsResume = authOptions.AllowTlsResume && !LocalAppContextSwitches.DisableTlsResume;

if (isServer)
{
direction = Interop.SspiCli.CredentialUse.SECPKG_CRED_INBOUND;
flags =
flags |=
Interop.SspiCli.SCH_CREDENTIALS.Flags.SCH_SEND_AUX_RECORD |
Interop.SspiCli.SCH_CREDENTIALS.Flags.SCH_CRED_NO_SYSTEM_MAPPER;
if (!allowTlsResume)
Expand All @@ -432,7 +432,7 @@ public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchCredentials(
else
{
direction = Interop.SspiCli.CredentialUse.SECPKG_CRED_OUTBOUND;
flags =
flags |=
Interop.SspiCli.SCH_CREDENTIALS.Flags.SCH_CRED_MANUAL_CRED_VALIDATION |
Interop.SspiCli.SCH_CREDENTIALS.Flags.SCH_CRED_NO_DEFAULT_CREDS |
Interop.SspiCli.SCH_CREDENTIALS.Flags.SCH_SEND_AUX_RECORD;
Expand Down Expand Up @@ -485,7 +485,7 @@ public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchCredentials(
credential.paCred = &certificateHandle;
}

if (NetEventSource.Log.IsEnabled()) NetEventSource.Info($"flags=({flags}), ProtocolFlags=({protocolFlags}), EncryptionPolicy={policy}");
if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(null, $"flags=({flags}), ProtocolFlags=({protocolFlags}), EncryptionPolicy={policy}");

Interop.SspiCli.TLS_PARAMETERS tlsParameters = default;
credential.cTlsParameters = 1;
Expand Down
Loading