public X509Certificate2 GetBindedCertificate(int port, out StoreName storeName) { if (_disposed) { throw new InvalidOperationException(Resources.HttpBindedDispose); } if (!_initialized) { throw new InvalidOperationException(Resources.HttpBindedInitialize); } X509Certificate2 certificate = null; var endPoint = new IPEndPoint(IPAddress.Any, port); var endPointData = endPoint.GetBytes(); var endPointPtr = IntPtr.Zero; var outConfigPtr = IntPtr.Zero; try { endPointPtr = Marshal.AllocHGlobal(endPointData.Length); Marshal.Copy(endPointData, 0, endPointPtr, endPointData.Length); var config = new HttpCertificateConfigurationQuery { IpPort = endPointPtr, QueryType = HttpConfigurationQueryType.Exact }; uint returnLength; var returnCode = NativeHttpServer.HttpQueryServiceConfiguration(IntPtr.Zero, HttpConfigurationType.Certificate, ref config, (uint)Marshal.SizeOf(config), IntPtr.Zero, 0, out returnLength, IntPtr.Zero); if (returnCode == 122) //ERROR_INSUFFICIENT_BUFFER { outConfigPtr = Marshal.AllocHGlobal((int)returnLength); returnCode = NativeHttpServer.HttpQueryServiceConfiguration(IntPtr.Zero, HttpConfigurationType.Certificate, ref config, (uint)Marshal.SizeOf(config), outConfigPtr, returnLength, out returnLength, IntPtr.Zero); } if (returnCode == 2) //ERROR_FILE_NOT_FOUND { storeName = 0; return(null); } if (returnCode != 0) { throw new Win32Exception((int)returnCode, Resources.HttpBindedException); } var outConfig = (HttpCertificateConfigurationSet) Marshal.PtrToStructure(outConfigPtr, typeof(HttpCertificateConfigurationSet)); var hash = new byte[outConfig.HashLength]; Marshal.Copy(outConfig.Hash, hash, 0, hash.Length); storeName = (StoreName)Enum.Parse(typeof(StoreName), outConfig.StoreName, true); var store = new X509Store(storeName, StoreLocation.LocalMachine); try { store.Open(OpenFlags.ReadOnly); foreach (var c in store.Certificates) { if (c.GetCertHash().SequenceEqual(hash)) { certificate = c; break; } } } finally { store.Close(); } } finally { if (endPointPtr != IntPtr.Zero) { Marshal.FreeHGlobal(endPointPtr); } if (outConfigPtr != IntPtr.Zero) { Marshal.FreeHGlobal(outConfigPtr); } } return(certificate); }
public static extern uint HttpQueryServiceConfiguration(IntPtr handle, HttpConfigurationType type, ref HttpCertificateConfigurationQuery configuration, uint length, IntPtr __outConfiguration, uint outLength, out uint returnLength, IntPtr overlapped);