コード例 #1
0
        /// <summary>
        /// Displays the dialog.
        /// </summary>
        public async Task <bool> ShowDialog(CertificateIdentifier certificateIdentifier)
        {
            CertificateStoreCTRL.StoreType = null;
            CertificateStoreCTRL.StorePath = null;
            PrivateKeyCB.SelectedIndex     = 0;
            PropertiesCTRL.Initialize((X509Certificate2)null);

            if (certificateIdentifier != null)
            {
                X509Certificate2 certificate = await certificateIdentifier.Find();

                CertificateStoreCTRL.StoreType = certificateIdentifier.StoreType;
                CertificateStoreCTRL.StorePath = certificateIdentifier.StorePath;

                if (certificate != null && certificateIdentifier.Find(true) != null)
                {
                    PrivateKeyCB.SelectedIndex = 1;
                }
                else
                {
                    PrivateKeyCB.SelectedIndex = 0;
                }

                PropertiesCTRL.Initialize(certificate);
            }

            if (ShowDialog() != DialogResult.OK)
            {
                return(false);
            }

            return(true);
        }
コード例 #2
0
ファイル: CertificateDlg.cs プロジェクト: yuriik83/UA-.NET
        /// <summary>
        /// Displays the dialog.
        /// </summary>
        public bool ShowDialog(CertificateIdentifier certificateIdentifier)
        {
            CertificateStoreCTRL.StoreType = null;
            CertificateStoreCTRL.StorePath = null;
            PrivateKeyCB.SelectedIndex = 0;
            PropertiesCTRL.Initialize((X509Certificate2)null);

            if (certificateIdentifier != null)
            {
                X509Certificate2 certificate = certificateIdentifier.Find();

                CertificateStoreCTRL.StoreType = certificateIdentifier.StoreType;
                CertificateStoreCTRL.StorePath = certificateIdentifier.StorePath;

                if (certificate != null && certificateIdentifier.Find(true) != null)
                {
                    PrivateKeyCB.SelectedIndex = 1;
                }
                else
                {
                    PrivateKeyCB.SelectedIndex = 0;
                }

                PropertiesCTRL.Initialize(certificate);
            }

            if (ShowDialog() != DialogResult.OK)
            {
                return false;
            }

            return true;
        }
コード例 #3
0
        /// <summary>
        /// Deletes an existing application instance certificate.
        /// </summary>
        /// <param name="configuration">The configuration instance that stores the configurable information for a UA application.</param>
        private static async Task DeleteApplicationInstanceCertificate(ApplicationConfiguration configuration)
        {
            // create a default certificate id none specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                return;
            }

            // delete certificate and private key.
            X509Certificate2 certificate = await id.Find().ConfigureAwait(false);

            if (certificate != null)
            {
                Utils.LogCertificate(TraceMasks.Security, "Deleting application instance certificate and private key.", certificate);
            }

            // delete trusted peer certificate.
            if (configuration.SecurityConfiguration != null &&
                configuration.SecurityConfiguration.TrustedPeerCertificates != null)
            {
                string thumbprint = id.Thumbprint;

                if (certificate != null)
                {
                    thumbprint = certificate.Thumbprint;
                }

                if (!string.IsNullOrEmpty(thumbprint))
                {
                    using (ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore())
                    {
                        bool deleted = await store.Delete(thumbprint).ConfigureAwait(false);

                        if (deleted)
                        {
                            Utils.LogInfo(TraceMasks.Security, "Application Instance Certificate [{0}] deleted from trusted store.", thumbprint);
                        }
                    }
                }
            }

            // delete certificate and private key from owner store.
            if (certificate != null)
            {
                using (ICertificateStore store = id.OpenStore())
                {
                    bool deleted = await store.Delete(certificate.Thumbprint).ConfigureAwait(false);

                    if (deleted)
                    {
                        Utils.LogCertificate(TraceMasks.Security, "Application certificate and private key deleted.", certificate);
                    }
                }
            }

            // erase the memory copy of the deleted certificate
            id.Certificate = null;
        }
コード例 #4
0
        /// <summary>
        /// Initializes the validator from the configuration for a token policy.
        /// </summary>
        /// <param name="issuerCertificate">The issuer certificate.</param>
        private SecurityTokenResolver CreateSecurityTokenResolver(CertificateIdentifier issuerCertificate)
        {
            if (issuerCertificate == null)
            {
                throw new ArgumentNullException("issuerCertificate");
            }

            // find the certificate.
            X509Certificate2 certificate = issuerCertificate.Find(false);

            if (certificate == null)
            {
                throw ServiceResultException.Create(
                          StatusCodes.BadCertificateInvalid,
                          "Could not find issuer certificate: {0}",
                          issuerCertificate);
            }

            // create a security token representing the certificate.
            List <SecurityToken> tokens = new List <SecurityToken>();

            tokens.Add(new X509SecurityToken(certificate));

            // create issued token resolver.
            SecurityTokenResolver tokenResolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
                new System.Collections.ObjectModel.ReadOnlyCollection <SecurityToken>(tokens),
                false);

            return(tokenResolver);
        }
コード例 #5
0
ファイル: OPCClient.cs プロジェクト: lulzzz/OPCAdapters
        /// <summary>
        /// Creates a user identity for the policy.
        /// </summary>
        private IUserIdentity CreateUserIdentity(UserTokenPolicy policy)
        {
            if (policy == null || policy.TokenType == UserTokenType.Anonymous)
            {
                return(null);
            }

            if (policy.TokenType == UserTokenType.UserName)
            {
                return(new UserIdentity("SomeUser", "password"));
            }

            if (policy.TokenType == UserTokenType.Certificate)
            {
                X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

                store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);

                try
                {
                    foreach (X509Certificate2 certificate in store.Certificates)
                    {
                        if (certificate.HasPrivateKey)
                        {
                            return(new UserIdentity(certificate));
                        }
                    }

                    return(null);
                }
                finally
                {
                    store.Close();
                }
            }

            if (policy.TokenType == UserTokenType.IssuedToken)
            {
                CertificateIdentifier userid = new CertificateIdentifier();

                userid.StoreType   = CertificateStoreType.Windows;
                userid.StorePath   = "LocalMachine\\Root";
                userid.SubjectName = "UASampleRoot";

                X509Certificate2  certificate  = userid.Find();
                X509SecurityToken signingToken = new X509SecurityToken(certificate);

                SamlSecurityToken token = CreateSAMLToken("*****@*****.**", signingToken);

                return(new UserIdentity(token));
            }

            throw ServiceResultException.Create(StatusCodes.BadSecurityPolicyRejected, "User token policy is not supported.");
        }
コード例 #6
0
        /// <summary>
        /// Creates a minimal endpoint description which allows a client to connect to a server.
        /// </summary>
        /// <remarks>
        /// In most cases the client will use the server's discovery endpoint to fetch the information
        /// constained in this structure.
        /// </remarks>
        public static EndpointDescription CreateEndpointDescription()
        {
            // create the endpoint description.
            EndpointDescription endpointDescription = new EndpointDescription();

            endpointDescription.EndpointUrl =
                Utils.Format("http://{0}:61211/UA/SampleClient", System.Net.Dns.GetHostName());
            // endpointDescription.EndpointUrl = Utils.Format("opc.tcp://{0}:51210/UA/SampleServer", System.Net.Dns.GetHostName());
            // endpointDescription.EndpointUrl = Utils.Format("http://{0}:51211/UA/SampleServer/None", System.Net.Dns.GetHostName());
            // endpointDescription.EndpointUrl = Utils.Format("http://{0}:51211/UA/SampleServer", System.Net.Dns.GetHostName());

            // specify the security policy to use.
            // endpointDescription.SecurityPolicyUri = SecurityPolicies.None;
            // endpointDescription.SecurityMode      = MessageSecurityMode.None;;
            endpointDescription.SecurityPolicyUri = SecurityPolicies.Basic256Sha256;
            endpointDescription.SecurityMode      = MessageSecurityMode.SignAndEncrypt;

            // specify the transport profile.
            endpointDescription.TransportProfileUri = Profiles.WsHttpXmlOrBinaryTransport;
            // endpointDescription.TransportProfileUri = Profiles.WsHttpXmlTransport;
            // endpointDescription.TransportProfileUri = Profiles.UaTcpTransport;

            endpointDescription.Server.DiscoveryUrls.Add(Utils.Format("http://{0}:61211/UA/SampleClient/discovery",
                                                                      System.Net.Dns.GetHostName()));

            // load the the server certificate from the local certificate store.
            CertificateIdentifier certificateIdentifier = new CertificateIdentifier();

            certificateIdentifier.StoreType   = CertificateStoreType.Windows;
            certificateIdentifier.StorePath   = "LocalMachine\\My";
            certificateIdentifier.SubjectName = "UA Sample Client";

            X509Certificate2 serverCertificate = certificateIdentifier.Find();

            if (serverCertificate == null)
            {
                throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid,
                                                    "Could not find server certificate: {0}", certificateIdentifier.SubjectName);
            }

            endpointDescription.ServerCertificate = serverCertificate.RawData;

            return(endpointDescription);
        }
コード例 #7
0
        /// <summary>
        /// Deletes an existing application instance certificate.
        /// </summary>
        /// <param name="configuration">The configuration instance that stores the configurable information for a UA application.</param>
        private static async Task DeleteApplicationInstanceCertificate(ApplicationConfiguration configuration)
        {
            Utils.Trace(Utils.TraceMasks.Information, "Deleting application instance certificate.");

            // create a default certificate id none specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                return;
            }

            // delete private key.
            X509Certificate2 certificate = await id.Find().ConfigureAwait(false);

            // delete trusted peer certificate.
            if (configuration.SecurityConfiguration != null && configuration.SecurityConfiguration.TrustedPeerCertificates != null)
            {
                string thumbprint = id.Thumbprint;

                if (certificate != null)
                {
                    thumbprint = certificate.Thumbprint;
                }

                if (!string.IsNullOrEmpty(thumbprint))
                {
                    using (ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore())
                    {
                        await store.Delete(thumbprint).ConfigureAwait(false);
                    }
                }
            }

            // delete private key.
            if (certificate != null)
            {
                using (ICertificateStore store = id.OpenStore())
                {
                    await store.Delete(certificate.Thumbprint).ConfigureAwait(false);
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Deletes an existing application instance certificate.
        /// </summary>
        /// <param name="configuration">The configuration instance that stores the configurable information for a UA application.</param>
        private static void DeleteApplicationInstanceCertificate(ApplicationConfiguration configuration)
        {
            Utils.Trace(Utils.TraceMasks.Information, "Deleting application instance certificate.");

            // Create a default certificate id none specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                return;
            }

            X509Certificate2 certificate = id.Find();

            // Delete trusted peer certificate.
            if (configuration.SecurityConfiguration?.TrustedPeerCertificates != null)
            {
                var thumbprint = id.Thumbprint;

                if (certificate != null)
                {
                    thumbprint = certificate.Thumbprint;
                }

                using (var store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore())
                {
                    store.Delete(thumbprint);
                }
            }

            // Delete private key.
            if (certificate == null)
            {
                return;
            }

            using (ICertificateStore store = id.OpenStore())
            {
                store.Delete(certificate.Thumbprint);
            }
        }
コード例 #9
0
ファイル: GuiUtils.cs プロジェクト: mcooper87/UA-.NET
        /// <summary>
        /// Deletes an existing application instance certificate.
        /// </summary>
        /// <param name="configuration">The configuration instance that stores the configurable information for a UA application.</param>
        public static void DeleteApplicationInstanceCertificate(ApplicationConfiguration configuration)
        {
            // create a default certificate id none specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                return;
            }

            // delete private key.
            X509Certificate2 certificate = id.Find();

            // delete trusted peer certificate.
            if (configuration.SecurityConfiguration != null && configuration.SecurityConfiguration.TrustedPeerCertificates != null)
            {
                string thumbprint = id.Thumbprint;

                if (certificate != null)
                {
                    thumbprint = certificate.Thumbprint;
                }

                if (!String.IsNullOrEmpty(thumbprint))
                {
                    using (ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore())
                    {
                        store.Delete(thumbprint);
                    }
                }
            }

            // delete private key.
            if (certificate != null)
            {
                using (ICertificateStore store = id.OpenStore())
                {
                    store.Delete(certificate.Thumbprint);
                }
            }
        }
コード例 #10
0
        private void CertificateBTN_Click(object sender, EventArgs e)
        {
            try
            {
                // determine default store.
                CertificateStoreIdentifier store = new CertificateStoreIdentifier();

                if (m_certificate != null)
                {
                    store.StoreType = m_certificate.StoreType;
                    store.StorePath = m_certificate.StorePath;
                }
                else
                {
                    store.StoreType = Utils.DefaultStoreType;
                    store.StorePath = Utils.DefaultStorePath;
                }

                // select the certificate.
                CertificateIdentifier certificate = new CertificateListDlg().ShowDialog(store, true);

                if (certificate != null)
                {
                    m_certificate = certificate;
                    X509Certificate2 certificate2 = m_certificate.Find();

                    if (certificate2 != null)
                    {
                        CertificateTB.Text = certificate2.Subject;
                    }
                    else
                    {
                        CertificateTB.Text = m_certificate.ToString();
                    }
                }
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
            }
        }
コード例 #11
0
        /// <summary>
        /// Updates the dialog with the configuration.
        /// </summary>
        private void Update(ManagedApplication application)
        {
            if (application == null)
            {
                application = new ManagedApplication();
            }

            m_application = application;
            SetIsSdkApplication(application.IsSdkCompatible);

            ApplicationNameTB.Text   = application.DisplayName;
            ExecutableFileTB.Text    = application.ExecutablePath;
            ConfigurationFileTB.Text = application.ConfigurationPath;
            CertificateTB.Text       = null;
            TrustListTB.Text         = null;

            m_certificate = application.Certificate;
            m_trustList   = application.TrustList;

            if (m_certificate != null)
            {
                X509Certificate2 certificate = m_certificate.Find();

                if (certificate != null)
                {
                    CertificateTB.Text = certificate.Subject;
                }
                else
                {
                    CertificateTB.Text = m_certificate.ToString();
                }
            }

            if (m_trustList != null)
            {
                TrustListTB.Text = m_trustList.ToString();
            }
        }
コード例 #12
0
        /// <summary>
        /// Creates a minimal endpoint description which allows a client to connect to a server.
        /// </summary>
        /// <remarks>
        /// In most cases the client will use the server's discovery endpoint to fetch the information
        /// constained in this structure.
        /// </remarks>
        public static EndpointDescription CreateEndpointDescription(string Url)
        {
            // create the endpoint description.
            EndpointDescription endpointDescription = new EndpointDescription();

            //endpointDescription.EndpointUrl = Utils.Format("opc.tcp://{0}:4840", System.Net.Dns.GetHostName());
            endpointDescription.EndpointUrl = Url;

            // specify the security policy to use.
            //endpointDescription.SecurityPolicyUri = SecurityPolicies.Basic128Rsa15;
            endpointDescription.SecurityPolicyUri = SecurityPolicies.None;
            //endpointDescription.SecurityMode      = MessageSecurityMode.SignAndEncrypt;
            endpointDescription.SecurityMode = MessageSecurityMode.None;

            // specify the transport profile.
            endpointDescription.TransportProfileUri = Profiles.WsHttpXmlOrBinaryTransport;

            // load the the server certificate from the local certificate store.
            CertificateIdentifier certificateIdentifier = new CertificateIdentifier();

            certificateIdentifier.StoreType = CertificateStoreType.Windows;
            certificateIdentifier.StorePath = "LocalMachine\\My";

            certificateIdentifier.SubjectName = "UA Test Client";

            X509Certificate2 serverCertificate = certificateIdentifier.Find();

            if (serverCertificate == null)
            {
                throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "Could not find server certificate in certificate store: {0}", certificateIdentifier.SubjectName);
            }

            endpointDescription.ServerCertificate = serverCertificate.GetRawCertData();

            return(endpointDescription);
        }
コード例 #13
0
        /// <summary>
        /// Checks for a valid application instance certificate.
        /// </summary>
        /// <param name="silent">if set to <c>true</c> no dialogs will be displayed.</param>
        /// <param name="minimumKeySize">Minimum size of the key.</param>
        /// <param name="lifeTimeInMonths">The lifetime in months.</param>
        public async Task <bool> CheckApplicationInstanceCertificate(
            bool silent,
            ushort minimumKeySize,
            ushort lifeTimeInMonths)
        {
            Utils.LogInfo("Checking application instance certificate.");

            if (m_applicationConfiguration == null)
            {
                await LoadApplicationConfiguration(silent).ConfigureAwait(false);
            }

            ApplicationConfiguration configuration = m_applicationConfiguration;

            // find the existing certificate.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                throw ServiceResultException.Create(StatusCodes.BadConfigurationError,
                                                    "Configuration file does not specify a certificate.");
            }

            // reload the certificate from disk in the cache.
            var passwordProvider = configuration.SecurityConfiguration.CertificatePasswordProvider;
            await configuration.SecurityConfiguration.ApplicationCertificate.LoadPrivateKeyEx(passwordProvider).ConfigureAwait(false);

            // load the certificate
            X509Certificate2 certificate = await id.Find(true).ConfigureAwait(false);

            // check that it is ok.
            if (certificate != null)
            {
                Utils.LogCertificate("Check certificate:", certificate);
                bool certificateValid = await CheckApplicationInstanceCertificate(configuration, certificate, silent, minimumKeySize).ConfigureAwait(false);

                if (!certificateValid)
                {
                    var message = new StringBuilder();
                    message.AppendLine("The certificate with subject {0} in the configuration is invalid.");
                    message.AppendLine(" Please update or delete the certificate from this location:");
                    message.AppendLine(" {1}");
                    throw ServiceResultException.Create(StatusCodes.BadConfigurationError,
                                                        message.ToString(), id.SubjectName, id.StorePath
                                                        );
                }
            }
            else
            {
                // check for missing private key.
                certificate = await id.Find(false).ConfigureAwait(false);

                if (certificate != null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadConfigurationError,
                                                        "Cannot access certificate private key. Subject={0}", certificate.Subject);
                }

                // check for missing thumbprint.
                if (!String.IsNullOrEmpty(id.Thumbprint))
                {
                    if (!String.IsNullOrEmpty(id.SubjectName))
                    {
                        CertificateIdentifier id2 = new CertificateIdentifier {
                            StoreType   = id.StoreType,
                            StorePath   = id.StorePath,
                            SubjectName = id.SubjectName
                        };
                        certificate = await id2.Find(true).ConfigureAwait(false);
                    }

                    if (certificate != null)
                    {
                        var message = new StringBuilder();
                        message.AppendLine("Thumbprint was explicitly specified in the configuration.");
                        message.AppendLine("Another certificate with the same subject name was found.");
                        message.AppendLine("Use it instead?");
                        message.AppendLine("Requested: {0}");
                        message.AppendLine("Found: {1}");
                        if (!await ApproveMessage(String.Format(message.ToString(), id.SubjectName, certificate.Subject), silent).ConfigureAwait(false))
                        {
                            throw ServiceResultException.Create(StatusCodes.BadConfigurationError,
                                                                message.ToString(), id.SubjectName, certificate.Subject);
                        }
                    }
                    else
                    {
                        var message = new StringBuilder();
                        message.AppendLine("Thumbprint was explicitly specified in the configuration. ");
                        message.AppendLine("Cannot generate a new certificate.");
                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, message.ToString());
                    }
                }
            }

            if (certificate == null)
            {
                certificate = await CreateApplicationInstanceCertificate(configuration,
                                                                         minimumKeySize, lifeTimeInMonths).ConfigureAwait(false);

                if (certificate == null)
                {
                    var message = new StringBuilder();
                    message.AppendLine("There is no cert with subject {0} in the configuration.");
                    message.AppendLine(" Please generate a cert for your application,");
                    message.AppendLine(" then copy the new cert to this location:");
                    message.AppendLine(" {1}");
                    throw ServiceResultException.Create(StatusCodes.BadConfigurationError,
                                                        message.ToString(), id.SubjectName, id.StorePath
                                                        );
                }
            }
            else
            {
                if (configuration.SecurityConfiguration.AddAppCertToTrustedStore)
                {
                    // ensure it is trusted.
                    await AddToTrustedStore(configuration, certificate).ConfigureAwait(false);
                }
            }

            return(true);
        }
コード例 #14
0
        /// <summary>
        /// Creates a user identity for the policy.
        /// </summary>
        private IUserIdentity CreateUserIdentity(UserTokenPolicy policy)
        {
            if (policy == null || policy.TokenType == UserTokenType.Anonymous)
            {
                return null;
            }

            if (policy.TokenType == UserTokenType.UserName)
            {
                return new UserIdentity("SomeUser", "password");
            }

            if (policy.TokenType == UserTokenType.Certificate)
            {
                X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

                store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);

                try
                {
                    foreach (X509Certificate2 certificate in store.Certificates)
                    {
                        if (certificate.HasPrivateKey)
                        {
                            return new UserIdentity(certificate);
                        }
                    }
                    
                    return null;
                }
                finally
                {
                    store.Close();
                }
            }

            if (policy.TokenType == UserTokenType.IssuedToken)
            {
                CertificateIdentifier userid = new CertificateIdentifier();

                userid.StoreType   = CertificateStoreType.Windows;
                userid.StorePath   = "LocalMachine\\Root";
                userid.SubjectName = "UASampleRoot";

                X509Certificate2 certificate = userid.Find();
                X509SecurityToken signingToken = new X509SecurityToken(certificate);

                SamlSecurityToken token = CreateSAMLToken("*****@*****.**", signingToken);
                          
                return new UserIdentity(token);            
            }

            throw ServiceResultException.Create(StatusCodes.BadSecurityPolicyRejected, "User token policy is not supported.");
        }
コード例 #15
0
        /// <summary>
        /// Updates the dialog with the configuration.
        /// </summary>
        private void Update(ManagedApplication application)
        {
            if (application == null)
            {
                application = new ManagedApplication();
            }

            m_application = application;
            SetIsSdkApplication(application.IsSdkCompatible);

            ApplicationNameTB.Text = application.DisplayName;
            ExecutableFileTB.Text = application.ExecutablePath;
            ConfigurationFileTB.Text = application.ConfigurationPath;
            CertificateTB.Text = null;
            TrustListTB.Text = null;

            m_certificate = application.Certificate;
            m_trustList = application.TrustList;

            if (m_certificate != null)
            {
                X509Certificate2 certificate = m_certificate.Find();

                if (certificate != null)
                {
                    CertificateTB.Text = certificate.Subject;
                }
                else
                {
                    CertificateTB.Text = m_certificate.ToString();
                }
            }

            if (m_trustList != null)
            {
                TrustListTB.Text = m_trustList.ToString();
            }
        }
コード例 #16
0
        private void CertificateBTN_Click(object sender, EventArgs e)
        {
            try
            {
                // determine default store.
                CertificateStoreIdentifier store = new CertificateStoreIdentifier();

                if (m_certificate != null)
                {
                    store.StoreType = m_certificate.StoreType;
                    store.StorePath = m_certificate.StorePath;
                }
                else
                {
                    store.StoreType = Utils.DefaultStoreType;
                    store.StorePath = Utils.DefaultStorePath;
                }

                // select the certificate.
                CertificateIdentifier certificate = new CertificateListDlg().ShowDialog(store, true);

                if (certificate != null)
                {
                    m_certificate = certificate;
                    X509Certificate2 certificate2 = m_certificate.Find();

                    if (certificate2 != null)
                    {
                        CertificateTB.Text = certificate2.Subject;
                    }
                    else
                    {
                        CertificateTB.Text = m_certificate.ToString();
                    }
                }
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
            }
        }
コード例 #17
0
        public async Task Initialize(
            GlobalDiscoveryClientConfiguration configuration,
            GlobalDiscoveryServerClient gds,
            ServerPushConfigurationClient server,
            RegisteredApplication application,
            bool isHttps)
        {
            m_configuration       = configuration;
            m_gds                 = gds;
            m_server              = server;
            m_application         = application;
            m_certificate         = null;
            m_certificatePassword = null;

            CertificateRequestTimer.Enabled = false;
            RequestProgressLabel.Visible    = false;
            ApplyChangesButton.Enabled      = false;

            CertificateControl.ShowNothing();

            X509Certificate2 certificate = null;

            if (!isHttps)
            {
                if (server.Endpoint != null && server.Endpoint.Description.ServerCertificate != null)
                {
                    certificate = new X509Certificate2(server.Endpoint.Description.ServerCertificate);
                }
                else if (application != null)
                {
                    if (!String.IsNullOrEmpty(application.CertificatePublicKeyPath))
                    {
                        string file = Utils.GetAbsoluteFilePath(application.CertificatePublicKeyPath, true, false, false);

                        if (file != null)
                        {
                            certificate = new X509Certificate2(file);
                        }
                    }
                    else if (!String.IsNullOrEmpty(application.CertificateStorePath))
                    {
                        CertificateIdentifier id = new CertificateIdentifier
                        {
                            StorePath = application.CertificateStorePath
                        };
                        id.StoreType   = CertificateStoreIdentifier.DetermineStoreType(id.StorePath);
                        id.SubjectName = application.CertificateSubjectName.Replace("localhost", Utils.GetHostName());

                        certificate = await id.Find(true);
                    }
                }
            }
            else
            {
                if (application != null)
                {
                    if (!String.IsNullOrEmpty(application.HttpsCertificatePublicKeyPath))
                    {
                        string file = Utils.GetAbsoluteFilePath(application.HttpsCertificatePublicKeyPath, true, false, false);

                        if (file != null)
                        {
                            certificate = new X509Certificate2(file);
                        }
                    }
                    else
                    {
                        foreach (string disoveryUrl in application.DiscoveryUrl)
                        {
                            if (Uri.IsWellFormedUriString(disoveryUrl, UriKind.Absolute))
                            {
                                Uri url = new Uri(disoveryUrl);

                                CertificateIdentifier id = new CertificateIdentifier()
                                {
                                    StoreType   = CertificateStoreType.X509Store,
                                    StorePath   = "CurrentUser\\UA_MachineDefault",
                                    SubjectName = "CN=" + url.DnsSafeHost
                                };

                                certificate = await id.Find();
                            }
                        }
                    }
                }
            }

            if (certificate != null)
            {
                try
                {
                    CertificateControl.Tag = certificate.Thumbprint;
                }
                catch (Exception)
                {
                    MessageBox.Show(
                        Parent,
                        "The certificate does not appear to be valid. Please check configuration settings.",
                        Parent.Text,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);

                    certificate = null;
                }
            }

            WarningLabel.Visible = certificate == null;

            if (certificate != null)
            {
                m_certificate = certificate;
                CertificateControl.ShowValue(null, "Application Certificate", new CertificateWrapper()
                {
                    Certificate = certificate
                }, true);
            }
        }
コード例 #18
0
        /// <summary>
        /// Checks for a valid application instance certificate.
        /// </summary>
        /// <param name="silent">if set to <c>true</c> no dialogs will be displayed.</param>
        /// <param name="minimumKeySize">Minimum size of the key.</param>
        /// <param name="lifeTimeInMonths">The lifetime in months.</param>
        public async Task <bool> CheckApplicationInstanceCertificate(
            bool silent,
            ushort minimumKeySize,
            ushort lifeTimeInMonths)
        {
            Utils.Trace(Utils.TraceMasks.Information, "Checking application instance certificate.");

            ApplicationConfiguration configuration = null;

            if (m_applicationConfiguration == null)
            {
                await LoadApplicationConfiguration(silent);
            }

            configuration = m_applicationConfiguration;
            bool certificateValid = false;

            // find the existing certificate.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "Configuration file does not specify a certificate.");
            }

            X509Certificate2 certificate = await id.Find(true);

            // check that it is ok.
            if (certificate != null)
            {
                certificateValid = await CheckApplicationInstanceCertificate(configuration, certificate, silent, minimumKeySize);
            }
            else
            {
                // check for missing private key.
                certificate = await id.Find(false);

                if (certificate != null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "Cannot access certificate private key. Subject={0}", certificate.Subject);
                }

                // check for missing thumbprint.
                if (!String.IsNullOrEmpty(id.Thumbprint))
                {
                    if (!String.IsNullOrEmpty(id.SubjectName))
                    {
                        CertificateIdentifier id2 = new CertificateIdentifier();
                        id2.StoreType   = id.StoreType;
                        id2.StorePath   = id.StorePath;
                        id2.SubjectName = id.SubjectName;

                        certificate = await id2.Find(true);
                    }

                    if (certificate != null)
                    {
                        string message = Utils.Format(
                            "Thumbprint was explicitly specified in the configuration." +
                            "\r\nAnother certificate with the same subject name was found." +
                            "\r\nUse it instead?\r\n" +
                            "\r\nRequested: {0}" +
                            "\r\nFound: {1}",
                            id.SubjectName,
                            certificate.Subject);

                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, message);
                    }
                    else
                    {
                        string message = Utils.Format("Thumbprint was explicitly specified in the configuration. Cannot generate a new certificate.");
                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, message);
                    }
                }
            }

            if ((certificate == null) || !certificateValid)
            {
                certificate = await CreateApplicationInstanceCertificate(configuration,
                                                                         minimumKeySize, lifeTimeInMonths);

                if (certificate == null)
                {
                    string message = Utils.Format(
                        "There is no cert with subject {0} in the configuration." +
                        "\r\n Please generate a cert for your application,",
                        "\r\n then copy the new cert to this location:" +
                        "\r\n{1}",
                        id.SubjectName,
                        id.StorePath);
                    throw ServiceResultException.Create(StatusCodes.BadConfigurationError, message);
                }
            }
            else
            {
                if (configuration.SecurityConfiguration.AddAppCertToTrustedStore)
                {
                    // ensure it is trusted.
                    await AddToTrustedStore(configuration, certificate);
                }
            }

            return(true);
        }
コード例 #19
0
        private async Task RequestNewCertificatePullMode(object sender, EventArgs e)
        {
            try
            {
                // check if we already have a private key
                NodeId requestId = null;
                if (!string.IsNullOrEmpty(m_application.CertificateStorePath))
                {
                    CertificateIdentifier id = new CertificateIdentifier
                    {
                        StoreType   = CertificateStoreIdentifier.DetermineStoreType(m_application.CertificateStorePath),
                        StorePath   = m_application.CertificateStorePath,
                        SubjectName = m_application.CertificateSubjectName.Replace("localhost", Utils.GetHostName())
                    };
                    m_certificate = await id.Find(true);

                    if (m_certificate != null &&
                        m_certificate.HasPrivateKey)
                    {
                        m_certificate = await id.LoadPrivateKey(m_certificatePassword);
                    }
                }

                bool hasPrivateKeyFile = false;
                if (!string.IsNullOrEmpty(m_application.CertificatePrivateKeyPath))
                {
                    FileInfo file = new FileInfo(m_application.CertificatePrivateKeyPath);
                    hasPrivateKeyFile = file.Exists;
                }

                var domainNames = m_application.GetDomainNames(m_certificate);
                if (m_certificate == null)
                {
                    // no private key
                    requestId = m_gds.StartNewKeyPairRequest(
                        m_application.ApplicationId,
                        null,
                        null,
                        m_application.CertificateSubjectName.Replace("localhost", Utils.GetHostName()),
                        domainNames,
                        "PFX",
                        m_certificatePassword);
                }
                else
                {
                    X509Certificate2 csrCertificate = null;
                    if (m_certificate.HasPrivateKey)
                    {
                        csrCertificate = m_certificate;
                    }
                    else
                    {
                        string absoluteCertificatePrivateKeyPath = Utils.GetAbsoluteFilePath(m_application.CertificatePrivateKeyPath, true, false, false);
                        byte[] pkcsData = File.ReadAllBytes(absoluteCertificatePrivateKeyPath);
                        if (m_application.GetPrivateKeyFormat(m_server?.GetSupportedKeyFormats()) == "PFX")
                        {
                            csrCertificate = CertificateFactory.CreateCertificateFromPKCS12(pkcsData, m_certificatePassword);
                        }
                        else
                        {
                            csrCertificate = CertificateFactory.CreateCertificateWithPEMPrivateKey(m_certificate, pkcsData, m_certificatePassword);
                        }
                    }
                    byte[] certificateRequest = CertificateFactory.CreateSigningRequest(csrCertificate, domainNames);
                    requestId = m_gds.StartSigningRequest(m_application.ApplicationId, null, null, certificateRequest);
                }

                m_application.CertificateRequestId = requestId.ToString();
                CertificateRequestTimer.Enabled    = true;
                RequestProgressLabel.Visible       = true;
                WarningLabel.Visible = false;
            }
            catch (Exception ex)
            {
                Opc.Ua.Client.Controls.ExceptionDlg.Show(Text, ex);
            }
        }
コード例 #20
0
        /// <summary>
        /// Checks for a valid application instance certificate.
        /// </summary>
        /// <param name="configuration">Config of UA application.</param>
        /// <param name="silent">If set to <c>true</c> no dialogs will be displayed.</param>
        /// <param name="minimumKeySize">Minimum size of the key.</param>
        public static void CheckApplicationInstanceCertificate(
            ApplicationConfiguration configuration,
            bool silent,
            ushort minimumKeySize)
        {
            Utils.Trace(Utils.TraceMasks.Information, "Checking application instance certificate.");

            bool createNewCertificate = true;

            // find the existing certificate.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "Configuration file does not specify a certificate.");
            }

            X509Certificate2 certificate = id.Find(true);

            // check that it is ok.
            if (certificate != null)
            {
                createNewCertificate = !CheckApplicationInstanceCertificate(configuration, certificate, silent, minimumKeySize);
            }
            else
            {
                // check for missing private key.
                certificate = id.Find(false);

                if (certificate != null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "Cannot access certificate private key. Subject={0}", certificate.Subject);
                }

                // check for missing thumbprint.
                if (!string.IsNullOrEmpty(id.Thumbprint))
                {
                    if (!string.IsNullOrEmpty(id.SubjectName))
                    {
                        CertificateIdentifier id2 = new CertificateIdentifier
                        {
                            StoreType   = id.StoreType,
                            StorePath   = id.StorePath,
                            SubjectName = id.SubjectName
                        };

                        certificate = id2.Find(true);
                    }

                    if (certificate != null)
                    {
                        string message = Utils.Format(
                            "Thumbprint was explicitly specified in the configuration." +
                            "\r\nAnother certificate with the same subject name was found." +
                            "\r\nUse it instead?\r\n" +
                            "\r\nRequested: {0}" +
                            "\r\nFound: {1}",
                            id.SubjectName,
                            certificate.Subject);

                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, message);
                    }
                    else
                    {
                        string message = Utils.Format("Thumbprint was explicitly specified in the configuration. Cannot generate a new certificate.");
                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, message);
                    }
                }
                else if (string.IsNullOrEmpty(id.SubjectName))
                {
                    string message = Utils.Format("Both SubjectName and Thumbprint are not specified in the configuration. Cannot generate a new certificate.");
                    throw ServiceResultException.Create(StatusCodes.BadConfigurationError, message);
                }
            }

            // create a new certificate.
            if (createNewCertificate)
            {
                certificate = CreateApplicationInstanceCertificate(configuration, minimumKeySize, 600);
                configuration.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            }
            // Make sure cert is in trusted store
            else
            {
                AddToTrustedStore(configuration, certificate);
                configuration.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            }
        }
コード例 #21
0
        /// <summary>
        /// Displays the dialog.
        /// </summary>
        public bool ShowDialog(CertificateIdentifier certificate)
        {
            m_certificate = certificate;

            CertificateStoreCTRL.StoreType = null;
            CertificateStoreCTRL.StorePath = null;
            CertificateStoreCTRL.ReadOnly = true;
            ApplicationNameTB.Text = null;
            ApplicationUriTB.Text = null;
            OrganizationTB.Text = null;
            DomainsTB.Text = System.Net.Dns.GetHostName();
            SubjectNameTB.Text = null;
            IssuerNameTB.Text = null;
            ValidFromTB.Text = null;
            ValidToTB.Text = null;
            ThumbprintTB.Text = null;

            if (certificate != null)
            {
                CertificateStoreCTRL.StoreType = certificate.StoreType;
                CertificateStoreCTRL.StorePath = certificate.StorePath;
                SubjectNameTB.Text = certificate.SubjectName;
                ThumbprintTB.Text = certificate.Thumbprint;

                X509Certificate2 data = certificate.Find();

                if (data != null)
                {
                    // fill in subject name.
                    StringBuilder buffer = new StringBuilder();

                    foreach (string element in Utils.ParseDistinguishedName(data.Subject))
                    {
                        if (element.StartsWith("CN="))
                        {
                            ApplicationNameTB.Text = element.Substring(3);
                        }

                        if (element.StartsWith("O="))
                        {

                            OrganizationTB.Text = element.Substring(2);
                        }

                        if (buffer.Length > 0)
                        {
                            buffer.Append('/');
                        }

                        buffer.Append(element);
                    }
                    
                    if (buffer.Length > 0)
                    {
                        SubjectNameTB.Text = buffer.ToString();
                    }

                    // fill in issuer name.
                    buffer = new StringBuilder();

                    foreach (string element in Utils.ParseDistinguishedName(data.Issuer))
                    {
                        if (buffer.Length > 0)
                        {
                            buffer.Append('/');
                        }

                        buffer.Append(element);
                    }

                    if (buffer.Length > 0)
                    {
                        IssuerNameTB.Text = buffer.ToString();
                    }

                    // fill in application uri.
                    string applicationUri = Utils.GetApplicationUriFromCertficate(data);

                    if (!String.IsNullOrEmpty(applicationUri))
                    {
                        ApplicationUriTB.Text = applicationUri;
                    }

                    // fill in domains.
                    buffer = new StringBuilder();

                    foreach (string domain in Utils.GetDomainsFromCertficate(data))
                    {
                        if (buffer.Length > 0)
                        {
                            buffer.Append(", ");
                        }

                        buffer.Append(domain);
                    }

                    if (buffer.Length > 0)
                    {
                        DomainsTB.Text = buffer.ToString();
                    }

                    ValidFromTB.Text = data.NotBefore.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
                    ValidToTB.Text = data.NotAfter.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
                    ThumbprintTB.Text = data.Thumbprint;
                }
            }

            if (ShowDialog() != DialogResult.OK)
            {
                return false;
            }

            return true;
        }
コード例 #22
0
ファイル: GuiUtils.cs プロジェクト: yuriik83/UA-.NET
        /// <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);
        }
コード例 #23
0
        /// <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;
        }
コード例 #24
0
        /// <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);
        }
コード例 #25
0
        /// <summary>
        /// Checks for a valid application instance certificate.
        /// </summary>
        /// <param name="silent">if set to <c>true</c> no dialogs will be displayed.</param>
        /// <param name="minimumKeySize">Minimum size of the key.</param>
        public async Task<bool> CheckApplicationInstanceCertificate(
            bool silent,
            ushort minimumKeySize)
        {
            Utils.Trace(Utils.TraceMasks.Information, "Checking application instance certificate.");

            ApplicationConfiguration configuration = null;

            if (m_applicationConfiguration == null)
            {
                await LoadApplicationConfiguration(silent);
            }

            configuration = m_applicationConfiguration;
            bool certificateValid = false;

            // find the existing certificate.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "Configuration file does not specify a certificate.");
            }

            X509Certificate2 certificate = await id.Find(true);

            // check that it is ok.
            if (certificate != null)
            {
                certificateValid = await CheckApplicationInstanceCertificate(configuration, certificate, silent, minimumKeySize);
            }
            else
            {
                // check for missing private key.
                certificate = await id.Find(false);

                if (certificate != null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "Cannot access certificate private key. Subject={0}", certificate.Subject);
                }

                // check for missing thumbprint.
                if (!String.IsNullOrEmpty(id.Thumbprint))
                {
                    if (!String.IsNullOrEmpty(id.SubjectName))
                    {
                        CertificateIdentifier id2 = new CertificateIdentifier();
                        id2.StoreType = id.StoreType;
                        id2.StorePath = id.StorePath;
                        id2.SubjectName = id.SubjectName;

                        certificate = await id2.Find(true);
                    }

                    if (certificate != null)
                    {
                        string message = Utils.Format(
                            "Thumbprint was explicitly specified in the configuration." +
                            "\r\nAnother certificate with the same subject name was found." +
                            "\r\nUse it instead?\r\n" +
                            "\r\nRequested: {0}" +
                            "\r\nFound: {1}",
                            id.SubjectName,
                            certificate.Subject);

                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, message);
                    }
                    else
                    {
                        string message = Utils.Format("Thumbprint was explicitly specified in the configuration. Cannot generate a new certificate.");
                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, message);
                    }
                }
            }

            if ((certificate == null) || !certificateValid)
            {
                certificate = await CreateApplicationInstanceCertificate(configuration, minimumKeySize);

                if (certificate == null)
                {
                    string message = Utils.Format(
                        "There is no cert with subject {0} in the configuration." +
                        "\r\n Please generate a cert for your application,",
                        "\r\n then copy the new cert to this location:" +
                        "\r\n{1}",
                        id.SubjectName,
                        id.StorePath);
                    throw ServiceResultException.Create(StatusCodes.BadConfigurationError, message);
                }
            }
            else
            {
                // ensure it is trusted.
                await AddToTrustedStore(configuration, certificate);
            }

            // add to discovery server.
            if (configuration.ApplicationType == ApplicationType.Server || configuration.ApplicationType == ApplicationType.ClientAndServer)
            {
                try
                {
                    await AddToDiscoveryServerTrustList(certificate, null, null, configuration.SecurityConfiguration.TrustedPeerCertificates);
                }
                catch (Exception e)
                {
                    Utils.Trace(e, "Could not add certificate to LDS trust list.");
                }
            }

            return true;
        }
コード例 #26
0
ファイル: GuiUtils.cs プロジェクト: mcooper87/UA-.NET
        /// <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));
        }
コード例 #27
0
        /// <summary>
        /// Installs a UA application.
        /// </summary>
        public static async Task InstallApplication(
            InstalledApplication application,
            bool autostart,
            bool configureFirewall)
        {
            // validate the executable file.
            string executableFile = Utils.GetAbsoluteFilePath(application.ExecutableFile, true, true, false);

            // get the default application name from the executable file.
            FileInfo executableFileInfo = new FileInfo(executableFile);

            string applicationName = executableFileInfo.Name.Substring(0, executableFileInfo.Name.Length - 4);

            // choose a default configuration file.
            if (String.IsNullOrEmpty(application.ConfigurationFile))
            {
                application.ConfigurationFile = Utils.Format(
                    "{0}\\{1}.Config.xml",
                    executableFileInfo.DirectoryName,
                    applicationName);
            }

            // validate the configuration file.
            string configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, false, false);

            // create a new file if one does not exist.
            bool useExisting = true;

            if (configurationFile == null)
            {
                configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, true, true);
                useExisting       = false;
            }

            // create the default configuration file.

            if (useExisting)
            {
                try
                {
                    Opc.Ua.Security.SecuredApplication existingSettings = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configurationFile);

                    // copy current settings
                    application.ApplicationType             = existingSettings.ApplicationType;
                    application.BaseAddresses               = existingSettings.BaseAddresses;
                    application.ApplicationCertificate      = existingSettings.ApplicationCertificate;
                    application.ApplicationName             = existingSettings.ApplicationName;
                    application.ProductName                 = existingSettings.ProductName;
                    application.RejectedCertificatesStore   = existingSettings.RejectedCertificatesStore;
                    application.TrustedCertificateStore     = existingSettings.TrustedCertificateStore;
                    application.TrustedCertificates         = existingSettings.TrustedCertificates;
                    application.IssuerCertificateStore      = existingSettings.IssuerCertificateStore;
                    application.IssuerCertificates          = application.IssuerCertificates;
                    application.UseDefaultCertificateStores = false;
                }
                catch (Exception e)
                {
                    useExisting = false;
                    Utils.Trace("WARNING. Existing configuration file could not be loaded: {0}.\r\nReplacing with default: {1}", e.Message, configurationFile);
                    File.Copy(configurationFile, configurationFile + ".bak", true);
                }
            }

            // create the configuration file from the default.
            if (!useExisting)
            {
                try
                {
                    string installationFile = Utils.Format(
                        "{0}\\Install\\{1}.Config.xml",
                        executableFileInfo.Directory.Parent.FullName,
                        applicationName);

                    if (!File.Exists(installationFile))
                    {
                        Utils.Trace("Could not find default configuation at: {0}", installationFile);
                    }

                    File.Copy(installationFile, configurationFile, true);
                    Utils.Trace("File.Copy({0}, {1})", installationFile, configurationFile);
                }
                catch (Exception e)
                {
                    Utils.Trace("Could not copy default configuation to: {0}. Error={1}.", configurationFile, e.Message);
                }
            }

            // create a default application name.
            if (String.IsNullOrEmpty(application.ApplicationName))
            {
                application.ApplicationName = applicationName;
            }

            // create a default product name.
            if (String.IsNullOrEmpty(application.ProductName))
            {
                application.ProductName = application.ApplicationName;
            }

            // create a default uri.
            if (String.IsNullOrEmpty(application.ApplicationUri))
            {
                application.ApplicationUri = Utils.Format("http://localhost/{0}/{1}", applicationName, Guid.NewGuid());
            }

            // make the uri specify the local machine.
            application.ApplicationUri = Utils.ReplaceLocalhost(application.ApplicationUri);

            // set a default application store.
            if (application.ApplicationCertificate == null)
            {
                application.ApplicationCertificate           = new Opc.Ua.Security.CertificateIdentifier();
                application.ApplicationCertificate.StoreType = Utils.DefaultStoreType;
                application.ApplicationCertificate.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault";
            }

            if (application.UseDefaultCertificateStores)
            {
                if (application.IssuerCertificateStore == null)
                {
                    application.IssuerCertificateStore           = new Opc.Ua.Security.CertificateStoreIdentifier();
                    application.IssuerCertificateStore.StoreType = Utils.DefaultStoreType;
                    application.IssuerCertificateStore.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault";
                }

                if (application.TrustedCertificateStore == null)
                {
                    application.TrustedCertificateStore           = new Opc.Ua.Security.CertificateStoreIdentifier();
                    application.TrustedCertificateStore.StoreType = Utils.DefaultStoreType;
                    application.TrustedCertificateStore.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault";
                }

                try
                {
                    Utils.GetAbsoluteDirectoryPath(application.TrustedCertificateStore.StorePath, true, true, true);
                }
                catch (Exception e)
                {
                    Utils.Trace("Could not access the machine directory: {0} '{1}'", application.RejectedCertificatesStore.StorePath, e);
                }

                if (application.RejectedCertificatesStore == null)
                {
                    application.RejectedCertificatesStore           = new Opc.Ua.Security.CertificateStoreIdentifier();
                    application.RejectedCertificatesStore.StoreType = CertificateStoreType.Directory;
                    application.RejectedCertificatesStore.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\RejectedCertificates";

                    StringBuilder buffer = new StringBuilder();

                    buffer.Append(ApplicationData.Current.LocalFolder.Path);
                    buffer.Append("\\OPC Foundation");
                    buffer.Append("\\RejectedCertificates");

                    string folderPath = buffer.ToString();

                    if (!Directory.Exists(folderPath))
                    {
                        Directory.CreateDirectory(folderPath);
                    }
                }
            }

            // check for valid certificate (discard invalid certificates).
            CertificateIdentifier applicationCertificate = Opc.Ua.Security.SecuredApplication.FromCertificateIdentifier(application.ApplicationCertificate);
            X509Certificate2      certificate            = await applicationCertificate.Find(true);

            if (certificate == null)
            {
                certificate = await applicationCertificate.Find(false);

                if (certificate != null)
                {
                    Utils.Trace(
                        "Found existing certificate but it does not have a private key: Store={0}, Certificate={1}",
                        application.ApplicationCertificate.StorePath,
                        application.ApplicationCertificate);
                }
                else
                {
                    Utils.Trace(
                        "Existing certificate could not be found: Store={0}, Certificate={1}",
                        application.ApplicationCertificate.StorePath,
                        application.ApplicationCertificate);
                }
            }

            // check if no certificate exists.
            if (certificate == null)
            {
                certificate = await CreateCertificateForApplication(application);
            }

            // ensure the application certificate is in the trusted peers store.
            try
            {
                CertificateStoreIdentifier certificateStore = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(application.TrustedCertificateStore);

                using (ICertificateStore store = certificateStore.OpenStore())
                {
                    X509Certificate2Collection peerCertificates = await store.FindByThumbprint(certificate.Thumbprint);

                    if (peerCertificates.Count == 0)
                    {
                        await store.Add(new X509Certificate2(certificate.RawData));
                    }
                }
            }
            catch (Exception e)
            {
                Utils.Trace(
                    "Could not add certificate '{0}' to trusted peer store '{1}'. Error={2}",
                    certificate.Subject,
                    application.TrustedCertificateStore,
                    e.Message);
            }

            // update configuration file location.
            UpdateConfigurationLocation(executableFile, configurationFile);

            // update configuration file.
            new Opc.Ua.Security.SecurityConfigurationManager().WriteConfiguration(configurationFile, application);

            ApplicationAccessRuleCollection accessRules = application.AccessRules;
            bool noRulesDefined = application.AccessRules == null || application.AccessRules.Count == 0;

            // add the default access rules.
            if (noRulesDefined)
            {
                ApplicationAccessRule rule = new ApplicationAccessRule();

                rule.IdentityName = WellKnownSids.Administrators;
                rule.RuleType     = AccessControlType.Allow;
                rule.Right        = ApplicationAccessRight.Configure;

                accessRules.Add(rule);

                rule = new ApplicationAccessRule();

                rule.IdentityName = WellKnownSids.Users;
                rule.RuleType     = AccessControlType.Allow;
                rule.Right        = ApplicationAccessRight.Update;

                accessRules.Add(rule);
            }

            // ensure the service account has priviledges.
            if (application.InstallAsService)
            {
                // check if a specific account is assigned.
                AccountInfo accountInfo = null;

                if (!String.IsNullOrEmpty(application.ServiceUserName))
                {
                    accountInfo = AccountInfo.Create(application.ServiceUserName);
                }

                // choose a built-in service account.
                if (accountInfo == null)
                {
                    accountInfo = AccountInfo.Create(WellKnownSids.NetworkService);

                    if (accountInfo == null)
                    {
                        accountInfo = AccountInfo.Create(WellKnownSids.LocalSystem);
                    }
                }

                ApplicationAccessRule rule = new ApplicationAccessRule();

                rule.IdentityName = accountInfo.ToString();
                rule.RuleType     = AccessControlType.Allow;
                rule.Right        = ApplicationAccessRight.Run;

                accessRules.Add(rule);
            }

            // set the permissions for the HTTP endpoints used by the application.
            if (configureFirewall && application.BaseAddresses != null && application.BaseAddresses.Count > 0)
            {
                for (int ii = 0; ii < application.BaseAddresses.Count; ii++)
                {
                    Uri url = Utils.ParseUri(application.BaseAddresses[ii]);

                    if (url != null)
                    {
                        try
                        {
                            HttpAccessRule.SetAccessRules(url, accessRules, true);
                            Utils.Trace("Added HTTP access rules for URL: {0}", url);
                        }
                        catch (Exception e)
                        {
                            Utils.Trace("Could not set HTTP access rules for URL: {0}. Error={1}", url, e.Message);

                            for (int jj = 0; jj < accessRules.Count; jj++)
                            {
                                ApplicationAccessRule rule = accessRules[jj];

                                Utils.Trace(
                                    (int)Utils.TraceMasks.Error,
                                    "IdentityName={0}, Right={1}, RuleType={2}",
                                    rule.IdentityName,
                                    rule.Right,
                                    rule.RuleType);
                            }
                        }
                    }
                }
            }

            // set permissions on the local certificate store.
            SetCertificatePermissions(
                application,
                applicationCertificate,
                accessRules,
                false);

            // set permissions on the local certificate store.
            if (application.RejectedCertificatesStore != null)
            {
                // need to grant full control to certificates in the RejectedCertificatesStore.
                foreach (ApplicationAccessRule rule in accessRules)
                {
                    if (rule.RuleType == AccessControlType.Allow)
                    {
                        rule.Right = ApplicationAccessRight.Configure;
                    }
                }

                CertificateStoreIdentifier rejectedCertificates = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(application.RejectedCertificatesStore);

                using (ICertificateStore store = rejectedCertificates.OpenStore())
                {
                    if (store.SupportsAccessControl)
                    {
                        store.SetAccessRules(accessRules, false);
                    }
                }
            }
        }
コード例 #28
0
        private async void CertificateRequestTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                NodeId requestId = NodeId.Parse(m_application.CertificateRequestId);

                byte[]   privateKeyPFX      = null;
                byte[][] issuerCertificates = null;

                byte[] certificate = m_gds.FinishRequest(
                    m_application.ApplicationId,
                    requestId,
                    out privateKeyPFX,
                    out issuerCertificates);

                if (certificate == null)
                {
                    // request not done yet, try again in a few seconds
                    return;
                }

                CertificateRequestTimer.Enabled = false;
                RequestProgressLabel.Visible    = false;

                if (m_application.RegistrationType != RegistrationType.ServerPush)
                {
                    X509Certificate2 newCert = new X509Certificate2(certificate);

                    if (!String.IsNullOrEmpty(m_application.CertificateStorePath) && !String.IsNullOrEmpty(m_application.CertificateSubjectName))
                    {
                        CertificateIdentifier cid = new CertificateIdentifier()
                        {
                            StorePath   = m_application.CertificateStorePath,
                            StoreType   = CertificateStoreIdentifier.DetermineStoreType(m_application.CertificateStorePath),
                            SubjectName = m_application.CertificateSubjectName.Replace("localhost", Utils.GetHostName())
                        };

                        // update store
                        using (var store = CertificateStoreIdentifier.OpenStore(m_application.CertificateStorePath))
                        {
                            // if we used a CSR, we already have a private key and therefore didn't request one from the GDS
                            // in this case, privateKey is null
                            if (privateKeyPFX == null)
                            {
                                X509Certificate2 oldCertificate = await cid.Find(true);

                                if (oldCertificate != null && oldCertificate.HasPrivateKey)
                                {
                                    oldCertificate = await cid.LoadPrivateKey(string.Empty);

                                    newCert = CertificateFactory.CreateCertificateWithPrivateKey(newCert, oldCertificate);
                                    await store.Delete(oldCertificate.Thumbprint);
                                }
                                else
                                {
                                    throw new ServiceResultException("Failed to merge signed certificate with the private key.");
                                }
                            }
                            else
                            {
                                newCert = new X509Certificate2(privateKeyPFX, string.Empty, X509KeyStorageFlags.Exportable);
                                newCert = CertificateFactory.Load(newCert, true);
                            }

                            await store.Add(newCert);
                        }
                    }
                    else
                    {
                        DialogResult result = DialogResult.Yes;
                        string       absoluteCertificatePublicKeyPath = Utils.GetAbsoluteFilePath(m_application.CertificatePublicKeyPath, true, false, false) ?? m_application.CertificatePublicKeyPath;
                        FileInfo     file = new FileInfo(absoluteCertificatePublicKeyPath);
                        if (file.Exists)
                        {
                            result = MessageBox.Show(
                                Parent,
                                "Replace certificate " +
                                absoluteCertificatePublicKeyPath +
                                "?",
                                Parent.Text,
                                MessageBoxButtons.YesNo,
                                MessageBoxIcon.Exclamation);
                        }

                        if (result == DialogResult.Yes)
                        {
                            byte[] exportedCert;
                            if (string.Compare(file.Extension, ".PEM", true) == 0)
                            {
                                exportedCert = CertificateFactory.ExportCertificateAsPEM(newCert);
                            }
                            else
                            {
                                exportedCert = newCert.Export(X509ContentType.Cert);
                            }
                            File.WriteAllBytes(absoluteCertificatePublicKeyPath, exportedCert);
                        }

                        // if we provided a PFX or P12 with the private key, we need to merge the new cert with the private key
                        if (m_application.GetPrivateKeyFormat(m_server?.GetSupportedKeyFormats()) == "PFX")
                        {
                            string absoluteCertificatePrivateKeyPath = Utils.GetAbsoluteFilePath(m_application.CertificatePrivateKeyPath, true, false, false) ?? m_application.CertificatePrivateKeyPath;
                            file = new FileInfo(absoluteCertificatePrivateKeyPath);
                            if (file.Exists)
                            {
                                result = MessageBox.Show(
                                    Parent,
                                    "Replace private key " +
                                    absoluteCertificatePrivateKeyPath +
                                    "?",
                                    Parent.Text,
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Exclamation);
                            }

                            if (result == DialogResult.Yes)
                            {
                                if (file.Exists)
                                {
                                    byte[]           pkcsData       = File.ReadAllBytes(absoluteCertificatePrivateKeyPath);
                                    X509Certificate2 oldCertificate = CertificateFactory.CreateCertificateFromPKCS12(pkcsData, m_certificatePassword);
                                    newCert  = CertificateFactory.CreateCertificateWithPrivateKey(newCert, oldCertificate);
                                    pkcsData = newCert.Export(X509ContentType.Pfx, m_certificatePassword);
                                    File.WriteAllBytes(absoluteCertificatePrivateKeyPath, pkcsData);

                                    if (privateKeyPFX != null)
                                    {
                                        throw new ServiceResultException("Did not expect a private key for this operation.");
                                    }
                                }
                                else
                                {
                                    File.WriteAllBytes(absoluteCertificatePrivateKeyPath, privateKeyPFX);
                                }
                            }
                        }
                    }

                    // update trust list.
                    if (!String.IsNullOrEmpty(m_application.TrustListStorePath))
                    {
                        using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_application.TrustListStorePath))
                        {
                            foreach (byte[] issuerCertificate in issuerCertificates)
                            {
                                X509Certificate2           x509  = new X509Certificate2(issuerCertificate);
                                X509Certificate2Collection certs = await store.FindByThumbprint(x509.Thumbprint);

                                if (certs.Count == 0)
                                {
                                    await store.Add(new X509Certificate2(issuerCertificate));
                                }
                            }
                        }
                    }

                    m_certificate = newCert;
                }
                else
                {
                    if (privateKeyPFX != null && privateKeyPFX.Length > 0)
                    {
                        var x509 = new X509Certificate2(privateKeyPFX, m_certificatePassword, X509KeyStorageFlags.Exportable);
                        privateKeyPFX = x509.Export(X509ContentType.Pfx);
                    }
                    bool applyChanges = m_server.UpdateCertificate(
                        null,
                        m_server.ApplicationCertificateType,
                        certificate,
                        (privateKeyPFX != null) ? "PFX" : null,
                        privateKeyPFX,
                        issuerCertificates);
                    if (applyChanges)
                    {
                        MessageBox.Show(
                            Parent,
                            "The certificate was updated, however, the apply changes command must be sent before the server will use the new certificate.",
                            Parent.Text,
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);

                        ApplyChangesButton.Enabled = true;
                    }
                }

                CertificateControl.ShowValue(null, "Application Certificate", new CertificateWrapper()
                {
                    Certificate = m_certificate
                }, true);
            }
            catch (Exception exception)
            {
                if (exception is ServiceResultException sre && sre.StatusCode == StatusCodes.BadNothingToDo)
                {
                    return;
                }

                RequestProgressLabel.Visible    = false;
                CertificateRequestTimer.Enabled = false;
                Opc.Ua.Client.Controls.ExceptionDlg.Show(Text, exception);
            }
        }
コード例 #29
0
        /// <summary>
        /// Initializes the validator from the configuration for a token policy.
        /// </summary>
        /// <param name="issuerCertificate">The issuer certificate.</param>
        private SecurityTokenResolver CreateSecurityTokenResolver(CertificateIdentifier issuerCertificate)
        {
            if (issuerCertificate == null) 
            {
                throw new ArgumentNullException("issuerCertificate");
            }

            // find the certificate.
            X509Certificate2 certificate = issuerCertificate.Find(false);
            
            if (certificate == null) 
            {
                throw ServiceResultException.Create(
                    StatusCodes.BadCertificateInvalid, 
                    "Could not find issuer certificate: {0}", 
                    issuerCertificate);
            }
            
            // create a security token representing the certificate.
            List<SecurityToken> tokens = new List<SecurityToken>();
            tokens.Add(new X509SecurityToken(certificate));

            // create issued token resolver.
            SecurityTokenResolver tokenResolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
                new System.Collections.ObjectModel.ReadOnlyCollection<SecurityToken>(tokens), 
                false);

            return tokenResolver;
        }
コード例 #30
0
        /// <summary>
        /// Creates a SAML token for the specified email address.
        /// </summary>
        public static async System.Threading.Tasks.Task <UserIdentity> CreateSAMLTokenAsync(string emailAddress)
        {
            // Normally this would be done by a server that is capable of verifying that
            // the user is a legimate holder of email address. Using a local certficate to
            // signed the SAML token is a short cut that would never be done in a real system.
            CertificateIdentifier userid = new CertificateIdentifier();

            userid.StoreType   = CertificateStoreType.X509Store;
            userid.StorePath   = "LocalMachine\\My";
            userid.SubjectName = "UA Sample Client";

            X509Certificate2 certificate = await userid.Find();

            X509SecurityToken signingToken = new X509SecurityToken(certificate);

            // Create list of confirmation strings
            List <string> confirmations = new List <string>();

            // Add holder-of-key string to list of confirmation strings
            confirmations.Add("urn:oasis:names:tc:SAML:1.0:cm:bearer");

            // Create SAML subject statement based on issuer member variable, confirmation string collection
            // local variable and proof key identifier parameter
            SamlSubject subject = new SamlSubject("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", null, emailAddress);

            // Create a list of SAML attributes
            List <SamlAttribute> attributes = new List <SamlAttribute>();
            Claim claim = Claim.CreateNameClaim(emailAddress);

            attributes.Add(new SamlAttribute(claim));

            // Create list of SAML statements
            List <SamlStatement> statements = new List <SamlStatement>();

            // Add a SAML attribute statement to the list of statements. Attribute statement is based on
            // subject statement and SAML attributes resulting from claims
            statements.Add(new SamlAttributeStatement(subject, attributes));

            // Create a valid from/until condition
            DateTime validFrom = DateTime.UtcNow;
            DateTime validTo   = DateTime.UtcNow.AddHours(12);

            SamlConditions conditions = new SamlConditions(validFrom, validTo);

            // Create the SAML assertion
            SamlAssertion assertion = new SamlAssertion(
                "_" + Guid.NewGuid().ToString(),
                signingToken.Certificate.Subject,
                validFrom,
                conditions,
                null,
                statements);

            SecurityKey signingKey = new System.IdentityModel.Tokens.RsaSecurityKey((RSA)signingToken.Certificate.PrivateKey);

            // Set the signing credentials for the SAML assertion
            assertion.SigningCredentials = new SigningCredentials(
                signingKey,
                System.IdentityModel.Tokens.SecurityAlgorithms.RsaSha1Signature,
                System.IdentityModel.Tokens.SecurityAlgorithms.Sha1Digest,
                new SecurityKeyIdentifier(signingToken.CreateKeyIdentifierClause <X509ThumbprintKeyIdentifierClause>()));
            // TODO
            // return new UserIdentity(new SamlSecurityToken(assertion));
            throw new NotImplementedException();
        }
コード例 #31
0
        private async void CertificateRequestTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                NodeId requestId = NodeId.Parse(m_application.CertificateRequestId);

                byte[]   privateKey         = null;
                byte[][] issuerCertificates = null;

                byte[] certificate = m_gds.FinishRequest(
                    m_application.ApplicationId,
                    requestId,
                    out privateKey,
                    out issuerCertificates);

                if (certificate == null)
                {
                    return;
                }

                CertificateRequestTimer.Enabled = false;
                RequestProgressLabel.Visible    = false;

                if (m_application.RegistrationType != RegistrationType.ServerPush)
                {
                    // save public key.
                    if (!String.IsNullOrEmpty(m_application.CertificatePublicKeyPath))
                    {
                        string file = Utils.GetAbsoluteFilePath(m_application.CertificatePublicKeyPath, true, false, true);
                        File.WriteAllBytes(file, certificate);
                    }

                    // check if the private was re-used.
                    if (privateKey == null || privateKey.Length == 0)
                    {
                        if (!String.IsNullOrEmpty(m_application.CertificatePrivateKeyPath))
                        {
                            string path = Utils.GetAbsoluteFilePath(m_application.CertificatePrivateKeyPath, true, true, true);

                            if (path != null)
                            {
                                if (!m_application.CertificatePrivateKeyPath.EndsWith("PEM", StringComparison.OrdinalIgnoreCase))
                                {
                                    var x509   = new X509Certificate2(certificate);
                                    var oldPfx = new X509Certificate2(path, (string)null, X509KeyStorageFlags.Exportable);
                                    var newPfx = CertificateAuthority.Replace(x509, oldPfx);
                                    var bytes  = newPfx.Export(X509ContentType.Pfx);
                                    File.WriteAllBytes(path, bytes);
                                }
                            }
                        }
                        else
                        {
                            if (!String.IsNullOrEmpty(m_application.CertificateStorePath) && !String.IsNullOrEmpty(m_application.CertificateSubjectName))
                            {
                                var x509 = new X509Certificate2(certificate);

                                var cid = new CertificateIdentifier()
                                {
                                    StorePath   = m_application.CertificateStorePath,
                                    SubjectName = m_application.CertificateSubjectName.Replace("localhost", System.Net.Dns.GetHostName())
                                };

                                var oldPfx = await cid.Find(true);

                                if (oldPfx != null)
                                {
                                    var newPfx = CertificateAuthority.Replace(x509, oldPfx);

                                    using (var store = CertificateStoreIdentifier.OpenStore(m_application.CertificateStorePath))
                                    {
                                        await store.Delete(oldPfx.Thumbprint);

                                        await store.Add(newPfx);
                                    }
                                }
                            }
                        }
                    }

                    // save private key.
                    else
                    {
                        if (!String.IsNullOrEmpty(m_application.CertificatePrivateKeyPath))
                        {
                            string path = Utils.GetAbsoluteFilePath(m_application.CertificatePrivateKeyPath, true, true, true);

                            if (path != null)
                            {
                                File.WriteAllBytes(path, privateKey);
                            }
                        }
                        else
                        {
                            if (!String.IsNullOrEmpty(m_application.CertificateStorePath) && !String.IsNullOrEmpty(m_application.CertificateSubjectName))
                            {
                                var cid = new CertificateIdentifier()
                                {
                                    StorePath   = m_application.CertificateStorePath,
                                    SubjectName = m_application.CertificateSubjectName
                                };

                                var oldCertificate = await cid.Find();

                                using (var store = CertificateStoreIdentifier.OpenStore(m_application.CertificateStorePath))
                                {
                                    if (oldCertificate != null)
                                    {
                                        await store.Delete(oldCertificate.Thumbprint);
                                    }

                                    var x509 = new X509Certificate2(privateKey, new System.Security.SecureString(), X509KeyStorageFlags.Exportable);
                                    x509 = CertificateFactory.Load(x509, true);
                                    await store.Add(x509);
                                }
                            }
                        }
                    }

                    // update trust list.
                    if (!String.IsNullOrEmpty(m_application.TrustListStorePath))
                    {
                        using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_application.TrustListStorePath))
                        {
                            foreach (var issuerCertificate in issuerCertificates)
                            {
                                var x509 = new X509Certificate2(issuerCertificate);

                                if (store.FindByThumbprint(x509.Thumbprint) == null)
                                {
                                    await store.Add(new X509Certificate2(issuerCertificate));
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (privateKey != null && privateKey.Length > 0)
                    {
                        var x509 = new X509Certificate2(privateKey, m_certificatePassword, X509KeyStorageFlags.Exportable);
                        privateKey = x509.Export(X509ContentType.Pfx);
                    }

                    bool applyChanges = m_server.UpdateCertificate(null, null, certificate, GetPrivateKeyFormat(), privateKey, issuerCertificates);

                    if (applyChanges)
                    {
                        MessageBox.Show(
                            Parent,
                            "The certificate was updated, however, the apply changes command must be sent before the server will use the new certificate.",
                            Parent.Text,
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);

                        ApplyChangesButton.Enabled = true;
                    }
                }

                m_certificate = new X509Certificate2(certificate);
                CertificateControl.ShowValue(null, "Application Certificate", new CertificateWrapper()
                {
                    Certificate = m_certificate
                }, true);
            }
            catch (Exception exception)
            {
                var sre = exception as ServiceResultException;

                if (sre != null && sre.StatusCode == StatusCodes.BadNothingToDo)
                {
                    return;
                }

                MessageBox.Show(Parent.Text + ": " + exception.Message);
                CertificateRequestTimer.Enabled = false;
            }
        }
コード例 #32
0
        private void RequestNewButton_Click(object sender, EventArgs e)
        {
            try
            {
                NodeId requestId = null;

                bool newPrivateKeyRequired = false;

                if (!String.IsNullOrEmpty(m_application.CertificatePrivateKeyPath))
                {
                    string path = Utils.GetAbsoluteFilePath(m_application.CertificatePrivateKeyPath, true, false, false);
                    newPrivateKeyRequired = path == null;
                }
                else if (!String.IsNullOrEmpty(m_application.CertificateStorePath))
                {
                    CertificateIdentifier id = new CertificateIdentifier();

                    id.StoreType   = CertificateStoreIdentifier.DetermineStoreType(m_application.CertificateStorePath);
                    id.StorePath   = m_application.CertificateStorePath;
                    id.SubjectName = m_application.CertificateSubjectName.Replace("localhost", System.Net.Dns.GetHostName());

                    newPrivateKeyRequired = id.Find(true) == null;
                }
                else if (!String.IsNullOrEmpty(m_application.ServerUrl))
                {
                    newPrivateKeyRequired = true;
                }

                byte[] certificateRequest = null;

                if (m_application.RegistrationType == RegistrationType.ServerPush)
                {
                    byte[] nonce = new byte[32];
                    System.Security.Cryptography.RandomNumberGenerator.Create().GetBytes(nonce);
                    certificateRequest    = m_server.CreateCertificateRequest(null, null, null, false, nonce);
                    newPrivateKeyRequired = false;

                    if (m_server.Endpoint != null && m_server.Endpoint.Description.ServerCertificate != null)
                    {
                        m_certificate = new X509Certificate2(m_server.Endpoint.Description.ServerCertificate);
                    }
                }

                if (newPrivateKeyRequired || RequestNewPrivateKey || m_certificate == null)
                {
                    m_certificatePassword = null; // Guid.NewGuid().ToString();

                    string   privateKeyFormat = GetPrivateKeyFormat();
                    string[] domainNames      = GetDomainNames();
                    string   subjectName      = GetSubjectName(domainNames);

                    requestId = m_gds.StartNewKeyPairRequest(
                        m_application.ApplicationId,
                        null,
                        null,
                        subjectName,
                        domainNames,
                        privateKeyFormat,
                        m_certificatePassword);
                }
                else
                {
                    if (certificateRequest == null)
                    {
                        var    certificate = m_certificate;
                        byte[] privateKey  = null;
                        bool   isPemKey    = false;

                        if (!certificate.HasPrivateKey)
                        {
                            if (!String.IsNullOrEmpty(m_application.CertificatePrivateKeyPath))
                            {
                                string path = Utils.GetAbsoluteFilePath(m_application.CertificatePrivateKeyPath, true, false, false);

                                if (path != null)
                                {
                                    privateKey = File.ReadAllBytes(path);
                                    isPemKey   = path.EndsWith("PEM", StringComparison.OrdinalIgnoreCase);
                                }
                            }
                        }

                        certificateRequest = CertificateAuthority.CreateRequest(
                            certificate,
                            privateKey,
                            isPemKey,
                            null,
                            null,
                            null,
                            null,
                            256);
                    }

                    requestId = m_gds.StartSigningRequest(m_application.ApplicationId, null, null, certificateRequest);
                }

                m_application.CertificateRequestId = requestId.ToString();
                CertificateRequestTimer.Enabled    = true;
                RequestProgressLabel.Visible       = true;
                WarningLabel.Visible = false;
            }
            catch (Exception exception)
            {
                MessageBox.Show(Parent.Text + ": " + exception.Message);
            }
        }
コード例 #33
0
        /// <summary>
        /// Displays the dialog.
        /// </summary>
        public bool ShowDialog(CertificateIdentifier certificate)
        {
            m_certificate = certificate;

            CertificateStoreCTRL.StoreType = null;
            CertificateStoreCTRL.StorePath = null;
            CertificateStoreCTRL.ReadOnly  = true;
            ApplicationNameTB.Text         = null;
            ApplicationUriTB.Text          = null;
            OrganizationTB.Text            = null;
            DomainsTB.Text     = System.Net.Dns.GetHostName();
            SubjectNameTB.Text = null;
            IssuerNameTB.Text  = null;
            ValidFromTB.Text   = null;
            ValidToTB.Text     = null;
            ThumbprintTB.Text  = null;

            if (certificate != null)
            {
                CertificateStoreCTRL.StoreType = certificate.StoreType;
                CertificateStoreCTRL.StorePath = certificate.StorePath;
                SubjectNameTB.Text             = certificate.SubjectName;
                ThumbprintTB.Text = certificate.Thumbprint;

                X509Certificate2 data = certificate.Find();

                if (data != null)
                {
                    // fill in subject name.
                    StringBuilder buffer = new StringBuilder();

                    foreach (string element in Utils.ParseDistinguishedName(data.Subject))
                    {
                        if (element.StartsWith("CN="))
                        {
                            ApplicationNameTB.Text = element.Substring(3);
                        }

                        if (element.StartsWith("O="))
                        {
                            OrganizationTB.Text = element.Substring(2);
                        }

                        if (buffer.Length > 0)
                        {
                            buffer.Append('/');
                        }

                        buffer.Append(element);
                    }

                    if (buffer.Length > 0)
                    {
                        SubjectNameTB.Text = buffer.ToString();
                    }

                    // fill in issuer name.
                    buffer = new StringBuilder();

                    foreach (string element in Utils.ParseDistinguishedName(data.Issuer))
                    {
                        if (buffer.Length > 0)
                        {
                            buffer.Append('/');
                        }

                        buffer.Append(element);
                    }

                    if (buffer.Length > 0)
                    {
                        IssuerNameTB.Text = buffer.ToString();
                    }

                    // fill in application uri.
                    string applicationUri = Utils.GetApplicationUriFromCertficate(data);

                    if (!String.IsNullOrEmpty(applicationUri))
                    {
                        ApplicationUriTB.Text = applicationUri;
                    }

                    // fill in domains.
                    buffer = new StringBuilder();

                    foreach (string domain in Utils.GetDomainsFromCertficate(data))
                    {
                        if (buffer.Length > 0)
                        {
                            buffer.Append(", ");
                        }

                        buffer.Append(domain);
                    }

                    if (buffer.Length > 0)
                    {
                        DomainsTB.Text = buffer.ToString();
                    }

                    ValidFromTB.Text  = data.NotBefore.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
                    ValidToTB.Text    = data.NotAfter.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
                    ThumbprintTB.Text = data.Thumbprint;
                }
            }

            if (ShowDialog() != DialogResult.OK)
            {
                return(false);
            }

            return(true);
        }
コード例 #34
0
        private void ExportBTN_Click(object sender, EventArgs e)
        {
            try {
                const string caption = "Export Certificate";

                if (m_currentDirectory == null)
                {
                    m_currentDirectory = Utils.GetAbsoluteDirectoryPath("%LocalApplicationData%", false, false, false);
                }

                if (m_currentDirectory == null)
                {
                    m_currentDirectory = Environment.CurrentDirectory;
                }

                X509Certificate2 certificate = m_certificate.Find();

                if (certificate == null)
                {
                    MessageBox.Show("Cannot export an invalid certificate.", caption, MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
                    return;
                }

                string displayName = null;

                foreach (string element in Utils.ParseDistinguishedName(certificate.Subject))
                {
                    if (element.StartsWith("CN="))
                    {
                        displayName = element.Substring(3);
                        break;
                    }
                }

                StringBuilder filePath = new StringBuilder();

                if (!String.IsNullOrEmpty(displayName))
                {
                    filePath.Append(displayName);
                    filePath.Append(" ");
                }

                filePath.Append("[");
                filePath.Append(certificate.Thumbprint);
                filePath.Append("].der");

                SaveFileDialog dialog = new SaveFileDialog();

                dialog.CheckFileExists  = false;
                dialog.CheckPathExists  = true;
                dialog.DefaultExt       = ".der";
                dialog.Filter           = "Certificate Files (*.der)|*.der|All Files (*.*)|*.*";
                dialog.ValidateNames    = true;
                dialog.Title            = "Save Certificate File";
                dialog.FileName         = filePath.ToString();
                dialog.InitialDirectory = m_currentDirectory;

                if (dialog.ShowDialog() != DialogResult.OK)
                {
                    return;
                }

                FileInfo fileInfo = new FileInfo(dialog.FileName);
                m_currentDirectory = fileInfo.DirectoryName;

                // save the file.
                using (Stream ostrm = fileInfo.Open(FileMode.Create, FileAccess.ReadWrite, FileShare.None)) {
                    byte[] data = certificate.RawData;
                    ostrm.Write(data, 0, data.Length);
                }
            } catch (Exception exception) {
                GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
            }
        }
コード例 #35
0
        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);
            }
        }
コード例 #36
0
        public static EndpointDescription CreateEndpointDescription(UAServer myServer)
        {
            // create the endpoint description.
            EndpointDescription endpointDescription = null;

            try
            {
                string discoveryUrl = myServer.ServerName;
                //OA 2018-04-27
                if (!discoveryUrl.StartsWith(Utils.UriSchemeOpcTcp) && !discoveryUrl.StartsWith(Utils.UriSchemeHttps))
                //if (!discoveryUrl.StartsWith(Utils.UriSchemeOpcTcp))
                {
                    if (!discoveryUrl.EndsWith("/discovery"))
                    {
                        discoveryUrl += "/discovery";
                    }
                }

                // parse the selected URL.
                Uri uri = new Uri(discoveryUrl);

                // set a short timeout because this is happening in the drop down event.
                EndpointConfiguration configuration = EndpointConfiguration.Create();
                configuration.OperationTimeout = 5000;

                //OA 2018-04-27 https
                if (discoveryUrl.StartsWith(Utils.UriSchemeHttps))
                {
                    configuration.OperationTimeout = 0;
                }
                //

                // Connect to the server's discovery endpoint and find the available configuration.
                using (DiscoveryClient client = DiscoveryClient.Create(uri, configuration))
                {
                    EndpointDescriptionCollection endpoints = client.GetEndpoints(null);

                    // select the best endpoint to use based on the selected URL and the UseSecurity checkbox.
                    for (int ii = 0; ii < endpoints.Count; ii++)
                    {
                        EndpointDescription endpoint = endpoints[ii];

                        // check for a match on the URL scheme.
                        if (endpoint.EndpointUrl.StartsWith(uri.Scheme))
                        {
                            // check if security was requested.
                            if (!myServer.SecurityPolicy.Equals("None"))
                            {
                                if (endpoint.SecurityMode == MessageSecurityMode.None)
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                if (endpoint.SecurityMode != MessageSecurityMode.None)
                                {
                                    continue;
                                }
                            }

                            // pick the first available endpoint by default.
                            if (endpointDescription == null)
                            {
                                endpointDescription = endpoint;
                            }

                            // The security level is a relative measure assigned by the server to the
                            // endpoints that it returns. Clients should always pick the highest level
                            // unless they have a reason not too.
                            if (endpoint.SecurityLevel > endpointDescription.SecurityLevel)
                            {
                                endpointDescription = endpoint;
                            }
                        }
                    }

                    // pick the first available endpoint by default.
                    if (endpointDescription == null && endpoints.Count > 0)
                    {
                        endpointDescription = endpoints[0];
                    }
                }

                // if a server is behind a firewall it may return URLs that are not accessible to the client.
                // This problem can be avoided by assuming that the domain in the URL used to call
                // GetEndpoints can be used to access any of the endpoints. This code makes that conversion.
                // Note that the conversion only makes sense if discovery uses the same protocol as the endpoint.

                Uri endpointUrl = Utils.ParseUri(endpointDescription.EndpointUrl);



                if (endpointUrl != null && endpointUrl.Scheme == uri.Scheme)
                {
                    UriBuilder builder = new UriBuilder(endpointUrl);
                    builder.Host = uri.DnsSafeHost;
                    builder.Port = uri.Port;
                    endpointDescription.EndpointUrl = builder.ToString();
                }
            }
            catch
            {
                endpointDescription             = new EndpointDescription();
                endpointDescription.EndpointUrl = myServer.ServerName;

                //ABA 2014-10-10
                if (myServer.SecurityPolicy.Equals("None"))
                {
                    endpointDescription.SecurityPolicyUri = SecurityPolicies.None;
                }
                //Commented by MM 03/07/2019
                //else if (myServer.SecurityPolicy.Equals("Basic128Rsa15"))
                //{
                //    endpointDescription.SecurityPolicyUri = SecurityPolicies.Basic128Rsa15;
                //}
                else if (myServer.SecurityPolicy.Equals("Basic256Sha256"))
                {
                    endpointDescription.SecurityPolicyUri = SecurityPolicies.Basic256Sha256;
                }
                else if (myServer.SecurityPolicy.Equals("Basic256"))
                {
                    endpointDescription.SecurityPolicyUri = SecurityPolicies.Basic256;
                }

                try
                {
                    MessageSecurityMode myMode;
                    myMode = (MessageSecurityMode)Enum.Parse(typeof(MessageSecurityMode), myServer.SecurityMode, false);
                    //endpointDescription.SecurityMode      = MessageSecurityMode.SignAndEncrypt;
                    endpointDescription.SecurityMode = myMode;
                }
                catch
                {
                    endpointDescription.SecurityMode = MessageSecurityMode.None;
                }

                // specify the transport profile.
                if (myServer.Protocol.Equals("opc.tcp"))
                {
                    endpointDescription.TransportProfileUri = Profiles.UaTcpTransport;
                }
                //added OA 2018-04-27
                else if (myServer.Protocol.Equals("http"))
                {
                    //OA-2018-06-18  endpointDescription.TransportProfileUri = Profiles.WsHttpXmlOrBinaryTransport;
                }
                else //added OA 2018-04-27
                {
                    endpointDescription.TransportProfileUri = Profiles.HttpsBinaryTransport; //OA-2018-06-18 HttpsXmlOrBinaryTransport;
                }
                //else  //OA 2018-04-27
                //{
                //    endpointDescription.TransportProfileUri = Profiles.WsHttpXmlOrBinaryTransport;
                //}

                if (myServer.UserIdentity.Equals(UserIdentityType.Certificate))
                {
                    // load the the server certificate from the local certificate store.
                    CertificateIdentifier certificateIdentifier = new CertificateIdentifier();

                    certificateIdentifier.StoreType = CertificateStoreType.X509Store; //OA-2018-06-18 .Windows;

                    if (!String.IsNullOrEmpty(myServer.CertificationStore))
                    {
                        //certificateIdentifier.StorePath = "LocalMachine\\UA Applications";
                        certificateIdentifier.StorePath = myServer.CertificationStore;
                    }
                    else
                    {
                        using (System.IO.FileStream fs = System.IO.File.OpenRead(myServer.CertificationPath))
                        {
                            byte[] bytes = new byte[fs.Length];
                            fs.Read(bytes, 0, Convert.ToInt32(fs.Length));

                            certificateIdentifier.RawData = bytes;
                        }
                    }

                    //certificateIdentifier.SubjectName = "ONBServer";//commented by HHA 12/11//2019

                    //OA-2018-06-25
                    //X509Certificate2 serverCertificate =  certificateIdentifier.Find();
                    X509Certificate2 serverCertificate = certificateIdentifier.Find().Result;

                    if (serverCertificate == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "Could not find server certificate: {0}", certificateIdentifier.SubjectName);
                    }

                    endpointDescription.ServerCertificate = serverCertificate.GetRawCertData();
                }
            }

            return(endpointDescription);
        }
コード例 #37
0
        /// <summary>
        /// Initialize the OPC UA Application's security configuration
        /// </summary>
        /// <returns></returns>
        private async Task InitApplicationSecurityAsync()
        {
            // update certificates validator
            _opcApplicationConfig.CertificateValidator.CertificateValidation +=
                new CertificateValidationEventHandler(VerifyCertificate);
            await _opcApplicationConfig.CertificateValidator
            .Update(_opcApplicationConfig).ConfigureAwait(false);

            // lookup for an existing certificate in the configured store
            var ownCertificate = await _opcApplicationConfig.SecurityConfiguration
                                 .ApplicationCertificate.Find(true).ConfigureAwait(false);

            if (ownCertificate == null)
            {
                //
                // Work around windows issue and lookup application certificate also on
                // directory if configured.  This is needed for container persistence.
                //
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
                    _configuration.AppCertStoreType == CertificateStoreType.Directory)
                {
                    // Use x509 store instead of directory for private cert.
                    var ownCertificateIdentifier = new CertificateIdentifier {
                        StoreType   = _configuration.AppCertStoreType,
                        StorePath   = _configuration.OwnCertPath,
                        SubjectName = _opcApplicationConfig.SecurityConfiguration
                                      .ApplicationCertificate.SubjectName
                    };
                    ownCertificate = await ownCertificateIdentifier.Find(true)
                                     .ConfigureAwait(false);

                    if ((ownCertificate != null) && !ownCertificate.Verify())
                    {
                        try {
                            _logger.Warning("Found malformed own certificate {Thumbprint}, " +
                                            "{Subject} in the store - deleting it...",
                                            ownCertificate.Thumbprint, ownCertificate.Subject);
                            ownCertificateIdentifier.RemoveFromStore(ownCertificate);
                        }
                        catch (Exception ex) {
                            _logger.Information(ex,
                                                "Failed to remove malformed own certificate");
                        }
                        ownCertificate = null;
                    }
                }
            }

            if (ownCertificate == null)
            {
                _logger.Information("Application own certificate not found. " +
                                    "Creating a new self-signed certificate with default settings...");
                ownCertificate = CertificateFactory.CreateCertificate(
                    _opcApplicationConfig.SecurityConfiguration.ApplicationCertificate.StoreType,
                    _opcApplicationConfig.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null,
                    _opcApplicationConfig.ApplicationUri, _opcApplicationConfig.ApplicationName,
                    _opcApplicationConfig.SecurityConfiguration.ApplicationCertificate.SubjectName,
                    null, CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime, CertificateFactory.defaultHashSize,
                    false, null, null);

                _opcApplicationConfig.SecurityConfiguration.ApplicationCertificate.Certificate =
                    ownCertificate;
                _logger.Information(
                    "New application certificate with {Thumbprint}, {Subject} created",
                    ownCertificate.Thumbprint, ownCertificate.SubjectName.Name);
            }
            else
            {
                _logger.Information("Application certificate with {Thumbprint}, {Subject} " +
                                    "found in the certificate store",
                                    ownCertificate.Thumbprint, ownCertificate.SubjectName.Name);
            }
            // Set the Certificate as the newly created certificate
            await SetOwnCertificateAsync(ownCertificate);

            if (_opcApplicationConfig.SecurityConfiguration.AutoAcceptUntrustedCertificates)
            {
                _logger.Warning(
                    "WARNING: Automatically accepting certificates. This is a security risk.");
            }
        }