private void DeleteBindingMI_Click(object sender, EventArgs e) { try { if (BindingsDV.SelectedRows.Count == 0) { return; } if (Ask("Are you sure you want to delete these bindings?")) { foreach (DataGridViewRow row in BindingsDV.SelectedRows) { DataRowView source = row.DataBoundItem as DataRowView; SslCertificateBinding binding = (SslCertificateBinding)source.Row[4]; HttpAccessRule.DeleteSslCertificateBinding(binding.IPAddress, binding.Port); } m_dataset.Tables[0].Clear(); // repopulate the grid. foreach (SslCertificateBinding binding in HttpAccessRule.GetSslCertificateBindings()) { AddRow(binding); } m_dataset.AcceptChanges(); BindingsDV.DataSource = m_dataset.Tables[0].DefaultView; } } catch (Exception exception) { GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception); } }
/// <summary> /// Adds a certificate binding to to list. /// </summary> private void AddRow(SslCertificateBinding binding) { DataRow row = m_dataset.Tables[0].NewRow(); row[0] = binding.IPAddress; row[1] = binding.Port; row[3] = binding.Thumbprint; row[4] = binding; CertificateStoreIdentifier id = new CertificateStoreIdentifier(); id.StoreType = CertificateStoreType.Windows; id.StorePath = "LocalMachine\\" + ((String.IsNullOrEmpty(binding.StoreName)) ? "My" : binding.StoreName); using (ICertificateStore store = id.OpenStore()) { X509Certificate2 certificate = store.FindByThumbprint(binding.Thumbprint); if (certificate != null) { row[2] = certificate.Subject; } else { row[2] = "<not found>"; } } m_dataset.Tables[0].Rows.Add(row); }
/// <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); } }
/// <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(typeof(HTTP_SERVICE_CONFIG_SSL_QUERY))); NativeMethods.ZeroMemory(pInput, Marshal.SizeOf(typeof(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(typeof(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(typeof(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(pOutput, typeof(HTTP_SERVICE_CONFIG_SSL_SET)); short family = Marshal.ReadInt16(sslSet.KeyDesc.pIpPort); SslCertificateBinding binding = new SslCertificateBinding(); if (family == AF_INET) { SOCKADDR_IN inet = (SOCKADDR_IN)Marshal.PtrToStructure(sslSet.KeyDesc.pIpPort, typeof(SOCKADDR_IN)); binding.IPAddress = new IPAddress(inet.addr); binding.Port = inet.port; } if (family == AF_INET6) { SOCKADDR_IN6 inet = (SOCKADDR_IN6)Marshal.PtrToStructure(sslSet.KeyDesc.pIpPort, typeof(SOCKADDR_IN6)); 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(pInput, typeof(HTTP_SERVICE_CONFIG_SSL_QUERY)); Marshal.FreeHGlobal(pInput); } if (pOutput != IntPtr.Zero) { Marshal.FreeHGlobal(pOutput); } NativeMethods.HttpTerminate(HttpInitFlag.HTTP_INITIALIZE_CONFIG, IntPtr.Zero); } return bindings; }
/// <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); }
private void OkBTN_Click(object sender, EventArgs e) { try { IPAddress address = IPAddress.Parse(IPAddressTB.Text); ushort port = (ushort)PortUD.Value; if (m_certificate == null) { throw new ArgumentException("You must specify a certificate."); } X509Certificate2 certificate = m_certificate.Find(true); if (certificate == null) { throw new ArgumentException("Certificate does not exist or has no private key."); } // setup policy chain X509ChainPolicy policy = new X509ChainPolicy(); policy.RevocationFlag = X509RevocationFlag.EntireChain; policy.RevocationMode = X509RevocationMode.Offline; policy.VerificationFlags = X509VerificationFlags.NoFlag; policy.VerificationFlags |= X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreCtlSignerRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreRootRevocationUnknown; // build chain. X509Chain chain = new X509Chain(); chain.ChainPolicy = policy; chain.Build(certificate); for (int ii = 0; ii < chain.ChainElements.Count; ii++) { X509ChainElement element = chain.ChainElements[ii]; // check for chain status errors. foreach (X509ChainStatus status in element.ChainElementStatus) { if (status.Status == X509ChainStatusFlags.UntrustedRoot) { if (!Ask("Cannot verify certificate up to a trusted root.\r\nAdd anyways?")) { return; } continue; } if (status.Status == X509ChainStatusFlags.RevocationStatusUnknown) { if (!Ask("The revocation status of this certificate cannot be verified.\r\nAdd anyways?")) { return; } continue; } // ignore informational messages. if (status.Status == X509ChainStatusFlags.OfflineRevocation) { continue; } if (status.Status != X509ChainStatusFlags.NoError) { throw new ArgumentException("[" + status.Status + "] " + status.StatusInformation); } } } // get the target store. if (m_store == null) { m_store = new CertificateStoreIdentifier(); m_store.StoreType = CertificateStoreType.Windows; m_store.StorePath = CertificateStoreTB.Text; } if (m_store.StoreType != CertificateStoreType.Windows) { throw new ArgumentException("You must choose a Windows store for SSL certificates."); } if (!m_store.StorePath.StartsWith("LocalMachine\\", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException("You must choose a machine store for SSL certificates."); } bool deleteExisting = false; using (ICertificateStore store = m_store.OpenStore()) { if (store.FindByThumbprint(certificate.Thumbprint) == null) { store.Add(certificate); deleteExisting = true; } } if (deleteExisting) { if (Ask("Would you like to delete the certificate from its current location?")) { using (ICertificateStore store = m_certificate.OpenStore()) { store.Delete(certificate.Thumbprint); } } } SslCertificateBinding binding = new SslCertificateBinding(); binding.IPAddress = address; binding.Port = port; binding.Thumbprint = certificate.Thumbprint; binding.ApplicationId = s_DefaultApplicationId; binding.StoreName = null; if (!m_store.StorePath.EndsWith("\\My")) { int index = m_store.StorePath.LastIndexOf("\\"); binding.StoreName = m_store.StorePath.Substring(index+1); } HttpAccessRule.SetSslCertificateBinding(binding); m_binding = binding; DialogResult = DialogResult.OK; } catch (Exception exception) { GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception); } }
private void OkBTN_Click(object sender, EventArgs e) { try { IPAddress address = IPAddress.Parse(IPAddressTB.Text); ushort port = (ushort)PortUD.Value; if (m_certificate == null) { throw new ArgumentException("You must specify a certificate."); } X509Certificate2 certificate = m_certificate.Find(true); if (certificate == null) { throw new ArgumentException("Certificate does not exist or has no private key."); } // setup policy chain X509ChainPolicy policy = new X509ChainPolicy(); policy.RevocationFlag = X509RevocationFlag.EntireChain; policy.RevocationMode = X509RevocationMode.Offline; policy.VerificationFlags = X509VerificationFlags.NoFlag; policy.VerificationFlags |= X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreCtlSignerRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreRootRevocationUnknown; // build chain. X509Chain chain = new X509Chain(); chain.ChainPolicy = policy; chain.Build(certificate); for (int ii = 0; ii < chain.ChainElements.Count; ii++) { X509ChainElement element = chain.ChainElements[ii]; // check for chain status errors. foreach (X509ChainStatus status in element.ChainElementStatus) { if (status.Status == X509ChainStatusFlags.UntrustedRoot) { if (!Ask("Cannot verify certificate up to a trusted root.\r\nAdd anyways?")) { return; } continue; } if (status.Status == X509ChainStatusFlags.RevocationStatusUnknown) { if (!Ask("The revocation status of this certificate cannot be verified.\r\nAdd anyways?")) { return; } continue; } // ignore informational messages. if (status.Status == X509ChainStatusFlags.OfflineRevocation) { continue; } if (status.Status != X509ChainStatusFlags.NoError) { throw new ArgumentException("[" + status.Status + "] " + status.StatusInformation); } } } // get the target store. if (m_store == null) { m_store = new CertificateStoreIdentifier(); m_store.StoreType = CertificateStoreType.Windows; m_store.StorePath = CertificateStoreTB.Text; } if (m_store.StoreType != CertificateStoreType.Windows) { throw new ArgumentException("You must choose a Windows store for SSL certificates."); } if (!m_store.StorePath.StartsWith("LocalMachine\\", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException("You must choose a machine store for SSL certificates."); } bool deleteExisting = false; using (ICertificateStore store = m_store.OpenStore()) { if (store.FindByThumbprint(certificate.Thumbprint) == null) { store.Add(certificate); deleteExisting = true; } } if (deleteExisting) { if (Ask("Would you like to delete the certificate from its current location?")) { using (ICertificateStore store = m_certificate.OpenStore()) { store.Delete(certificate.Thumbprint); } } } SslCertificateBinding binding = new SslCertificateBinding(); binding.IPAddress = address; binding.Port = port; binding.Thumbprint = certificate.Thumbprint; binding.ApplicationId = s_DefaultApplicationId; binding.StoreName = null; if (!m_store.StorePath.EndsWith("\\My")) { int index = m_store.StorePath.LastIndexOf("\\"); binding.StoreName = m_store.StorePath.Substring(index + 1); } HttpAccessRule.SetSslCertificateBinding(binding); m_binding = binding; DialogResult = DialogResult.OK; } catch (Exception exception) { GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception); } }