internal static async Task <QuicSecurityConfiguration> CreateQuicSecurityConfig(IQuicInteropApi api, QuicRegistration registration) { 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); api.SecConfigCreate(registration.m_handle, QuicSecConfigFlags.None, null, null, null, (void *)callback); return(configComplete); } var configCompleteDelegate = RunSecConfig(); var secConfig = await completionSource.Task.ConfigureAwait(false); GC.KeepAlive(configCompleteDelegate); return(secConfig); }
internal static async Task <QuicSecurityConfiguration> CreateQuicSecurityConfig(IQuicInteropApi api, QuicRegistration registration, QuicNativeCertificateHashStore certHashStore, string?principal, bool enableOcsp) { var flags = QuicSecConfigFlags.CertificateHashStore; 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 = certHashStore; 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); }
internal static async Task <QuicSecurityConfiguration> CreateQuicSecurityConfig(IQuicInteropApi api, QuicRegistration registration, string certFile, string keyFile, bool enableOcsp) { var flags = QuicSecConfigFlags.CertificateFile; 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); int maxCertFileLength = Encoding.UTF8.GetMaxByteCount(certFile.Length); Span <byte> maxCertFileSpan = maxCertFileLength < 256 ? stackalloc byte[maxCertFileLength] : new byte[maxCertFileLength]; int maxKeyFileLength = Encoding.UTF8.GetMaxByteCount(keyFile.Length); Span <byte> maxKeyFileSpan = maxKeyFileLength < 256 ? stackalloc byte[maxKeyFileLength] : new byte[maxKeyFileLength]; fixed(byte *certFileBytePtr = maxCertFileSpan) fixed(byte *keyFileBytePtr = maxKeyFileSpan) { fixed(char *certFileStrPtr = certFile) { int actualLength = Encoding.UTF8.GetBytes(certFileStrPtr, certFile.Length, certFileBytePtr, maxCertFileSpan.Length); maxCertFileSpan[actualLength] = 0; } fixed(char *keyFileStrPtr = keyFile) { int actualLength = Encoding.UTF8.GetBytes(keyFileStrPtr, keyFile.Length, keyFileBytePtr, maxKeyFileSpan.Length); maxKeyFileSpan[actualLength] = 0; } var file = new QuicNativeCertificateFile(); file.CertificateFile = certFileBytePtr; file.PrivateKeyFile = keyFileBytePtr; api.SecConfigCreate(registration.m_handle, flags, &file, null, null, (void *)callback); } return(configComplete); } var configCompleteDelegate = RunSecConfig(); var secConfig = await completionSource.Task.ConfigureAwait(false); GC.KeepAlive(configCompleteDelegate); return(secConfig); }