/// <summary> /// Удаляет привязку сертификата к сетевому адресу и порту. /// </summary> public static void DeleteCertificateBinding(IPEndPoint endPoint) { CallHttpApi(() => { var socketAddressHandle = CreateNativeSocketAddress(endPoint); var socketAddressPtr = socketAddressHandle.AddrOfPinnedObject(); var configInfo = new HTTP_SERVICE_CONFIG_SSL_SET { KeyDesc = new HTTP_SERVICE_CONFIG_SSL_KEY(socketAddressPtr) }; var queryPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET))); Marshal.StructureToPtr(configInfo, queryPtr, false); try { var invokeResult = HttpDeleteServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, queryPtr, Marshal.SizeOf(configInfo), IntPtr.Zero); ThrowWin32ExceptionIfError(invokeResult); } finally { Marshal.FreeCoTaskMem(queryPtr); if (socketAddressHandle.IsAllocated) { socketAddressHandle.Free(); } } }); }
public static HttpConfigSsl GetHttpSslConfig() { HttpConfigSsl result = new HttpConfigSsl(); int size; for (int count = 0;; count++) { HTTP_SERVICE_CONFIG_SSL_QUERY query = new HTTP_SERVICE_CONFIG_SSL_QUERY(HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryNext, new HTTP_SERVICE_CONFIG_SSL_KEY(), count); ErrorCode errorCode = HttpQueryServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, ref query, Marshal.SizeOf(query), null, 0, out size, IntPtr.Zero); if (errorCode != ErrorCode.ERROR_SUCCESS) { if (errorCode == ErrorCode.ERROR_NO_MORE_ITEMS) { break; } if (errorCode != ErrorCode.ERROR_INSUFFICIENT_BUFFER) { throw new Win32Exception((int)errorCode); } byte[] buffer = new byte[size]; fixed(byte *b = buffer) { errorCode = HttpQueryServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, ref query, Marshal.SizeOf(query), b, size, out size, IntPtr.Zero); if (errorCode != ErrorCode.ERROR_SUCCESS) { throw new Win32Exception((int)errorCode); } HTTP_SERVICE_CONFIG_SSL_SET output = (HTTP_SERVICE_CONFIG_SSL_SET)Marshal.PtrToStructure((IntPtr)b, typeof(HTTP_SERVICE_CONFIG_SSL_SET)); result.Add(output.KeyDesc, output.ParamDesc); } } } return(result); }
public static void DeleteSsl(IPEndPoint iPEndPoint) { if (iPEndPoint == null) { return; } using (HttpConfigSslEntryInterop interop = new HttpConfigSslEntryInterop(iPEndPoint)) { HTTP_SERVICE_CONFIG_SSL_SET configInformation = interop.GetConfigInformation(); ErrorCode errorCode = HttpDeleteServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, ref configInformation, Marshal.SizeOf(configInformation), IntPtr.Zero); if (errorCode != ErrorCode.ERROR_FILE_NOT_FOUND && errorCode != ErrorCode.ERROR_SUCCESS) { throw new Win32Exception((int)errorCode); } } }
public static void CreateSsl(HttpConfigSslEntry entry) { if (entry == null) { return; } using (HttpConfigSslEntryInterop interop = new HttpConfigSslEntryInterop(entry)) { HTTP_SERVICE_CONFIG_SSL_SET configInformation = interop.GetConfigInformation(); ErrorCode errorCode = HttpSetServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, ref configInformation, Marshal.SizeOf(configInformation), IntPtr.Zero); if (errorCode != ErrorCode.ERROR_SUCCESS) { throw new Win32Exception((int)errorCode); } } }
public static void DeleteCertificateBinding(params IPEndPoint[] ipPorts) { if (ipPorts == null || ipPorts.Length == 0) { return; } CallHttpApi( delegate { foreach (var ipPort in ipPorts) { HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET(); GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort); IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject(); HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey = new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort); configSslSet.KeyDesc = httpServiceConfigSslKey; IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem( Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET))); Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false); try { uint retVal = HttpDeleteServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); if (sockAddrHandle.IsAllocated) { sockAddrHandle.Free(); } } } }); }
/// <summary> /// Create the parameter for the configuration operation /// </summary> private static HTTP_SERVICE_CONFIG_SSL_SET CreateParameter(IPAddress ipAddress, int port, byte[] hash, StoreName store) { HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET(); HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey = new HTTP_SERVICE_CONFIG_SSL_KEY(); HTTP_SERVICE_CONFIG_SSL_PARAM configSslParam = new HTTP_SERVICE_CONFIG_SSL_PARAM(); IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port); // serialize the endpoint to a SocketAddress and create an array to hold the values. Pin the array. SocketAddress socketAddress = ipEndPoint.Serialize(); byte[] socketBytes = new byte[socketAddress.Size]; GCHandle handleSocketAddress = GCHandle.Alloc(socketBytes, GCHandleType.Pinned); // Should copy the first 16 bytes (the SocketAddress has a 32 byte buffer, the size will only be 16, //which is what the SOCKADDR accepts for (int i = 0; i < socketAddress.Size; ++i) { socketBytes[i] = socketAddress[i]; } httpServiceConfigSslKey.pIpPort = handleSocketAddress.AddrOfPinnedObject(); GCHandle handleHash = GCHandle.Alloc(hash, GCHandleType.Pinned); configSslParam.AppId = new Guid((Assembly.GetEntryAssembly().GetCustomAttributes(typeof(GuidAttribute), false)[0] as GuidAttribute).Value); configSslParam.DefaultCertCheckMode = 0; configSslParam.DefaultFlags = HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT; configSslParam.DefaultRevocationFreshnessTime = 0; configSslParam.DefaultRevocationUrlRetrievalTimeout = 0; configSslParam.pSslCertStoreName = store.ToString(); configSslParam.pSslHash = handleHash.AddrOfPinnedObject(); configSslParam.SslHashLength = hash.Length; configSslSet.ParamDesc = configSslParam; configSslSet.KeyDesc = httpServiceConfigSslKey; return(configSslSet); }
/// <summary> /// Deletes a new SSL certificate binding. /// </summary> public static void DeleteSslCertificateBinding(IPAddress address, ushort port) { if (address == null) { throw new ArgumentNullException("address"); } // initialize library. HttpError error = NativeMethods.HttpInitialize( new HTTPAPI_VERSION(1, 0), HttpInitFlag.HTTP_INITIALIZE_CONFIG, IntPtr.Zero); if (error != HttpError.NO_ERROR) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Could not initialize HTTP library.\r\nError={0}", error); } IntPtr pAddress = IntPtr.Zero; IntPtr pConfigInfo = IntPtr.Zero; try { pAddress = ToIntPtr(address, port); HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET(); configSslSet.KeyDesc.pIpPort = pAddress; int size = Marshal.SizeOf <HTTP_SERVICE_CONFIG_SSL_SET>(); pConfigInfo = Marshal.AllocCoTaskMem(size); Marshal.StructureToPtr(configSslSet, pConfigInfo, false); error = NativeMethods.HttpDeleteServiceConfiguration( IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pConfigInfo, size, IntPtr.Zero); if (error != HttpError.NO_ERROR) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Could not delete existing SSL certificate binding.\r\nError={0}", error); } } finally { if (pConfigInfo != IntPtr.Zero) { Marshal.FreeCoTaskMem(pConfigInfo); } if (pAddress != IntPtr.Zero) { Marshal.FreeCoTaskMem(pAddress); } NativeMethods.HttpTerminate(HttpInitFlag.HTTP_INITIALIZE_CONFIG, IntPtr.Zero); } }
/// <summary> /// Creates a new SSL certificate binding. /// </summary> public static void SetSslCertificateBinding(SslCertificateBinding binding) { if (binding == null) { throw new ArgumentNullException("binding"); } // initialize library. HttpError error = NativeMethods.HttpInitialize( new HTTPAPI_VERSION(1, 0), HttpInitFlag.HTTP_INITIALIZE_CONFIG, IntPtr.Zero); if (error != HttpError.NO_ERROR) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Could not initialize HTTP library.\r\nError={0}", error); } IntPtr pAddress = IntPtr.Zero; IntPtr pThumprint = IntPtr.Zero; IntPtr pConfigInfo = IntPtr.Zero; try { pAddress = ToIntPtr(binding.IPAddress, binding.Port); byte[] thumbprint = Utils.FromHexString(binding.Thumbprint); pThumprint = Marshal.AllocCoTaskMem(thumbprint.Length); Marshal.Copy(thumbprint, 0, pThumprint, thumbprint.Length); HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET(); configSslSet.KeyDesc.pIpPort = pAddress; configSslSet.ParamDesc.pSslHash = pThumprint; configSslSet.ParamDesc.SslHashLength = thumbprint.Length; configSslSet.ParamDesc.AppId = binding.ApplicationId; configSslSet.ParamDesc.pSslCertStoreName = binding.StoreName; configSslSet.ParamDesc.DefaultCertCheckMode = binding.DefaultCertCheckMode; configSslSet.ParamDesc.DefaultFlags = binding.DefaultFlags; configSslSet.ParamDesc.DefaultRevocationFreshnessTime = binding.DefaultRevocationFreshnessTime; configSslSet.ParamDesc.DefaultRevocationUrlRetrievalTimeout = binding.DefaultRevocationUrlRetrievalTimeout; configSslSet.ParamDesc.pDefaultSslCtlIdentifier = binding.DefaultSslCtlIdentifier; configSslSet.ParamDesc.pDefaultSslCtlStoreName = binding.DefaultSslCtlStoreName; int size = Marshal.SizeOf <HTTP_SERVICE_CONFIG_SSL_SET>(); pConfigInfo = Marshal.AllocCoTaskMem(size); Marshal.StructureToPtr(configSslSet, pConfigInfo, false); error = NativeMethods.HttpSetServiceConfiguration( IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pConfigInfo, size, IntPtr.Zero); if (error == HttpError.ERROR_ALREADY_EXISTS) { error = NativeMethods.HttpDeleteServiceConfiguration( IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pConfigInfo, size, IntPtr.Zero); if (error != HttpError.NO_ERROR) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Could not delete existing SSL certificate binding.\r\nError={0}", error); } error = NativeMethods.HttpSetServiceConfiguration( IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pConfigInfo, size, IntPtr.Zero); } if (error != HttpError.NO_ERROR) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Could not create SSL certificate binding.\r\nError={0}", error); } } finally { if (pConfigInfo != IntPtr.Zero) { Marshal.FreeCoTaskMem(pConfigInfo); } if (pAddress != IntPtr.Zero) { Marshal.FreeCoTaskMem(pAddress); } if (pThumprint != IntPtr.Zero) { Marshal.FreeCoTaskMem(pThumprint); } NativeMethods.HttpTerminate(HttpInitFlag.HTTP_INITIALIZE_CONFIG, IntPtr.Zero); } }
/// <summary> /// Fetches the current SSL certificate configuration. /// </summary> public static List <SslCertificateBinding> GetSslCertificateBindings() { List <SslCertificateBinding> bindings = new List <SslCertificateBinding>(); // initialize library. HttpError error = NativeMethods.HttpInitialize( new HTTPAPI_VERSION(1, 0), HttpInitFlag.HTTP_INITIALIZE_CONFIG, IntPtr.Zero); if (error != HttpError.NO_ERROR) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Could not initialize HTTP library.\r\nError={0}", error); } // set up the iterator. HTTP_SERVICE_CONFIG_SSL_QUERY query = new HTTP_SERVICE_CONFIG_SSL_QUERY(); query.QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryNext; query.KeyDesc.pIpPort = IntPtr.Zero; IntPtr pInput = Marshal.AllocHGlobal(Marshal.SizeOf <HTTP_SERVICE_CONFIG_SSL_QUERY>()); NativeMethods.ZeroMemory(pInput, Marshal.SizeOf <HTTP_SERVICE_CONFIG_SSL_QUERY>()); IntPtr pOutput = IntPtr.Zero; try { // loop through each record. for (query.dwToken = 0; error == HttpError.NO_ERROR; query.dwToken++) { // get the size of buffer to allocate. Marshal.StructureToPtr(query, pInput, true); int requiredBufferLength = 0; error = NativeMethods.HttpQueryServiceConfiguration( IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInput, Marshal.SizeOf <HTTP_SERVICE_CONFIG_SSL_QUERY>(), pOutput, requiredBufferLength, out requiredBufferLength, IntPtr.Zero); if (error == HttpError.ERROR_NO_MORE_ITEMS) { break; } if (error != HttpError.ERROR_INSUFFICIENT_BUFFER) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Could not read SSL configuration information.\r\nError={0}", error); } // allocate the buffer. pOutput = Marshal.AllocHGlobal(requiredBufferLength); NativeMethods.ZeroMemory(pOutput, requiredBufferLength); // get the actual data. error = NativeMethods.HttpQueryServiceConfiguration( IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInput, Marshal.SizeOf <HTTP_SERVICE_CONFIG_SSL_QUERY>(), pOutput, requiredBufferLength, out requiredBufferLength, IntPtr.Zero); if (error != HttpError.NO_ERROR) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Could not read SSL configuration information.\r\nError={0}", error); } HTTP_SERVICE_CONFIG_SSL_SET sslSet = (HTTP_SERVICE_CONFIG_SSL_SET)Marshal.PtrToStructure <HTTP_SERVICE_CONFIG_SSL_SET>(pOutput); short family = Marshal.ReadInt16(sslSet.KeyDesc.pIpPort); SslCertificateBinding binding = new SslCertificateBinding(); if (family == AF_INET) { SOCKADDR_IN inet = (SOCKADDR_IN)Marshal.PtrToStructure <SOCKADDR_IN>(sslSet.KeyDesc.pIpPort); binding.IPAddress = new IPAddress(inet.addr); binding.Port = inet.port; } if (family == AF_INET6) { SOCKADDR_IN6 inet = (SOCKADDR_IN6)Marshal.PtrToStructure <SOCKADDR_IN6>(sslSet.KeyDesc.pIpPort); binding.IPAddress = new IPAddress(inet.addr, inet.scopeID); binding.Port = inet.port; } binding.Port = (ushort)(((binding.Port & 0xFF00) >> 8) | ((binding.Port & 0x00FF) << 8)); byte[] bytes = new byte[sslSet.ParamDesc.SslHashLength]; Marshal.Copy(sslSet.ParamDesc.pSslHash, bytes, 0, bytes.Length); binding.Thumbprint = Utils.ToHexString(bytes); binding.ApplicationId = sslSet.ParamDesc.AppId; binding.StoreName = sslSet.ParamDesc.pSslCertStoreName; binding.DefaultCertCheckMode = sslSet.ParamDesc.DefaultCertCheckMode; binding.DefaultRevocationFreshnessTime = sslSet.ParamDesc.DefaultRevocationFreshnessTime; binding.DefaultRevocationUrlRetrievalTimeout = sslSet.ParamDesc.DefaultRevocationUrlRetrievalTimeout; binding.DefaultSslCtlIdentifier = sslSet.ParamDesc.pDefaultSslCtlIdentifier; binding.DefaultSslCtlStoreName = sslSet.ParamDesc.pDefaultSslCtlStoreName; binding.DefaultFlags = sslSet.ParamDesc.DefaultFlags; bindings.Add(binding); Marshal.FreeHGlobal(pOutput); pOutput = IntPtr.Zero; } } finally { if (pInput != IntPtr.Zero) { Marshal.DestroyStructure <HTTP_SERVICE_CONFIG_SSL_QUERY>(pInput); Marshal.FreeHGlobal(pInput); } if (pOutput != IntPtr.Zero) { Marshal.FreeHGlobal(pOutput); } NativeMethods.HttpTerminate(HttpInitFlag.HTTP_INITIALIZE_CONFIG, IntPtr.Zero); } return(bindings); }
static extern ErrorCode HttpSetServiceConfiguration(IntPtr nullHandle, HTTP_SERVICE_CONFIG_ID configId, ref HTTP_SERVICE_CONFIG_SSL_SET configInformation, int configInformationLength, IntPtr pOverlapped);
/// <summary> /// Создает привязку сертификата к сетевому адресу и порту. /// </summary> public static void CreateBindCertificate(IPEndPoint endPoint, byte[] certificate, StoreName certificateStore, Guid applicationId) { CallHttpApi(() => { var socketAddressHandle = CreateNativeSocketAddress(endPoint); var socketAddressPtr = socketAddressHandle.AddrOfPinnedObject(); var certificateHandle = GCHandle.Alloc(certificate, GCHandleType.Pinned); // Запись конфигурации с информацией о привязке сертификата к сетевому адресу и порту var configInfo = new HTTP_SERVICE_CONFIG_SSL_SET { KeyDesc = new HTTP_SERVICE_CONFIG_SSL_KEY(socketAddressPtr), ParamDesc = new HTTP_SERVICE_CONFIG_SSL_PARAM { AppId = applicationId, DefaultCertCheckMode = 0, DefaultFlags = 0, DefaultRevocationFreshnessTime = 0, DefaultRevocationUrlRetrievalTimeout = 0, pSslCertStoreName = certificateStore.ToString(), pSslHash = certificateHandle.AddrOfPinnedObject(), SslHashLength = certificate.Length } }; var configInfoPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET))); Marshal.StructureToPtr(configInfo, configInfoPtr, false); const HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo; try { var invokeResult = HttpSetServiceConfiguration(IntPtr.Zero, queryType, configInfoPtr, Marshal.SizeOf(configInfo), IntPtr.Zero); if (invokeResult == ERROR_ALREADY_EXISTS) { // Удаление записи invokeResult = HttpDeleteServiceConfiguration(IntPtr.Zero, queryType, configInfoPtr, Marshal.SizeOf(configInfo), IntPtr.Zero); ThrowWin32ExceptionIfError(invokeResult); // Создание записи invokeResult = HttpSetServiceConfiguration(IntPtr.Zero, queryType, configInfoPtr, Marshal.SizeOf(configInfo), IntPtr.Zero); ThrowWin32ExceptionIfError(invokeResult); } else { ThrowWin32ExceptionIfError(invokeResult); } } finally { Marshal.FreeCoTaskMem(configInfoPtr); if (certificateHandle.IsAllocated) { certificateHandle.Free(); } if (socketAddressHandle.IsAllocated) { socketAddressHandle.Free(); } } }); }
public static void DeleteCertificateBinding(params IPEndPoint[] ipPorts) { if (ipPorts == null || ipPorts.Length == 0) return; CallHttpApi( delegate { foreach (var ipPort in ipPorts) { HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET(); GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort); IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject(); HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey = new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort); configSslSet.KeyDesc = httpServiceConfigSslKey; IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem( Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET))); Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false); try { uint retVal = HttpDeleteServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); if (sockAddrHandle.IsAllocated) sockAddrHandle.Free(); } } }); }
public static void BindCertificate(IPEndPoint ipPort, byte[] hash, string storeName, Guid appId) { if (ipPort == null) throw new ArgumentNullException(nameof(ipPort)); if (hash == null) throw new ArgumentNullException(nameof(hash)); CallHttpApi( delegate { HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET(); GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort); IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject(); HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey = new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort); 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_SET))); Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false); try { uint retVal = HttpSetServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); if (ERROR_ALREADY_EXISTS != retVal) { ThrowWin32ExceptionIfError(retVal); } else { retVal = HttpDeleteServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); retVal = HttpSetServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); } } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); if (handleHash.IsAllocated) handleHash.Free(); if (sockAddrHandle.IsAllocated) sockAddrHandle.Free(); } }); }
public static void BindCertificate(string ipAddress, int port, byte[] hash) { TraceSource.WriteInfo( PortAclUtility.TraceType, "Started to Bind certificate to port. ipAddress: {0}, port: {1}, hash: {2}. Current thread identity: {3}", ipAddress, port, BitConverter.ToString(hash), Thread.CurrentPrincipal.Identity.Name); uint retVal = (uint)NOERROR; // NOERROR = 0 HTTPAPI_VERSION httpApiVersion = new HTTPAPI_VERSION(1, 0); retVal = HttpInitialize(httpApiVersion, HTTP_INITIALIZE_CONFIG, IntPtr.Zero); TraceSource.WriteInfo( PortAclUtility.TraceType, "HttpInitialize completed with return value: {0}.", retVal); if ((uint)NOERROR == retVal) { HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET(); HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey = new HTTP_SERVICE_CONFIG_SSL_KEY(); HTTP_SERVICE_CONFIG_SSL_PARAM configSslParam = new HTTP_SERVICE_CONFIG_SSL_PARAM(); IPAddress ip = IPAddress.Any; //IPAddress.Parse("0.0.0.0"); IPEndPoint ipEndPoint = new IPEndPoint(ip, port); // serialize the endpoint to a SocketAddress and create an array to hold the values. Pin the array. SocketAddress socketAddress = ipEndPoint.Serialize(); byte[] socketBytes = new byte[socketAddress.Size]; GCHandle handleSocketAddress = GCHandle.Alloc(socketBytes, GCHandleType.Pinned); // Should copy the first 16 bytes (the SocketAddress has a 32 byte buffer, the size will only be 16, //which is what the SOCKADDR accepts for (int i = 0; i < socketAddress.Size; ++i) { socketBytes[i] = socketAddress[i]; } httpServiceConfigSslKey.pIpPort = handleSocketAddress.AddrOfPinnedObject(); GCHandle handleHash = GCHandle.Alloc(hash, GCHandleType.Pinned); configSslParam.AppId = Guid.NewGuid(); configSslParam.DefaultCertCheckMode = 0; configSslParam.DefaultFlags = HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT; configSslParam.DefaultRevocationFreshnessTime = 0; configSslParam.DefaultRevocationUrlRetrievalTimeout = 0; configSslParam.pSslCertStoreName = StoreName.My.ToString(); 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_SET))); Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false); retVal = HttpSetServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); TraceSource.WriteInfo( PortAclUtility.TraceType, "HttpSetServiceConfiguration completed with return value: {0}.", retVal); if ((uint)ERROR_ALREADY_EXISTS == retVal) // ERROR_ALREADY_EXISTS = 183 { retVal = HttpDeleteServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); TraceSource.WriteInfo( PortAclUtility.TraceType, "HttpDeleteServiceConfiguration completed with return value: {0}.", retVal); if ((uint)NOERROR == retVal) { retVal = HttpSetServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); TraceSource.WriteInfo( PortAclUtility.TraceType, "HttpSetServiceConfiguration completed with return value: {0}.", retVal); } } handleSocketAddress.Free(); handleHash.Free(); Marshal.FreeCoTaskMem(pInputConfigInfo); HttpTerminate(HTTP_INITIALIZE_CONFIG, IntPtr.Zero); } if ((uint)NOERROR != retVal) { TraceSource.WriteError( PortAclUtility.TraceType, "BindCertificate failed with error: {0}.", retVal); throw new Win32Exception(Convert.ToInt32(retVal)); } }
/// <summary> /// Creates a new SSL certificate binding. /// </summary> public static void SetSslCertificateBinding(SslCertificateBinding binding) { if (binding == null) throw new ArgumentNullException("binding"); // initialize library. HttpError error = NativeMethods.HttpInitialize( new HTTPAPI_VERSION(1,0), HttpInitFlag.HTTP_INITIALIZE_CONFIG, IntPtr.Zero); if (error != HttpError.NO_ERROR) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Could not initialize HTTP library.\r\nError={0}", error); } IntPtr pAddress = IntPtr.Zero; IntPtr pThumprint = IntPtr.Zero; IntPtr pConfigInfo = IntPtr.Zero; try { pAddress = ToIntPtr(binding.IPAddress, binding.Port); byte[] thumbprint = Utils.FromHexString(binding.Thumbprint); pThumprint = Marshal.AllocCoTaskMem(thumbprint.Length); Marshal.Copy(thumbprint, 0, pThumprint, thumbprint.Length); HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET(); configSslSet.KeyDesc.pIpPort = pAddress; configSslSet.ParamDesc.pSslHash = pThumprint; configSslSet.ParamDesc.SslHashLength = thumbprint.Length; configSslSet.ParamDesc.AppId = binding.ApplicationId; configSslSet.ParamDesc.pSslCertStoreName = binding.StoreName; configSslSet.ParamDesc.DefaultCertCheckMode = binding.DefaultCertCheckMode; configSslSet.ParamDesc.DefaultFlags = binding.DefaultFlags; configSslSet.ParamDesc.DefaultRevocationFreshnessTime = binding.DefaultRevocationFreshnessTime; configSslSet.ParamDesc.DefaultRevocationUrlRetrievalTimeout = binding.DefaultRevocationUrlRetrievalTimeout; configSslSet.ParamDesc.pDefaultSslCtlIdentifier = binding.DefaultSslCtlIdentifier; configSslSet.ParamDesc.pDefaultSslCtlStoreName = binding.DefaultSslCtlStoreName; int size = Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET)); pConfigInfo = Marshal.AllocCoTaskMem(size); Marshal.StructureToPtr(configSslSet, pConfigInfo, false); error = NativeMethods.HttpSetServiceConfiguration( IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pConfigInfo, size, IntPtr.Zero); if (error == HttpError.ERROR_ALREADY_EXISTS) { error = NativeMethods.HttpDeleteServiceConfiguration( IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pConfigInfo, size, IntPtr.Zero); if (error != HttpError.NO_ERROR) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Could not delete existing SSL certificate binding.\r\nError={0}", error); } error = NativeMethods.HttpSetServiceConfiguration( IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pConfigInfo, size, IntPtr.Zero); } if (error != HttpError.NO_ERROR) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Could not create SSL certificate binding.\r\nError={0}", error); } } finally { if (pConfigInfo != IntPtr.Zero) { Marshal.FreeCoTaskMem(pConfigInfo); } if (pAddress != IntPtr.Zero) { Marshal.FreeCoTaskMem(pAddress); } if (pThumprint != IntPtr.Zero) { Marshal.FreeCoTaskMem(pThumprint); } NativeMethods.HttpTerminate(HttpInitFlag.HTTP_INITIALIZE_CONFIG, IntPtr.Zero); } }
static extern ErrorCode HttpDeleteServiceConfiguration(IntPtr serviceIntPtr, HTTP_SERVICE_CONFIG_ID configId, ref HTTP_SERVICE_CONFIG_SSL_SET configInformation, int configInformationLength, IntPtr pOverlapped);
/// <summary> /// Deletes a new SSL certificate binding. /// </summary> public static void DeleteSslCertificateBinding(IPAddress address, ushort port) { if (address == null) throw new ArgumentNullException("address"); // initialize library. HttpError error = NativeMethods.HttpInitialize( new HTTPAPI_VERSION(1, 0), HttpInitFlag.HTTP_INITIALIZE_CONFIG, IntPtr.Zero); if (error != HttpError.NO_ERROR) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Could not initialize HTTP library.\r\nError={0}", error); } IntPtr pAddress = IntPtr.Zero; IntPtr pConfigInfo = IntPtr.Zero; try { pAddress = ToIntPtr(address, port); HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET(); configSslSet.KeyDesc.pIpPort = pAddress; int size = Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET)); pConfigInfo = Marshal.AllocCoTaskMem(size); Marshal.StructureToPtr(configSslSet, pConfigInfo, false); error = NativeMethods.HttpDeleteServiceConfiguration( IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pConfigInfo, size, IntPtr.Zero); if (error != HttpError.NO_ERROR) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Could not delete existing SSL certificate binding.\r\nError={0}", error); } } finally { if (pConfigInfo != IntPtr.Zero) { Marshal.FreeCoTaskMem(pConfigInfo); } if (pAddress != IntPtr.Zero) { Marshal.FreeCoTaskMem(pAddress); } NativeMethods.HttpTerminate(HttpInitFlag.HTTP_INITIALIZE_CONFIG, IntPtr.Zero); } }
public static void BindCertificate(IPEndPoint ipPort, byte[] hash, string storeName, Guid appId) { if (ipPort == null) { throw new ArgumentNullException(nameof(ipPort)); } if (hash == null) { throw new ArgumentNullException(nameof(hash)); } CallHttpApi( delegate { HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET(); GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort); IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject(); HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey = new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort); 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_SET))); Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false); try { uint retVal = HttpSetServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); if (ERROR_ALREADY_EXISTS != retVal) { ThrowWin32ExceptionIfError(retVal); } else { retVal = HttpDeleteServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); retVal = HttpSetServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); ThrowWin32ExceptionIfError(retVal); } } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); if (handleHash.IsAllocated) { handleHash.Free(); } if (sockAddrHandle.IsAllocated) { sockAddrHandle.Free(); } } }); }