Skip to content

Commit

Permalink
Version check to work around microsoft/msquic#4132
Browse files Browse the repository at this point in the history
  • Loading branch information
rzikm committed Feb 26, 2024
1 parent c595b05 commit 6b9142f
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,16 @@ private MsQuicApi(QUIC_API_TABLE* apiTable)
private static readonly Lazy<MsQuicApi> _api = new Lazy<MsQuicApi>(AllocateMsQuicApi);
internal static MsQuicApi Api => _api.Value;

internal static Version? Version { get; private set; }

internal static bool IsQuicSupported { get; }

internal static string MsQuicLibraryVersion { get; } = "unknown";
internal static string? NotSupportedReason { get; }

// workaround for https://github.com/microsoft/msquic/issues/4132
internal static bool SupportsAsyncCertValidation => Version >= new Version(2, 4, 0);

internal static bool UsesSChannelBackend { get; }

internal static bool Tls13ServerMayBeDisabled { get; }
Expand All @@ -69,6 +74,7 @@ static MsQuicApi()
{
bool loaded = false;
IntPtr msQuicHandle;
Version = default;

// MsQuic is using DualMode sockets and that will fail even for IPv4 if AF_INET6 is not available.
if (!Socket.OSSupportsIPv6)
Expand Down Expand Up @@ -135,7 +141,7 @@ static MsQuicApi()
}
return;
}
Version version = new Version((int)libVersion[0], (int)libVersion[1], (int)libVersion[2], (int)libVersion[3]);
Version = new Version((int)libVersion[0], (int)libVersion[1], (int)libVersion[2], (int)libVersion[3]);

paramSize = 64 * sizeof(sbyte);
sbyte* libGitHash = stackalloc sbyte[64];
Expand All @@ -150,11 +156,11 @@ static MsQuicApi()
}
string? gitHash = Marshal.PtrToStringUTF8((IntPtr)libGitHash);

MsQuicLibraryVersion = $"{Interop.Libraries.MsQuic} {version} ({gitHash})";
MsQuicLibraryVersion = $"{Interop.Libraries.MsQuic} {Version} ({gitHash})";

if (version < s_minMsQuicVersion)
if (Version < s_minMsQuicVersion)
{
NotSupportedReason = $"Incompatible MsQuic library version '{version}', expecting higher than '{s_minMsQuicVersion}'.";
NotSupportedReason = $"Incompatible MsQuic library version '{Version}', expecting higher than '{s_minMsQuicVersion}'.";
if (NetEventSource.Log.IsEnabled())
{
NetEventSource.Info(null, NotSupportedReason);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,24 @@ internal unsafe void StartAsyncCertificateValidation(void* certificatePtr, void*
}
}

// Hand-off rest of the work to the threadpool, certificatePtr and chainPtr are invalid inside the lambda.
QuicConnection thisConnection = _connection; // cannot use "this" inside lambda since SslConnectionOptions is struct
_ = Task.Run(() =>
QuicConnection connection = _connection;
if (MsQuicApi.SupportsAsyncCertValidation)
{
// hand-off rest of the work to the thread pool, certificatePtr and chainPtr are invalid beyond this point
_ = Task.Run(() =>
{
StartAsyncCertificateValidationCore(connection, certificate, certData, chainData, certDataRented, chainDataRented);
});
}
else
{
// due to a bug in MsQuic, we need to call the callback synchronously to close the connection properly when
// we reject the certificate
StartAsyncCertificateValidationCore(connection, certificate, certData, chainData, certDataRented, chainDataRented);
}

static void StartAsyncCertificateValidationCore(QuicConnection thisConnection, X509Certificate2? certificate, Memory<byte> certData, Memory<byte> chainData, byte[]? certDataRented, byte[]? chainDataRented)
{
QUIC_TLS_ALERT_CODES result;
try
{
Expand Down Expand Up @@ -158,7 +171,7 @@ internal unsafe void StartAsyncCertificateValidation(void* certificatePtr, void*
NetEventSource.Error(thisConnection, $"{thisConnection} ConnectionCertificateValidationComplete failed with {ThrowHelper.GetErrorMessageForStatus(status)}");
}
}
});
}
}

private QUIC_TLS_ALERT_CODES ValidateCertificate(X509Certificate2? certificate, Span<byte> certData, Span<byte> chainData)
Expand Down

0 comments on commit 6b9142f

Please sign in to comment.