1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Collections.Generic; 7 using System.Net.Security; 8 using System.Runtime.InteropServices; 9 using System.Text; 10 using Microsoft.Win32.SafeHandles; 11 12 internal static partial class Interop 13 { 14 internal static partial class Ssl 15 { AppVerifyCallback(IntPtr storeCtx, IntPtr arg)16 internal delegate int AppVerifyCallback(IntPtr storeCtx, IntPtr arg); ClientCertCallback(IntPtr ssl, out IntPtr x509, out IntPtr pkey)17 internal delegate int ClientCertCallback(IntPtr ssl, out IntPtr x509, out IntPtr pkey); SslCtxSetAlpnCallback(IntPtr ssl, out byte* outp, out byte outlen, byte* inp, uint inlen, IntPtr arg)18 internal unsafe delegate int SslCtxSetAlpnCallback(IntPtr ssl, out byte* outp, out byte outlen, byte* inp, uint inlen, IntPtr arg); 19 20 [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxCreate")] SslCtxCreate(IntPtr method)21 internal static extern SafeSslContextHandle SslCtxCreate(IntPtr method); 22 23 [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxDestroy")] SslCtxDestroy(IntPtr ctx)24 internal static extern void SslCtxDestroy(IntPtr ctx); 25 26 [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetCertVerifyCallback")] SslCtxSetCertVerifyCallback(IntPtr ctx, AppVerifyCallback cb, IntPtr arg)27 internal static extern void SslCtxSetCertVerifyCallback(IntPtr ctx, AppVerifyCallback cb, IntPtr arg); 28 29 [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetClientCertCallback")] SslCtxSetClientCertCallback(IntPtr ctx, ClientCertCallback callback)30 internal static extern void SslCtxSetClientCertCallback(IntPtr ctx, ClientCertCallback callback); 31 32 [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetAlpnProtos")] SslCtxSetAlpnProtos(SafeSslContextHandle ctx, IntPtr protos, int len)33 internal static extern int SslCtxSetAlpnProtos(SafeSslContextHandle ctx, IntPtr protos, int len); 34 35 [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetAlpnSelectCb")] SslCtxSetAlpnSelectCb(SafeSslContextHandle ctx, SslCtxSetAlpnCallback callback, IntPtr arg)36 internal static unsafe extern void SslCtxSetAlpnSelectCb(SafeSslContextHandle ctx, SslCtxSetAlpnCallback callback, IntPtr arg); 37 SslCtxSetAlpnProtos(SafeSslContextHandle ctx, List<SslApplicationProtocol> protocols)38 internal static unsafe int SslCtxSetAlpnProtos(SafeSslContextHandle ctx, List<SslApplicationProtocol> protocols) 39 { 40 byte[] buffer = ConvertAlpnProtocolListToByteArray(protocols); 41 fixed (byte* b = buffer) 42 { 43 return SslCtxSetAlpnProtos(ctx, (IntPtr)b, buffer.Length); 44 } 45 } 46 ConvertAlpnProtocolListToByteArray(List<SslApplicationProtocol> applicationProtocols)47 internal static byte[] ConvertAlpnProtocolListToByteArray(List<SslApplicationProtocol> applicationProtocols) 48 { 49 int protocolSize = 0; 50 foreach (SslApplicationProtocol protocol in applicationProtocols) 51 { 52 if (protocol.Protocol.Length == 0 || protocol.Protocol.Length > byte.MaxValue) 53 { 54 throw new ArgumentException(SR.net_ssl_app_protocols_invalid, nameof(applicationProtocols)); 55 } 56 57 protocolSize += protocol.Protocol.Length + 1; 58 } 59 60 byte[] buffer = new byte[protocolSize]; 61 var offset = 0; 62 foreach (SslApplicationProtocol protocol in applicationProtocols) 63 { 64 buffer[offset++] = (byte)(protocol.Protocol.Length); 65 protocol.Protocol.Span.CopyTo(new Span<byte>(buffer).Slice(offset)); 66 offset += protocol.Protocol.Length; 67 } 68 69 return buffer; 70 } 71 } 72 } 73 74 namespace Microsoft.Win32.SafeHandles 75 { 76 internal sealed class SafeSslContextHandle : SafeHandle 77 { SafeSslContextHandle()78 private SafeSslContextHandle() 79 : base(IntPtr.Zero, true) 80 { 81 } 82 SafeSslContextHandle(IntPtr handle, bool ownsHandle)83 internal SafeSslContextHandle(IntPtr handle, bool ownsHandle) 84 : base(handle, ownsHandle) 85 { 86 } 87 88 public override bool IsInvalid 89 { 90 get { return handle == IntPtr.Zero; } 91 } 92 ReleaseHandle()93 protected override bool ReleaseHandle() 94 { 95 Interop.Ssl.SslCtxDestroy(handle); 96 SetHandle(IntPtr.Zero); 97 return true; 98 } 99 } 100 } 101