Example #1
0
        internal unsafe QuicSession(IQuicInteropApi nativeApi, QuicRegistration registration, byte[][] apln)
        {
            m_nativeApi = nativeApi;

            QuicHandle *handle = null;

            QuicNativeBuffer *buffers = stackalloc QuicNativeBuffer[apln.Length];

            try
            {
                for (int i = 0; i < apln.Length; i++)
                {
                    byte *allocated = (byte *)Marshal.AllocHGlobal((IntPtr)apln[i].Length);
                    buffers[i].Buffer = allocated;
                    buffers[i].Length = (uint)apln[i].Length;
                    apln[i].AsSpan().CopyTo(new Span <byte>(allocated, apln[i].Length));
                }

                m_nativeApi.SessionOpen(registration.m_handle, buffers, (uint)apln.Length, null, &handle);
                m_handle = handle;
            }
            finally
            {
                for (int i = 0; i < apln.Length; i++)
                {
                    Marshal.FreeHGlobal((IntPtr)buffers[i].Buffer);
                }
            }
        }
        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);
        }
        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);
        }