public bool verify(CertificateTrustCallback prompt, String hostName, List certs)
        {
            X509Certificate2 serverCert = ConvertCertificate(certs.iterator().next() as X509Certificate);
            X509Chain        chain      = new X509Chain();

            chain.ChainPolicy.RevocationMode =
                PreferencesFactory.get().getBoolean("connection.ssl.x509.revocation.online")
                    ? X509RevocationMode.Online
                    : X509RevocationMode.Offline;
            chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0, 10); // set timeout to 10 seconds
            chain.ChainPolicy.VerificationFlags   = X509VerificationFlags.NoFlag;

            for (int index = 1; index < certs.size(); index++)
            {
                chain.ChainPolicy.ExtraStore.Add(ConvertCertificate(certs.get(index) as X509Certificate));
            }
            chain.Build(serverCert);

            bool isException = CheckForException(hostName, serverCert);

            if (isException)
            {
                // Exceptions always have precedence
                return(true);
            }

            string errorFromChainStatus = GetErrorFromChainStatus(chain, hostName);
            bool   certError            = null != errorFromChainStatus;
            bool   hostnameMismatch     = hostName != null &&
                                          !HostnameVerifier.CheckServerIdentity(certs.iterator().next() as X509Certificate,
                                                                                serverCert, hostName);

            // check if host name matches
            if (null == errorFromChainStatus && hostnameMismatch)
            {
                errorFromChainStatus =
                    string.Format(LocaleFactory.localizedString(
                                      "The certificate for this server is invalid. You might be connecting to a server that is pretending to be {0} which could put your confidential information at risk. Would you like to connect to the server anyway?",
                                      "Keychain"), hostName);
            }

            if (null != errorFromChainStatus)
            {
                // Title: LocaleFactory.localizedString("Certificate Error", "Keychain")
                // Main Instruction: LocaleFactory.localizedString("Certificate Error", "Keychain")
                // Content: errorFromChainStatus
                // Verification Text: LocaleFactory.localizedString("Always Trust", "Keychain")
                // CommandButtons: { LocaleFactory.localizedString("Continue", "Credentials"), LocaleFactory.localizedString("Disconnect"), LocaleFactory.localizedString("Show Certificate", "Keychain") }
                // ShowCancelButton: false
                // Main Icon: Warning
                // Footer Icon: Information

                TaskDialogResult result =
                    TaskDialog.TaskDialog.Show(
                        title: LocaleFactory.localizedString("Certificate Error", "Keychain"),
                        mainInstruction: LocaleFactory.localizedString("Certificate Error", "Keychain"),
                        verificationText: LocaleFactory.localizedString("Always Trust", "Keychain"),
                        content: errorFromChainStatus,
                        commandLinks:
                        new string[]
                {
                    LocaleFactory.localizedString("Continue", "Credentials"),
                    LocaleFactory.localizedString("Disconnect"),
                    LocaleFactory.localizedString("Show Certificate", "Keychain")
                },
                        mainIcon: TaskDialogIcon.Warning, footerIcon: TaskDialogIcon.Information,
                        callback: (dialog, args, data) =>
                {
                    switch (args.Notification)
                    {
                    case TaskDialogNotification.ButtonClicked:
                        if (args.ButtonIndex == 2)
                        {
                            X509Certificate2UI.DisplayCertificate(serverCert);
                            return(true);
                        }
                        break;
                    }
                    return(false);
                });

                if (result.Result == TaskDialogSimpleResult.Command)
                {
                    if (result.CommandButtonResult == 0)
                    {
                        if (result.VerificationChecked == true)
                        {
                            if (certError)
                            {
                                //todo can we use the Trusted People and Third Party Certificate Authority Store? Currently X509Chain is the problem.
                                AddCertificate(serverCert, StoreName.Root);
                            }
                            PreferencesFactory.get()
                            .setProperty(hostName + ".certificate.accept", serverCert.Thumbprint);
                        }
                        return(true);
                    }
                    if (result.CommandButtonResult == 1)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Ejemplo n.º 2
0
        public override bool isTrusted(String hostName, X509Certificate[] certs)
        {
            X509Certificate2 serverCert = ConvertCertificate(certs[0]);
            X509Chain        chain      = new X509Chain();

            //todo Online revocation check. Preference.
            chain.ChainPolicy.RevocationMode      = X509RevocationMode.Offline; // | X509RevocationMode.Online
            chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0, 10);  // set timeout to 10 seconds
            chain.ChainPolicy.VerificationFlags   = X509VerificationFlags.NoFlag;

            for (int index = 1; index < certs.Length; index++)
            {
                chain.ChainPolicy.ExtraStore.Add(ConvertCertificate(certs[index]));
            }
            chain.Build(serverCert);

            string errorFromChainStatus = GetErrorFromChainStatus(chain, hostName);
            bool   certError            = null != errorFromChainStatus;
            bool   hostnameMismatch     = !HostnameVerifier.CheckServerIdentity(certs[0], serverCert, hostName) &&
                                          !CheckForException(hostName, serverCert);

            // check if host name matches
            if (null == errorFromChainStatus && hostnameMismatch)
            {
                errorFromChainStatus = Locale.localizedString(
                    "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “%@” which could put your confidential information at risk. Would you like to connect to the server anyway?",
                    "Keychain").Replace("%@", hostName);
            }

            if (null != errorFromChainStatus)
            {
                while (true)
                {
                    TaskDialog   d = new TaskDialog();
                    DialogResult r =
                        d.ShowCommandBox(Locale.localizedString("This certificate is not valid", "Keychain"),
                                         Locale.localizedString("This certificate is not valid", "Keychain"),
                                         errorFromChainStatus,
                                         null,
                                         null,
                                         Locale.localizedString("Always Trust", "Keychain"),
                                         String.Format("{0}|{1}|{2}",
                                                       Locale.localizedString("Continue", "Credentials"),
                                                       Locale.localizedString("Disconnect"),
                                                       Locale.localizedString("Show Certificate", "Keychain")),
                                         false,
                                         SysIcons.Warning, SysIcons.Information);
                    if (r == DialogResult.OK)
                    {
                        if (d.CommandButtonResult == 0)
                        {
                            if (d.VerificationChecked)
                            {
                                if (certError)
                                {
                                    //todo can we use the Trusted People and Third Party Certificate Authority Store? Currently X509Chain is the problem.
                                    AddCertificate(serverCert, StoreName.Root);
                                }
                                if (hostnameMismatch)
                                {
                                    Preferences.instance().setProperty(hostName + ".certificate.accept",
                                                                       serverCert.SubjectName.Name);
                                }
                            }
                            return(true);
                        }
                        if (d.CommandButtonResult == 1)
                        {
                            return(false);
                        }
                        if (d.CommandButtonResult == 2)
                        {
                            X509Certificate2UI.DisplayCertificate(serverCert);
                        }
                    }
                }
            }
            return(true);
        }