public unsafe Task <QuicSecurityConfiguration> CreateSecurityConfiguration(ReadOnlySpan <byte> hash) { #pragma warning disable CA1303 // Do not pass literals as localized parameters if (hash.Length != 20) { throw new ArgumentOutOfRangeException(nameof(hash), "Hash must be 20 bytes long"); } #pragma warning restore CA1303 // Do not pass literals as localized parameters var nativeHash = new QuicNativeCertificateHash(); hash.CopyTo(new Span <byte>(nativeHash.ShaHash, 20)); return(QuicSecurityConfiguration.CreateQuicSecurityConfig(m_nativeApi, this, nativeHash, null, false)); }
internal static async Task <QuicSecurityConfiguration> CreateQuicSecurityConfig(IQuicInteropApi api, QuicRegistration registration, QuicNativeCertificateHash certHash, string?principal, bool enableOcsp) { var flags = QuicSecConfigFlags.CertificateHash; if (enableOcsp) { flags |= QuicSecConfigFlags.EnableOcsp; } var completionSource = new TaskCompletionSource <QuicSecurityConfiguration>(TaskCreationOptions.RunContinuationsAsynchronously); unsafe QuicSecConfigCreateComplete RunSecConfig() { QuicSecConfigCreateComplete configComplete = (void *context, int status, QuicNativeSecConfig *config) => { completionSource.SetResult(new QuicSecurityConfiguration(api, config)); }; var callback = Marshal.GetFunctionPointerForDelegate(configComplete); var certHashCopy = certHash; if (principal == null) { api.SecConfigCreate(registration.m_handle, flags, &certHashCopy, null, null, (void *)callback); } else { int maxPrincipalLength = Encoding.UTF8.GetMaxByteCount(principal.Length); Span <byte> principalSpan = maxPrincipalLength < 256 ? stackalloc byte[maxPrincipalLength] : new byte[maxPrincipalLength]; fixed(byte *principalBytePtr = principalSpan) { fixed(char *principalStrPtr = principal) { int actualLength = Encoding.UTF8.GetBytes(principalStrPtr, principal.Length, principalBytePtr, principalSpan.Length); principalSpan[actualLength] = 0; } api.SecConfigCreate(registration.m_handle, flags, &certHashCopy, principalBytePtr, null, (void *)callback); } } return(configComplete); } var configCompleteDelegate = RunSecConfig(); var secConfig = await completionSource.Task.ConfigureAwait(false); GC.KeepAlive(configCompleteDelegate); return(secConfig); }