public static void DeleteSniBinding(params Tuple <string, int>[] bindings) { if (bindings == null || bindings.Length == 0) { return; } if (Environment.OSVersion.Version < new Version(6, 2)) { return; } CallHttpApi( delegate { foreach (var binding in bindings) { HTTP_SERVICE_CONFIG_SSL_SNI_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SNI_SET(); HTTP_SERVICE_CONFIG_SSL_SNI_KEY httpServiceConfigSslKey = new HTTP_SERVICE_CONFIG_SSL_SNI_KEY(); httpServiceConfigSslKey.Host = binding.Item1; httpServiceConfigSslKey.IpPort = CreateSockAddrStorageStructure(binding.Item2); configSslSet.KeyDesc = httpServiceConfigSslKey; IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem( Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SNI_SET))); Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false); try { uint retVal = HttpDeleteServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSslSniCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); } } }); }
public static void DeleteSniBinding(params Tuple<string, int>[] bindings) { if (bindings == null || bindings.Length == 0) return; if (Environment.OSVersion.Version < new Version(6, 2)) { return; } CallHttpApi( delegate { foreach (var binding in bindings) { HTTP_SERVICE_CONFIG_SSL_SNI_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SNI_SET(); HTTP_SERVICE_CONFIG_SSL_SNI_KEY httpServiceConfigSslKey = new HTTP_SERVICE_CONFIG_SSL_SNI_KEY(); httpServiceConfigSslKey.Host = binding.Item1; httpServiceConfigSslKey.IpPort = CreateSockAddrStorageStructure(binding.Item2); configSslSet.KeyDesc = httpServiceConfigSslKey; IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem( Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SNI_SET))); Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false); try { uint retVal = HttpDeleteServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSslSniCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); } } }); }
public static void BindSni(Tuple<string, int> binding, byte[] hash, string storeName, Guid appId) { if (binding == null) throw new ArgumentNullException(nameof(binding)); if (hash == null) throw new ArgumentNullException(nameof(hash)); if (Environment.OSVersion.Version < new Version(6, 2)) { return; } CallHttpApi( delegate { HTTP_SERVICE_CONFIG_SSL_SNI_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SNI_SET(); HTTP_SERVICE_CONFIG_SSL_SNI_KEY httpServiceConfigSslKey = new HTTP_SERVICE_CONFIG_SSL_SNI_KEY(); httpServiceConfigSslKey.Host = binding.Item1; httpServiceConfigSslKey.IpPort = CreateSockAddrStorageStructure(binding.Item2); HTTP_SERVICE_CONFIG_SSL_PARAM configSslParam = new HTTP_SERVICE_CONFIG_SSL_PARAM(); GCHandle handleHash = GCHandle.Alloc(hash, GCHandleType.Pinned); configSslParam.AppId = appId; configSslParam.DefaultCertCheckMode = 0; configSslParam.DefaultFlags = 0; //HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT; configSslParam.DefaultRevocationFreshnessTime = 0; configSslParam.DefaultRevocationUrlRetrievalTimeout = 0; configSslParam.pSslCertStoreName = storeName; configSslParam.pSslHash = handleHash.AddrOfPinnedObject(); configSslParam.SslHashLength = hash.Length; configSslSet.ParamDesc = configSslParam; configSslSet.KeyDesc = httpServiceConfigSslKey; IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SNI_SET))); Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false); try { uint retVal = HttpSetServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSslSniCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); if (ERROR_ALREADY_EXISTS != retVal) { ThrowWin32ExceptionIfError(retVal); } else { retVal = HttpDeleteServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSslSniCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); retVal = HttpSetServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSslSniCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); } } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); if (handleHash.IsAllocated) handleHash.Free(); } }); }
public static SslSniInfo QuerySslSniInfo(Tuple<string, int> binding) { if (string.IsNullOrWhiteSpace(binding.Item1)) { return null; } if (Environment.OSVersion.Version < new Version(6, 2)) { return null; } SslSniInfo result = null; uint retVal; CallHttpApi(delegate { HTTP_SERVICE_CONFIG_SSL_SNI_KEY sslKey = new HTTP_SERVICE_CONFIG_SSL_SNI_KEY(); sslKey.Host = binding.Item1; sslKey.IpPort = CreateSockAddrStorageStructure(binding.Item2); HTTP_SERVICE_CONFIG_SSL_SNI_QUERY inputConfigInfoQuery = new HTTP_SERVICE_CONFIG_SSL_SNI_QUERY { QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryExact, KeyDesc = sslKey }; IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SNI_QUERY))); Marshal.StructureToPtr(inputConfigInfoQuery, pInputConfigInfo, false); IntPtr pOutputConfigInfo = IntPtr.Zero; int returnLength = 0; try { HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSslSniCertInfo; int inputConfigInfoSize = Marshal.SizeOf(inputConfigInfoQuery); retVal = HttpQueryServiceConfiguration(IntPtr.Zero, queryType, pInputConfigInfo, inputConfigInfoSize, pOutputConfigInfo, returnLength, out returnLength, IntPtr.Zero); if (retVal == ERROR_FILE_NOT_FOUND) return; if (ERROR_INSUFFICIENT_BUFFER == retVal) // ERROR_INSUFFICIENT_BUFFER = 122 { pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength); try { retVal = HttpQueryServiceConfiguration(IntPtr.Zero, queryType, pInputConfigInfo, inputConfigInfoSize, pOutputConfigInfo, returnLength, out returnLength, IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); var outputConfigInfo = (HTTP_SERVICE_CONFIG_SSL_SNI_SET) Marshal.PtrToStructure(pOutputConfigInfo, typeof(HTTP_SERVICE_CONFIG_SSL_SNI_SET)); byte[] hash = new byte[outputConfigInfo.ParamDesc.SslHashLength]; Marshal.Copy(outputConfigInfo.ParamDesc.pSslHash, hash, 0, hash.Length); Guid appId = outputConfigInfo.ParamDesc.AppId; string storeName = outputConfigInfo.ParamDesc.pSslCertStoreName; var host = outputConfigInfo.KeyDesc.Host; var ipPort = ReadSockAddrStorageStructure(outputConfigInfo.KeyDesc.IpPort); result = new SslSniInfo { AppId = appId, Hash = hash, StoreName = storeName, Port = ipPort.Port, Host = host }; } finally { Marshal.FreeCoTaskMem(pOutputConfigInfo); } } else { ThrowWin32ExceptionIfError(retVal); } } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); } }); return result; }
public static void BindSni(Tuple <string, int> binding, byte[] hash, string storeName, Guid appId) { if (binding == null) { throw new ArgumentNullException(nameof(binding)); } if (hash == null) { throw new ArgumentNullException(nameof(hash)); } if (Environment.OSVersion.Version < new Version(6, 2)) { return; } CallHttpApi( delegate { HTTP_SERVICE_CONFIG_SSL_SNI_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SNI_SET(); HTTP_SERVICE_CONFIG_SSL_SNI_KEY httpServiceConfigSslKey = new HTTP_SERVICE_CONFIG_SSL_SNI_KEY(); httpServiceConfigSslKey.Host = binding.Item1; httpServiceConfigSslKey.IpPort = CreateSockAddrStorageStructure(binding.Item2); HTTP_SERVICE_CONFIG_SSL_PARAM configSslParam = new HTTP_SERVICE_CONFIG_SSL_PARAM(); GCHandle handleHash = GCHandle.Alloc(hash, GCHandleType.Pinned); configSslParam.AppId = appId; configSslParam.DefaultCertCheckMode = 0; configSslParam.DefaultFlags = 0; //HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT; configSslParam.DefaultRevocationFreshnessTime = 0; configSslParam.DefaultRevocationUrlRetrievalTimeout = 0; configSslParam.pSslCertStoreName = storeName; configSslParam.pSslHash = handleHash.AddrOfPinnedObject(); configSslParam.SslHashLength = hash.Length; configSslSet.ParamDesc = configSslParam; configSslSet.KeyDesc = httpServiceConfigSslKey; IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SNI_SET))); Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false); try { uint retVal = HttpSetServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSslSniCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); if (ERROR_ALREADY_EXISTS != retVal) { ThrowWin32ExceptionIfError(retVal); } else { retVal = HttpDeleteServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSslSniCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); retVal = HttpSetServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSslSniCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); } } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); if (handleHash.IsAllocated) { handleHash.Free(); } } }); }
public static SslSniInfo QuerySslSniInfo(Tuple <string, int> binding) { if (string.IsNullOrWhiteSpace(binding.Item1)) { return(null); } if (Environment.OSVersion.Version < new Version(6, 2)) { return(null); } SslSniInfo result = null; uint retVal; CallHttpApi(delegate { HTTP_SERVICE_CONFIG_SSL_SNI_KEY sslKey = new HTTP_SERVICE_CONFIG_SSL_SNI_KEY(); sslKey.Host = binding.Item1; sslKey.IpPort = CreateSockAddrStorageStructure(binding.Item2); HTTP_SERVICE_CONFIG_SSL_SNI_QUERY inputConfigInfoQuery = new HTTP_SERVICE_CONFIG_SSL_SNI_QUERY { QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryExact, KeyDesc = sslKey }; IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SNI_QUERY))); Marshal.StructureToPtr(inputConfigInfoQuery, pInputConfigInfo, false); IntPtr pOutputConfigInfo = IntPtr.Zero; int returnLength = 0; try { HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSslSniCertInfo; int inputConfigInfoSize = Marshal.SizeOf(inputConfigInfoQuery); retVal = HttpQueryServiceConfiguration(IntPtr.Zero, queryType, pInputConfigInfo, inputConfigInfoSize, pOutputConfigInfo, returnLength, out returnLength, IntPtr.Zero); if (retVal == ERROR_FILE_NOT_FOUND) { return; } if (ERROR_INSUFFICIENT_BUFFER == retVal) // ERROR_INSUFFICIENT_BUFFER = 122 { pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength); try { retVal = HttpQueryServiceConfiguration(IntPtr.Zero, queryType, pInputConfigInfo, inputConfigInfoSize, pOutputConfigInfo, returnLength, out returnLength, IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); var outputConfigInfo = (HTTP_SERVICE_CONFIG_SSL_SNI_SET) Marshal.PtrToStructure(pOutputConfigInfo, typeof(HTTP_SERVICE_CONFIG_SSL_SNI_SET)); byte[] hash = new byte[outputConfigInfo.ParamDesc.SslHashLength]; Marshal.Copy(outputConfigInfo.ParamDesc.pSslHash, hash, 0, hash.Length); Guid appId = outputConfigInfo.ParamDesc.AppId; string storeName = outputConfigInfo.ParamDesc.pSslCertStoreName; var host = outputConfigInfo.KeyDesc.Host; var ipPort = ReadSockAddrStorageStructure(outputConfigInfo.KeyDesc.IpPort); result = new SslSniInfo { AppId = appId, Hash = hash, StoreName = storeName, Port = ipPort.Port, Host = host }; } finally { Marshal.FreeCoTaskMem(pOutputConfigInfo); } } else { ThrowWin32ExceptionIfError(retVal); } } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); } }); return(result); }