Example #1
0
 private void AddBTN_Click(object sender, EventArgs e)
 {
     try
     {
         if (new SelectComServerDlg().ShowDialog(m_configuration))
         {
             m_configuration.SaveToFile(m_configuration.SourceFilePath);
             UpdateServers();
         }
     }
     catch (Exception exception)
     {
         MessageBox.Show(exception.Message);
     }
 }
        /// <summary>
        /// Synchronous helper implementation of CheckApplicationInstanceCertificate for C++ Proxy
        /// </summary>
        public static void CheckApplicationInstanceCertificate(ApplicationConfiguration configuration)
        {
            // create a default certificate id none specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                id             = new CertificateIdentifier();
                id.StoreType   = Utils.DefaultStoreType;
                id.StorePath   = Utils.DefaultStorePath;
                id.SubjectName = configuration.ApplicationName;
            }

            // check for certificate with a private key.
            X509Certificate2 certificate = id.Find(true).Result;

            if (certificate != null)
            {
                return;
            }

            // construct the subject name from the
            List <string> hostNames = new List <string>();

            hostNames.Add(Utils.GetHostName());

            string commonName  = Utils.Format("CN={0}", configuration.ApplicationName);
            string domainName  = Utils.Format("DC={0}", hostNames[0]);
            string subjectName = Utils.Format("{0}, {1}", commonName, domainName);

            // create a new certificate with a new public key pair.
            certificate = CertificateFactory.CreateCertificate(
                configuration.ApplicationUri,
                configuration.ApplicationName,
                subjectName,
                hostNames)
                          .CreateForRSA()
                          .AddToStore(
                id.StoreType,
                id.StorePath);

            id.Certificate = certificate;

            // update and save the configuration file.
            configuration.SaveToFile(configuration.SourceFilePath);

            // add certificate to the trusted peer store so other applications will trust it.
            using (ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore())
            {
                X509Certificate2Collection certificateCollection = store.FindByThumbprint(certificate.Thumbprint).Result;
                if (certificateCollection != null)
                {
                    store.Add(certificateCollection[0]).Wait();
                }
            }

            // tell the certificate validator about the new certificate.
            configuration.CertificateValidator.Update(configuration.SecurityConfiguration).Wait();
        }
Example #3
0
        private void Config_SelectServerMI_Click(object sender, EventArgs e)
        {
            try
            {
                if (!new SelectComServerDlg().ShowDialogForUpdate(m_configuration))
                {
                    return;
                }

                m_configuration.SaveToFile(m_configuration.SourceFilePath);

                m_server.Stop();
                m_server = new ComDaServerWrapper();
                m_server.Start(m_configuration);

                ServerDiagnosticsCTRL.Initialize(m_server, m_configuration);
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
        }
Example #4
0
        /// <summary>
        /// Creates an application instance certificate if one does not already exist.
        /// </summary>
        public static X509Certificate2 CheckApplicationInstanceCertificate(
            ApplicationConfiguration configuration,
            ushort keySize,
            bool interactive,
            bool updateFile)
        {
            // create a default certificate id none specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                id             = new CertificateIdentifier();
                id.StoreType   = Utils.DefaultStoreType;
                id.StorePath   = Utils.DefaultStorePath;
                id.SubjectName = configuration.ApplicationName;
            }

            bool           createNewCertificate = false;
            IList <string> serverDomainNames    = configuration.GetServerDomainNames();

            // check for private key.
            X509Certificate2 certificate = id.Find(true);

            if (certificate == null)
            {
                // check if config file has wrong thumprint.
                if (!String.IsNullOrEmpty(id.SubjectName) && !String.IsNullOrEmpty(id.Thumbprint))
                {
                    CertificateIdentifier id2 = new CertificateIdentifier();
                    id2.StoreType   = id.StoreType;
                    id2.StorePath   = id.StorePath;
                    id2.SubjectName = id.SubjectName;
                    id = id2;

                    certificate = id2.Find(true);

                    if (certificate != null)
                    {
                        string message = Utils.Format(
                            "Matching certificate with SubjectName={0} found but with a different thumbprint. Use certificate?",
                            id.SubjectName);

                        if (interactive)
                        {
                            if (MessageBox.Show(message, configuration.ApplicationName, MessageBoxButtons.YesNo) == DialogResult.No)
                            {
                                certificate = null;
                            }
                        }
                    }
                }
            }

            // check if private key is missing.
            if (certificate == null)
            {
                certificate = id.Find(false);

                if (certificate != null)
                {
                    string message = Utils.Format(
                        "Matching certificate with SubjectName={0} found but without a private key. Create a new certificate?",
                        id.SubjectName);

                    if (interactive)
                    {
                        if (MessageBox.Show(message, configuration.ApplicationName, MessageBoxButtons.YesNo) == DialogResult.No)
                        {
                            certificate = null;
                        }
                    }
                }
            }

            // check domains.
            if (certificate != null)
            {
                IList <string> certificateDomainNames = Utils.GetDomainsFromCertficate(certificate);

                for (int ii = 0; ii < serverDomainNames.Count; ii++)
                {
                    if (Utils.FindStringIgnoreCase(certificateDomainNames, serverDomainNames[ii]))
                    {
                        continue;
                    }

                    if (String.Compare(serverDomainNames[ii], "localhost", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        // check computer name.
                        string computerName = System.Net.Dns.GetHostName();

                        if (Utils.FindStringIgnoreCase(certificateDomainNames, computerName))
                        {
                            continue;
                        }

                        // check for aliases.
                        System.Net.IPHostEntry entry = System.Net.Dns.GetHostEntry(computerName);

                        bool found = false;

                        for (int jj = 0; jj < entry.Aliases.Length; jj++)
                        {
                            if (Utils.FindStringIgnoreCase(certificateDomainNames, entry.Aliases[jj]))
                            {
                                found = true;
                                break;
                            }
                        }

                        if (found)
                        {
                            continue;
                        }

                        // check for ip addresses.
                        for (int jj = 0; jj < entry.AddressList.Length; jj++)
                        {
                            if (Utils.FindStringIgnoreCase(certificateDomainNames, entry.AddressList[jj].ToString()))
                            {
                                found = true;
                                break;
                            }
                        }

                        if (found)
                        {
                            continue;
                        }
                    }

                    string message = Utils.Format(
                        "The server is configured to use domain '{0}' which does not appear in the certificate. Update certificate?",
                        serverDomainNames[ii]);

                    createNewCertificate = true;

                    if (interactive)
                    {
                        if (MessageBox.Show(message, configuration.ApplicationName, MessageBoxButtons.YesNo) != DialogResult.Yes)
                        {
                            createNewCertificate = false;
                            continue;
                        }
                    }

                    Utils.Trace(message);
                    break;
                }

                if (!createNewCertificate)
                {
                    // check if key size matches.
                    if (keySize == certificate.PublicKey.Key.KeySize)
                    {
                        AddToTrustedStore(configuration, certificate);
                        return(certificate);
                    }
                }
            }

            // prompt user.
            if (interactive)
            {
                if (!createNewCertificate)
                {
                    if (MessageBox.Show("Application does not have an instance certificate. Create one automatically?", configuration.ApplicationName, MessageBoxButtons.YesNo) == DialogResult.No)
                    {
                        return(null);
                    }
                }
            }

            // delete existing certificate.
            if (certificate != null)
            {
                DeleteApplicationInstanceCertificate(configuration);
            }

            // add the localhost.
            if (serverDomainNames.Count == 0)
            {
                serverDomainNames.Add(System.Net.Dns.GetHostName());
            }

            certificate = Opc.Ua.CertificateFactory.CreateCertificate(
                id.StoreType,
                id.StorePath,
                configuration.ApplicationUri,
                configuration.ApplicationName,
                null,
                serverDomainNames,
                keySize,
                300);

            id.Certificate = certificate;
            AddToTrustedStore(configuration, certificate);

            if (updateFile && !String.IsNullOrEmpty(configuration.SourceFilePath))
            {
                configuration.SaveToFile(configuration.SourceFilePath);
            }

            configuration.CertificateValidator.Update(configuration.SecurityConfiguration);

            return(configuration.SecurityConfiguration.ApplicationCertificate.LoadPrivateKey(null));
        }
        /// <summary>
        /// Creates an application instance certificate if one does not already exist.
        /// </summary>
        public static async Task <X509Certificate2> CheckApplicationInstanceCertificate(
            ApplicationConfiguration configuration,
            ushort keySize,
            bool interactive,
            bool updateFile)
        {
            // create a default certificate if none is specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                id             = new CertificateIdentifier();
                id.StoreType   = Utils.DefaultStoreType;
                id.StorePath   = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault";
                id.SubjectName = configuration.ApplicationName;
            }

            bool           createNewCertificate = false;
            IList <string> serverDomainNames    = configuration.GetServerDomainNames();

            // check for private key.
            X509Certificate2 certificate = await id.Find(true);

            if (certificate == null)
            {
                // check if config file has wrong thumprint.
                if (!String.IsNullOrEmpty(id.SubjectName) && !String.IsNullOrEmpty(id.Thumbprint))
                {
                    CertificateIdentifier id2 = new CertificateIdentifier();
                    id2.StoreType   = id.StoreType;
                    id2.StorePath   = id.StorePath;
                    id2.SubjectName = id.SubjectName;
                    id = id2;

                    certificate = await id2.Find(true);

                    if (certificate != null)
                    {
                        string message = Utils.Format(
                            "Matching certificate with SubjectName={0} found but with a different thumbprint. Use certificate?",
                            id.SubjectName);

                        if (interactive)
                        {
                            MessageDlg       dialog = new MessageDlg(message, MessageDlgButton.Yes, MessageDlgButton.No);
                            MessageDlgButton result = await dialog.ShowAsync();

                            if (result != MessageDlgButton.Yes)
                            {
                                certificate = null;
                            }
                        }
                    }
                }

                // check if private key is missing.
                if (certificate == null)
                {
                    certificate = await id.Find(false);

                    if (certificate != null)
                    {
                        string message = Utils.Format(
                            "Matching certificate with SubjectName={0} found but without a private key. Create a new certificate?",
                            id.SubjectName);

                        if (interactive)
                        {
                            MessageDlg       dialog = new MessageDlg(message, MessageDlgButton.Yes, MessageDlgButton.No);
                            MessageDlgButton result = await dialog.ShowAsync();

                            if (result != MessageDlgButton.Yes)
                            {
                                certificate = null;
                            }
                        }
                    }
                }

                // check domains.
                if (certificate != null)
                {
                    IList <string> certificateDomainNames = Utils.GetDomainsFromCertficate(certificate);

                    for (int ii = 0; ii < serverDomainNames.Count; ii++)
                    {
                        if (Utils.FindStringIgnoreCase(certificateDomainNames, serverDomainNames[ii]))
                        {
                            continue;
                        }

                        if (String.Compare(serverDomainNames[ii], "localhost", StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            // check computer name.
                            string computerName = Utils.GetHostName();

                            if (Utils.FindStringIgnoreCase(certificateDomainNames, computerName))
                            {
                                continue;
                            }
                        }

                        string message = Utils.Format(
                            "The server is configured to use domain '{0}' which does not appear in the certificate. Create new certificate?",
                            serverDomainNames[ii]);

                        createNewCertificate = true;

                        if (interactive)
                        {
                            MessageDlg       dialog = new MessageDlg(message, MessageDlgButton.Yes, MessageDlgButton.No);
                            MessageDlgButton result = await dialog.ShowAsync();

                            if (result != MessageDlgButton.Yes)
                            {
                                createNewCertificate = false;
                                continue;
                            }
                        }

                        Utils.Trace(message);
                        break;
                    }

                    if (!createNewCertificate)
                    {
                        // check if key size matches.
                        if (keySize == certificate.GetRSAPublicKey().KeySize)
                        {
                            await AddToTrustedStore(configuration, certificate);

                            return(certificate);
                        }
                    }
                }

                // prompt user.
                if (interactive)
                {
                    if (!createNewCertificate)
                    {
                        MessageDlg       dialog = new MessageDlg("Application does not have an instance certificate.\n Create one automatically?", MessageDlgButton.Yes, MessageDlgButton.No);
                        MessageDlgButton result = await dialog.ShowAsync();

                        if (result != MessageDlgButton.Yes)
                        {
                            return(null);
                        }
                    }
                }

                // delete existing certificate.
                if (certificate != null)
                {
                    await DeleteApplicationInstanceCertificate(configuration);
                }

                // add the localhost.
                if (serverDomainNames.Count == 0)
                {
                    serverDomainNames.Add(Utils.GetHostName());
                }

                certificate = await Opc.Ua.CertificateFactory.CreateCertificate(
                    id.StoreType,
                    id.StorePath,
                    configuration.ApplicationUri,
                    configuration.ApplicationName,
                    null,
                    serverDomainNames,
                    keySize,
                    300);

                id.Certificate = certificate;
                await AddToTrustedStore(configuration, certificate);

                if (updateFile && !String.IsNullOrEmpty(configuration.SourceFilePath))
                {
                    configuration.SaveToFile(configuration.SourceFilePath);
                }

                await configuration.CertificateValidator.Update(configuration.SecurityConfiguration);

                return(await configuration.SecurityConfiguration.ApplicationCertificate.LoadPrivateKey(null));
            }

            return(certificate);
        }
Example #6
0
        /// <summary>
        /// Creates an application instance certificate if one does not already exist.
        /// </summary>
        public static void CheckApplicationInstanceCertificate(ApplicationConfiguration configuration)
        {
            // create a default certificate id none specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                id = new CertificateIdentifier
                {
                    StoreType   = CertificateStoreType.X509Store,
                    StorePath   = "LocalMachine\\My",
                    SubjectName = configuration.ApplicationName
                };
            }

            // check for certificate with a private key.
            X509Certificate2 certificate = id.Find(true).Result;

            if (certificate != null)
            {
                //This UA application already has an instance certificate
                SaveCertificate(certificate);
                return;
            }

            //This UA application does not have an instance certificate. Create one automatically

            // construct the subject name from the
            List <string> hostNames = new List <string>
            {
                System.Net.Dns.GetHostName()
            };

            string commonName  = Utils.Format("CN={0}", configuration.ApplicationName);
            string domainName  = Utils.Format("DC={0}", hostNames[0]);
            string subjectName = Utils.Format("{0}, {1}", commonName, domainName);

            // check if a distinguished name was specified.
            if (id.SubjectName.IndexOf("=", StringComparison.Ordinal) != -1)
            {
                List <string> fields = Utils.ParseDistinguishedName(id.SubjectName);

                bool commonNameFound = false;
                bool domainNameFound = false;

                for (int ii = 0; ii < fields.Count; ii++)
                {
                    string field = fields[ii];

                    if (field.StartsWith("CN="))
                    {
                        fields[ii]      = commonName;
                        commonNameFound = true;
                        continue;
                    }

                    if (field.StartsWith("DC="))
                    {
                        fields[ii]      = domainName;
                        domainNameFound = true;
                        continue;
                    }
                }

                if (!commonNameFound)
                {
                    fields.Insert(0, commonName);
                }

                if (!domainNameFound)
                {
                    fields.Insert(0, domainName);
                }

                StringBuilder buffer = new StringBuilder();

                for (int ii = 0; ii < fields.Count; ii++)
                {
                    if (buffer.Length > 0)
                    {
                        buffer.Append(", ");
                    }

                    buffer.Append(fields[ii]);
                }

                subjectName = buffer.ToString();
            }

            // create a new certificate with a new public key pair.
            //certificate = CertificateFactory.CreateCertificate(
            //    id.StoreType,
            //    id.StorePath,
            //    configuration.ApplicationUri,
            //    configuration.ApplicationName,
            //    subjectName,
            //    hostNames,
            //    1024,
            //    120);

            ushort minimumKeySize   = CertificateFactory.defaultKeySize;
            ushort lifeTimeInMonths = CertificateFactory.defaultLifeTime;

            certificate = CertificateFactory.CreateCertificate(
                id.StoreType,
                id.StorePath,
                null,
                configuration.ApplicationUri,
                configuration.ApplicationName,
                id.SubjectName,
                hostNames,
                minimumKeySize,
                DateTime.UtcNow - TimeSpan.FromDays(1),
                lifeTimeInMonths,
                CertificateFactory.defaultHashSize,
                false,
                null,
                null);

            // update and save the configuration file.
            id.Certificate = certificate;
            configuration.SaveToFile(configuration.SourceFilePath);

            // add certificate to the trusted peer store so other applications will trust it.
            ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();

            try
            {
                X509Certificate2 certificate2 = store.FindByThumbprint(certificate.Thumbprint).Result[0];

                if (certificate2 == null)
                {
                    store.Add(certificate);
                }
            }
            finally
            {
                store.Close();
            }

            // tell the certificate validator about the new certificate.
            configuration.CertificateValidator.Update(configuration.SecurityConfiguration);
            SaveCertificate(certificate);
        }
Example #7
0
        /// <summary>
        /// Creates an application instance certificate if one does not already exist.
        /// </summary>
        public static X509Certificate2 CheckApplicationInstanceCertificate(
            ApplicationConfiguration configuration, 
            ushort keySize, 
            bool interactive,
            bool updateFile)
        {
            // create a default certificate id none specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                id = new CertificateIdentifier();
                id.StoreType = Utils.DefaultStoreType;
                id.StorePath = Utils.DefaultStorePath;
                id.SubjectName = configuration.ApplicationName;
            }

            bool createNewCertificate = false;
            IList<string> serverDomainNames = configuration.GetServerDomainNames();

            // check for private key.
            X509Certificate2 certificate = id.Find(true);

            if (certificate == null)
            {
                // check if config file has wrong thumprint.
                if (!String.IsNullOrEmpty(id.SubjectName) && !String.IsNullOrEmpty(id.Thumbprint))
                {
                    CertificateIdentifier id2 = new CertificateIdentifier();
                    id2.StoreType = id.StoreType;
                    id2.StorePath = id.StorePath;
                    id2.SubjectName = id.SubjectName;
                    id = id2;

                    certificate = id2.Find(true);

                    if (certificate != null)
                    {
                        string message = Utils.Format(
                            "Matching certificate with SubjectName={0} found but with a different thumbprint. Use certificate?",
                            id.SubjectName);

                        if (interactive)
                        {
                            if (MessageBox.Show(message, configuration.ApplicationName, MessageBoxButtons.YesNo) == DialogResult.No)
                            {
                                certificate = null;
                            }
                        }
                    }
                }
            }

            // check if private key is missing.
            if (certificate == null)
            {
                certificate = id.Find(false);

                if (certificate != null)
                {
                    string message = Utils.Format(
                        "Matching certificate with SubjectName={0} found but without a private key. Create a new certificate?",
                        id.SubjectName);

                    if (interactive)
                    {
                        if (MessageBox.Show(message, configuration.ApplicationName, MessageBoxButtons.YesNo) == DialogResult.No)
                        {
                            certificate = null;
                        }
                    }
                }
            }

            // check domains.
            if (certificate != null)
            {
                IList<string> certificateDomainNames = Utils.GetDomainsFromCertficate(certificate);

                for (int ii = 0; ii < serverDomainNames.Count; ii++)
                {
                    if (Utils.FindStringIgnoreCase(certificateDomainNames, serverDomainNames[ii]))
                    {
                        continue;
                    }

                    if (String.Compare(serverDomainNames[ii], "localhost", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        // check computer name.
                        string computerName = System.Net.Dns.GetHostName();

                        if (Utils.FindStringIgnoreCase(certificateDomainNames, computerName))
                        {
                            continue;
                        }

                        // check for aliases.
                        System.Net.IPHostEntry entry = System.Net.Dns.GetHostEntry(computerName);
                        
                        bool found = false;

                        for (int jj = 0; jj < entry.Aliases.Length; jj++)
                        {
                            if (Utils.FindStringIgnoreCase(certificateDomainNames, entry.Aliases[jj]))
                            {
                                found = true;
                                break;
                            }
                        }

                        if (found)
                        {
                            continue;
                        }

                        // check for ip addresses.
                        for (int jj = 0; jj < entry.AddressList.Length; jj++)
                        {
                            if (Utils.FindStringIgnoreCase(certificateDomainNames, entry.AddressList[jj].ToString()))
                            {
                                found = true;
                                break;
                            }
                        }

                        if (found)
                        {
                            continue;
                        }
                    }

                    string message = Utils.Format(
                        "The server is configured to use domain '{0}' which does not appear in the certificate. Update certificate?",
                        serverDomainNames[ii]);

                    createNewCertificate = true;

                    if (interactive)
                    {
                        if (MessageBox.Show(message, configuration.ApplicationName, MessageBoxButtons.YesNo) != DialogResult.Yes)
                        {
                            createNewCertificate = false;
                            continue;
                        }
                    }

                    Utils.Trace(message);
                    break;
                }

                if (!createNewCertificate)
                {
                    // check if key size matches.
                    if (keySize == certificate.PublicKey.Key.KeySize)
                    {
                        AddToTrustedStore(configuration, certificate);
                        return certificate;
                    }
                }
            }

            // prompt user.
            if (interactive)
            {
                if (!createNewCertificate)
                {
                    if (MessageBox.Show("Application does not have an instance certificate. Create one automatically?", configuration.ApplicationName, MessageBoxButtons.YesNo) == DialogResult.No)
                    {
                        return null;
                    }
                }
            }

            // delete existing certificate.
            if (certificate != null)
            {
                DeleteApplicationInstanceCertificate(configuration);
            }

            // add the localhost.
            if (serverDomainNames.Count == 0)
            {
                serverDomainNames.Add(System.Net.Dns.GetHostName());
            }

            certificate = Opc.Ua.CertificateFactory.CreateCertificate(
                id.StoreType,
                id.StorePath,
                configuration.ApplicationUri,
                configuration.ApplicationName,
                null,
                serverDomainNames,
                keySize,
                300);

            id.Certificate = certificate;
            AddToTrustedStore(configuration, certificate);

            if (updateFile && !String.IsNullOrEmpty(configuration.SourceFilePath))
            {
                configuration.SaveToFile(configuration.SourceFilePath);
            }

            configuration.CertificateValidator.Update(configuration.SecurityConfiguration);

            return configuration.SecurityConfiguration.ApplicationCertificate.LoadPrivateKey(null);
        }
        /// <summary>
        /// Creates an application instance certificate if one does not already exist.
        /// </summary>
        public static async Task<X509Certificate2> CheckApplicationInstanceCertificate(
            ApplicationConfiguration configuration,
            ushort keySize,
            bool interactive,
            bool updateFile)
        {
            // create a default certificate if none is specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                id = new CertificateIdentifier();
                id.StoreType = Utils.DefaultStoreType;
                id.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault";
                id.SubjectName = configuration.ApplicationName;
            }

            bool createNewCertificate = false;
            IList<string> serverDomainNames = configuration.GetServerDomainNames();

            // check for private key.
            X509Certificate2 certificate = await id.Find(true);

            if (certificate == null)
            {
                // check if config file has wrong thumprint.
                if (!String.IsNullOrEmpty(id.SubjectName) && !String.IsNullOrEmpty(id.Thumbprint))
                {
                    CertificateIdentifier id2 = new CertificateIdentifier();
                    id2.StoreType = id.StoreType;
                    id2.StorePath = id.StorePath;
                    id2.SubjectName = id.SubjectName;
                    id = id2;

                    certificate = await id2.Find(true);

                    if (certificate != null)
                    {
                        string message = Utils.Format(
                            "Matching certificate with SubjectName={0} found but with a different thumbprint. Use certificate?",
                            id.SubjectName);

                        if (interactive)
                        {
                            MessageDlg dialog = new MessageDlg(message, MessageDlgButton.Yes, MessageDlgButton.No);
                            MessageDlgButton result = await dialog.ShowAsync();
                            if (result != MessageDlgButton.Yes)
                            {
                                certificate = null;
                            }
                        }
                    }
                }

                // check if private key is missing.
                if (certificate == null)
                {
                    certificate = await id.Find(false);

                    if (certificate != null)
                    {
                        string message = Utils.Format(
                            "Matching certificate with SubjectName={0} found but without a private key. Create a new certificate?",
                            id.SubjectName);

                        if (interactive)
                        {
                            MessageDlg dialog = new MessageDlg(message, MessageDlgButton.Yes, MessageDlgButton.No);
                            MessageDlgButton result = await dialog.ShowAsync();
                            if (result != MessageDlgButton.Yes)
                            {
                                certificate = null;
                            }
                        }
                    }
                }

                // check domains.
                if (certificate != null)
                {
                    IList<string> certificateDomainNames = Utils.GetDomainsFromCertficate(certificate);

                    for (int ii = 0; ii < serverDomainNames.Count; ii++)
                    {
                        if (Utils.FindStringIgnoreCase(certificateDomainNames, serverDomainNames[ii]))
                        {
                            continue;
                        }

                        if (String.Compare(serverDomainNames[ii], "localhost", StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            // check computer name.
                            string computerName = Utils.GetHostName();

                            if (Utils.FindStringIgnoreCase(certificateDomainNames, computerName))
                            {
                                continue;
                            }
                        }

                        string message = Utils.Format(
                            "The server is configured to use domain '{0}' which does not appear in the certificate. Create new certificate?",
                            serverDomainNames[ii]);

                        createNewCertificate = true;

                        if (interactive)
                        {
                            MessageDlg dialog = new MessageDlg(message, MessageDlgButton.Yes, MessageDlgButton.No);
                            MessageDlgButton result = await dialog.ShowAsync();
                            if (result != MessageDlgButton.Yes)
                            {
                                createNewCertificate = false;
                                continue;
                            }
                        }

                        Utils.Trace(message);
                        break;
                    }

                    if (!createNewCertificate)
                    {
                        // check if key size matches.
                        if (keySize == certificate.GetRSAPublicKey().KeySize)
                        {
                            await AddToTrustedStore(configuration, certificate);
                            return certificate;
                        }
                    }
                }

                // prompt user.
                if (interactive)
                {
                    if (!createNewCertificate)
                    {
                        MessageDlg dialog = new MessageDlg("Application does not have an instance certificate.\n Create one automatically?", MessageDlgButton.Yes, MessageDlgButton.No);
                        MessageDlgButton result = await dialog.ShowAsync();
                        if (result != MessageDlgButton.Yes)
                        {
                            return null;
                        }
                    }
                }

                // delete existing certificate.
                if (certificate != null)
                {
                    await DeleteApplicationInstanceCertificate(configuration);
                }

                // add the localhost.
                if (serverDomainNames.Count == 0)
                {
                    serverDomainNames.Add(Utils.GetHostName());
                }

                certificate = await Opc.Ua.CertificateFactory.CreateCertificate(
                    id.StoreType,
                    id.StorePath,
                    configuration.ApplicationUri,
                    configuration.ApplicationName,
                    null,
                    serverDomainNames,
                    keySize,
                    300);

                id.Certificate = certificate;
                await AddToTrustedStore(configuration, certificate);

                if (updateFile && !String.IsNullOrEmpty(configuration.SourceFilePath))
                {
                    configuration.SaveToFile(configuration.SourceFilePath);
                }

                await configuration.CertificateValidator.Update(configuration.SecurityConfiguration);

                return await configuration.SecurityConfiguration.ApplicationCertificate.LoadPrivateKey(null);
            }

            return certificate;
        }
        /// <summary>
        /// Synchronous helper implementation of CheckApplicationInstanceCertificate for C++ Proxy
        /// </summary>
        public static void CheckApplicationInstanceCertificate(ApplicationConfiguration configuration)
        {
            // create a default certificate id none specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                id = new CertificateIdentifier();
                id.StoreType = Utils.DefaultStoreType;
                id.StorePath = Utils.DefaultStorePath;
                id.SubjectName = configuration.ApplicationName;
            }

            // check for certificate with a private key.
            X509Certificate2 certificate = null;
            Task.Run(async () => certificate = await id.Find(true)).Wait();

            if (certificate != null)
            {
                return;
            }

            // construct the subject name from the 
            List<string> hostNames = new List<string>();
            hostNames.Add(Utils.GetHostName());

            string commonName = Utils.Format("CN={0}", configuration.ApplicationName);
            string domainName = Utils.Format("DC={0}", hostNames[0]);
            string subjectName = Utils.Format("{0}, {1}", commonName, domainName);

            // create a new certificate with a new public key pair.
            certificate = CertificateFactory.CreateCertificate(
                id.StoreType,
                id.StorePath,
                configuration.ApplicationUri,
                configuration.ApplicationName,
                subjectName,
                hostNames,
                2048,
                120,
                256);

            // update and save the configuration file.
            id.Certificate = certificate;
            configuration.SaveToFile(configuration.SourceFilePath);

            // add certificate to the trusted peer store so other applications will trust it.
            ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();

            try
            {
                Task.Run(async () =>
                    {
                        X509Certificate2Collection certificateCollection = await store.FindByThumbprint(certificate.Thumbprint);
                        if (certificateCollection != null)
                        {
                            await store.Add(certificateCollection[0]);
                        }
                    }
                ).Wait();
            }
            finally
            {
                store.Close();
            }

            // tell the certificate validator about the new certificate.
            configuration.CertificateValidator.Update(configuration.SecurityConfiguration);

        }