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);
}
}