Example #1
0
        /// <summary>
        /// Creates the objects used to validate the user identity tokens supported by the server.
        /// </summary>
        private void CreateUserIdentityValidators(ApplicationConfiguration configuration)
        {
            foreach (UserTokenPolicy policy in configuration.ServerConfiguration.UserTokenPolicies)
            {
                // create a validator for a certificate token policy
                if (policy.TokenType == UserTokenType.Certificate)
                {
                    // check if user certificate trust lists are specified in configuration
                    SecurityConfiguration securityConfiguration = configuration.SecurityConfiguration;

                    if (securityConfiguration.TrustedUserCertificates != null &&
                        securityConfiguration.UserIssuerCertificates != null)
                    {
                        CertificateValidator validator = new CertificateValidator();
                        validator.Update(securityConfiguration).Wait();
                        validator.Update(
                            securityConfiguration.UserIssuerCertificates,
                            securityConfiguration.TrustedUserCertificates,
                            securityConfiguration.RejectedCertificateStore);

                        // set custom validator for user certificates
                        certificateValidator = validator.GetChannelValidator();
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Creates the objects used to validate the user identity tokens supported by the server.
        /// </summary>
        private void CreateUserIdentityValidators(ApplicationConfiguration configuration)
        {
            for (int ii = 0; ii < configuration.ServerConfiguration.UserTokenPolicies.Count; ii++)
            {
                UserTokenPolicy policy = configuration.ServerConfiguration.UserTokenPolicies[ii];

                // create a validator for a certificate token policy.
                if (policy.TokenType == UserTokenType.Certificate)
                {
                    // check if user certificate trust lists are specified in configuration.
                    if (configuration.SecurityConfiguration.TrustedUserCertificates != null &&
                        configuration.SecurityConfiguration.UserIssuerCertificates != null)
                    {
                        CertificateValidator certificateValidator = new CertificateValidator();
                        certificateValidator.Update(configuration.SecurityConfiguration).Wait();
                        certificateValidator.Update(configuration.SecurityConfiguration.UserIssuerCertificates,
                                                    configuration.SecurityConfiguration.TrustedUserCertificates,
                                                    configuration.SecurityConfiguration.RejectedCertificateStore);

                        // set custom validator for user certificates.
                        m_certificateValidator = certificateValidator.GetChannelValidator();
                    }
                }
            }
        }
        public static void VerifyApplicationCertIntegrity(
            X509Certificate2 newCert,
            byte[] privateKey,
            string privateKeyPassword,
            string privateKeyFormat,
            X509Certificate2Collection issuerCertificates)
        {
            Assert.NotNull(newCert);
            if (privateKey != null)
            {
                X509Certificate2 newPrivateKeyCert = null;
                if (privateKeyFormat == "PFX")
                {
                    newPrivateKeyCert = CertificateFactory.CreateCertificateFromPKCS12(privateKey, privateKeyPassword);
                }
                else if (privateKeyFormat == "PEM")
                {
                    newPrivateKeyCert = CertificateFactory.CreateCertificateWithPEMPrivateKey(newCert, privateKey, privateKeyPassword);
                }
                else
                {
                    Assert.True(false, "Invalid private key format");
                }
                Assert.NotNull(newPrivateKeyCert);
                // verify the public cert matches the private key
                Assert.True(CertificateFactory.VerifyRSAKeyPair(newCert, newPrivateKeyCert, true));
                Assert.True(CertificateFactory.VerifyRSAKeyPair(newPrivateKeyCert, newPrivateKeyCert, true));
            }

            CertificateIdentifierCollection issuerCertIdCollection = new CertificateIdentifierCollection();

            foreach (var issuerCert in issuerCertificates)
            {
                issuerCertIdCollection.Add(new CertificateIdentifier(issuerCert));
            }

            // verify cert with issuer chain
            CertificateValidator certValidator = new CertificateValidator();
            CertificateTrustList issuerStore   = new CertificateTrustList();
            CertificateTrustList trustedStore  = new CertificateTrustList();

            trustedStore.TrustedCertificates = issuerCertIdCollection;
            certValidator.Update(trustedStore, issuerStore, null);
            Assert.Throws <Opc.Ua.ServiceResultException>(() =>
            {
                certValidator.Validate(newCert);
            });
            issuerStore.TrustedCertificates = issuerCertIdCollection;
            certValidator.Update(issuerStore, trustedStore, null);
            certValidator.Validate(newCert);
        }
Example #4
0
        public OpcUaClient()
        {
            #region 初始化
            var application = new ApplicationInstance();
            application.ApplicationType   = ApplicationType.Client;
            application.ConfigSectionName = Path.GetFileName(Assembly.GetExecutingAssembly().Location);

            var certificateValidator = new CertificateValidator();
            certificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
            SecurityConfiguration securityConfiguration = new SecurityConfiguration
            {
                AutoAcceptUntrustedCertificates = true,
                //RejectSHA1SignedCertificates = false,
                //MinimumCertificateKeySize = 1024,
            };
            certificateValidator.Update(securityConfiguration);

            application.ApplicationConfiguration = new ApplicationConfiguration
            {
                ApplicationName      = application.ConfigSectionName,
                ApplicationType      = ApplicationType.Client,
                CertificateValidator = certificateValidator,
                ServerConfiguration  = new ServerConfiguration
                {
                    MaxSubscriptionCount     = 100000,
                    MaxMessageQueueSize      = 1000000,
                    MaxNotificationQueueSize = 1000000,
                    MaxPublishRequestCount   = 10000000,
                },

                SecurityConfiguration = new SecurityConfiguration
                {
                    AutoAcceptUntrustedCertificates = true,
                    //RejectSHA1SignedCertificates = false,
                    //MinimumCertificateKeySize = 1024,
                },

                TransportQuotas = new TransportQuotas
                {
                    OperationTimeout      = 6000000,
                    MaxStringLength       = int.MaxValue,
                    MaxByteStringLength   = int.MaxValue,
                    MaxArrayLength        = 65535,
                    MaxMessageSize        = 419430400,
                    MaxBufferSize         = 65535,
                    ChannelLifetime       = -1,
                    SecurityTokenLifetime = -1
                },
                ClientConfiguration = new ClientConfiguration
                {
                    DefaultSessionTimeout   = -1,
                    MinSubscriptionLifetime = -1,
                },
                DisableHiResClock = true
            };

            m_configuration = application.ApplicationConfiguration;

            #endregion
        }
Example #5
0
        public static void VerifyApplicationCertIntegrity(byte[] certificate, byte[] privateKey, string privateKeyPassword, string privateKeyFormat, byte[][] issuerCertificates)
        {
            X509Certificate2 newCert = new X509Certificate2(certificate);

            Assert.IsNotNull(newCert);
            X509Certificate2 newPrivateKeyCert = null;

            if (privateKeyFormat == "PFX")
            {
                newPrivateKeyCert = X509Utils.CreateCertificateFromPKCS12(privateKey, privateKeyPassword);
            }
            else if (privateKeyFormat == "PEM")
            {
                newPrivateKeyCert = CertificateFactory.CreateCertificateWithPEMPrivateKey(newCert, privateKey, privateKeyPassword);
            }
            else
            {
                Assert.Fail("Invalid private key format");
            }
            Assert.IsNotNull(newPrivateKeyCert);
            // verify the public cert matches the private key
            Assert.IsTrue(X509Utils.VerifyRSAKeyPair(newCert, newPrivateKeyCert, true));
            Assert.IsTrue(X509Utils.VerifyRSAKeyPair(newPrivateKeyCert, newPrivateKeyCert, true));
            CertificateIdentifierCollection issuerCertIdCollection = new CertificateIdentifierCollection();

            foreach (var issuer in issuerCertificates)
            {
                var issuerCert = new X509Certificate2(issuer);
                Assert.IsNotNull(issuerCert);
                issuerCertIdCollection.Add(new CertificateIdentifier(issuerCert));
            }

            // verify cert with issuer chain
            CertificateValidator certValidator = new CertificateValidator();
            CertificateTrustList issuerStore   = new CertificateTrustList();
            CertificateTrustList trustedStore  = new CertificateTrustList();

            trustedStore.TrustedCertificates = issuerCertIdCollection;
            certValidator.Update(trustedStore, issuerStore, null);
            Assert.That(() => {
                certValidator.Validate(newCert);
            }, Throws.Exception);
            issuerStore.TrustedCertificates = issuerCertIdCollection;
            certValidator.Update(issuerStore, trustedStore, null);
            certValidator.Validate(newCert);
        }
Example #6
0
        public static void VerifyApplicationCertIntegrity(
            X509Certificate2 newCert,
            Key privateKey,
            X509Certificate2Collection issuerCertificates)
        {
            Assert.NotNull(newCert);
            Assert.True(privateKey.HasPrivateKey());
            if (privateKey != null)
            {
                using (var newPrivateKeyCert = new X509Certificate2(newCert.RawData)
                {
                    PrivateKey = privateKey.ToRSA()
                }) {
                    Assert.True(newPrivateKeyCert.HasPrivateKey);
                    Assert.NotNull(newPrivateKeyCert);
                    Assert.True(newPrivateKeyCert.HasPrivateKey);
                    // verify the public cert matches the private key
                    Assert.True(CertificateFactory.VerifyRSAKeyPair(newCert, newPrivateKeyCert, true));
                    Assert.True(CertificateFactory.VerifyRSAKeyPair(newPrivateKeyCert, newPrivateKeyCert, true));
                }
            }
            var issuerCertIdCollection = new CertificateIdentifierCollection();

            foreach (var issuerCert in issuerCertificates)
            {
                issuerCertIdCollection.Add(new CertificateIdentifier(issuerCert));
            }

            // verify cert with issuer chain
            var certValidator = new CertificateValidator();
            var issuerStore   = new CertificateTrustList();
            var trustedStore  = new CertificateTrustList {
                TrustedCertificates = issuerCertIdCollection
            };

            certValidator.Update(trustedStore, issuerStore, null);
            Assert.Throws <ServiceResultException>(() => certValidator.Validate(newCert));
            issuerStore.TrustedCertificates = issuerCertIdCollection;
            certValidator.Update(issuerStore, trustedStore, null);
            certValidator.Validate(newCert);
        }
Example #7
0
        private void CreateUserIdentityValidators(ApplicationConfiguration configuration)
        {
            for (int ii = 0; ii < configuration.ServerConfiguration.UserTokenPolicies.Count; ii++)
            {
                UserTokenPolicy policy = configuration.ServerConfiguration.UserTokenPolicies[ii];

                if (policy.TokenType == UserTokenType.Certificate)
                {
                    if (configuration.SecurityConfiguration.TrustedUserCertificates != null &&
                        configuration.SecurityConfiguration.UserIssuerCertificates != null)
                    {
                        CertificateValidator certificateValidator = new CertificateValidator();
                        certificateValidator.Update(configuration.SecurityConfiguration).Wait();
                        certificateValidator.Update(configuration.SecurityConfiguration.UserIssuerCertificates,
                                                    configuration.SecurityConfiguration.TrustedUserCertificates,
                                                    configuration.SecurityConfiguration.RejectedCertificateStore);

                        m_userCertificateValidator = certificateValidator.GetChannelValidator();
                    }
                }
            }
        }
Example #8
0
        private CertificateValidator InitValidatorWithStores()
        {
            CertificateValidator certValidator   = new CertificateValidator();
            CertificateTrustList issuerTrustList = new CertificateTrustList();

            issuerTrustList.StoreType = "Directory";
            issuerTrustList.StorePath = _issuerStore.Directory.FullName;
            CertificateTrustList trustedTrustList = new CertificateTrustList();

            trustedTrustList.StoreType = "Directory";
            trustedTrustList.StorePath = _trustedStore.Directory.FullName;
            certValidator.Update(issuerTrustList, trustedTrustList, null);
            return(certValidator);
        }
Example #9
0
        private CertificateValidator InitValidatorWithStores()
        {
            var certValidator   = new CertificateValidator();
            var issuerTrustList = new CertificateTrustList {
                StoreType = "Directory",
                StorePath = m_issuerStore.Directory.FullName
            };
            var trustedTrustList = new CertificateTrustList {
                StoreType = "Directory",
                StorePath = m_trustedStore.Directory.FullName
            };

            certValidator.Update(issuerTrustList, trustedTrustList, null);
            return(certValidator);
        }
Example #10
0
 /// <summary>
 /// Creates the objects used to validate the user identity tokens supported by the server.
 /// </summary>
 private void CreateUserIdentityValidators(ApplicationConfiguration configuration)
 {
     foreach (UserTokenPolicy policy in configuration.ServerConfiguration.UserTokenPolicies)
     {
         // create a validator for a certificate token policy.
         if (policy.TokenType != UserTokenType.Certificate)
         {
             continue;
         }
         // check if user certificate trust lists are specified in configuration.
         if (configuration.SecurityConfiguration.TrustedUserCertificates == null ||
             configuration.SecurityConfiguration.UserIssuerCertificates == null)
         {
             continue;
         }
         CertificateValidator certificateValidator = new CertificateValidator();
         certificateValidator.Update(configuration.SecurityConfiguration).Wait();
         certificateValidator.Update(configuration.SecurityConfiguration.UserIssuerCertificates,
                                     configuration.SecurityConfiguration.TrustedUserCertificates,
                                     configuration.SecurityConfiguration.RejectedCertificateStore);
         // set custom validator for user certificates.
         _certificateValidator = certificateValidator.GetChannelValidator();
     }
 }
Example #11
0
        internal static async Task <CertificateValidator> CreateValidatorAsync(TrustListModel trustList)
        {
            var storePath = "%LocalApplicationData%/OPCVaultTest/pki/";

            DeleteDirectory(storePath);

            // verify cert with issuer chain
            var certValidator   = new CertificateValidator();
            var issuerTrustList = await CreateTrustListAsync(
                storePath + "issuer",
                trustList.IssuerCertificates.ToStackModel(),
                trustList.IssuerCrls.ToStackModel()
                );

            var trustedTrustList = await CreateTrustListAsync(
                storePath + "trusted",
                trustList.TrustedCertificates.ToStackModel(),
                trustList.TrustedCrls.ToStackModel()
                );

            certValidator.Update(issuerTrustList, trustedTrustList, null);
            return(certValidator);
        }
        /// <summary>
        /// Creates the validator using the issuer and trusted store.
        /// </summary>
        public CertificateValidator Update()
        {
            var certValidator   = new CertificateValidator();
            var issuerTrustList = new CertificateTrustList {
                StoreType = "Directory",
                StorePath = m_issuerStore.Directory.FullName
            };
            var trustedTrustList = new CertificateTrustList {
                StoreType = "Directory",
                StorePath = m_trustedStore.Directory.FullName
            };
            CertificateStoreIdentifier rejectedList = null;

            if (m_rejectedStore != null)
            {
                rejectedList = new CertificateStoreIdentifier {
                    StoreType = "Directory",
                    StorePath = m_rejectedStore.Directory.FullName
                };
            }
            certValidator.Update(issuerTrustList, trustedTrustList, rejectedList);
            m_certificateValidator = certValidator;
            return(certValidator);
        }
Example #13
0
        public static void VerifySignedApplicationCert(ApplicationTestData testApp,
                                                       X509Certificate2 signedCert, X509Certificate2Collection issuerCerts)
        {
            var issuerCert = issuerCerts[0];

            var signedCertO = signedCert.ToCertificate();

            Assert.NotNull(signedCertO);
            Assert.False(signedCert.HasPrivateKey);
            Assert.True(Utils.CompareDistinguishedName(testApp.Subject, signedCert.Subject));
            Assert.False(Utils.CompareDistinguishedName(signedCert.Issuer, signedCert.Subject));
            Assert.True(Utils.CompareDistinguishedName(signedCert.Issuer, issuerCert.Subject));

            // test basic constraints
            var constraints = signedCertO.GetBasicConstraintsExtension();

            Assert.NotNull(constraints);
            Assert.True(constraints.Critical);
            Assert.False(constraints.CertificateAuthority);
            Assert.False(constraints.HasPathLengthConstraint);

            // key usage
            var keyUsage = signedCertO.GetKeyUsageExtension();

            Assert.NotNull(keyUsage);
            Assert.True(keyUsage.Critical);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.CrlSign) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.DataEncipherment) == X509KeyUsageFlags.DataEncipherment);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.DecipherOnly) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.DigitalSignature) == X509KeyUsageFlags.DigitalSignature);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.EncipherOnly) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.KeyAgreement) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.KeyCertSign) == 0);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.KeyEncipherment) == X509KeyUsageFlags.KeyEncipherment);
            Assert.True((keyUsage.KeyUsages & X509KeyUsageFlags.NonRepudiation) == X509KeyUsageFlags.NonRepudiation);

            // enhanced key usage
            var enhancedKeyUsage = signedCertO.GetEnhancedKeyUsageExtension();

            Assert.NotNull(enhancedKeyUsage);
            Assert.True(enhancedKeyUsage.Critical);

            // test for authority key
            var authority = signedCertO.GetAuthorityKeyIdentifierExtension();

            Assert.NotNull(authority);
            Assert.NotNull(authority.SerialNumber);
            Assert.NotNull(authority.KeyId);
            Assert.NotNull(authority.AuthorityNames);

            // verify authority key in signed cert
            var subjectKeyId = signedCertO.GetSubjectKeyIdentifierExtension();

            Assert.Equal(subjectKeyId.SubjectKeyIdentifier, authority.KeyId);
            Assert.Equal(issuerCert.SerialNumber, authority.SerialNumber.ToString());

            var subjectAlternateName = signedCertO.GetSubjectAltNameExtension();

            Assert.NotNull(subjectAlternateName);
            Assert.False(subjectAlternateName.Critical);
            var domainNames = Utils.GetDomainsFromCertficate(signedCert);

            foreach (var domainName in testApp.DomainNames)
            {
                Assert.Contains(domainName, domainNames, StringComparer.OrdinalIgnoreCase);
            }
            Assert.True(subjectAlternateName.Uris.Count == 1);
            var applicationUri = Utils.GetApplicationUriFromCertificate(signedCert);

            Assert.True(testApp.ApplicationRecord.ApplicationUri == applicationUri);

            var issuerCertIdCollection = new CertificateIdentifierCollection();

            foreach (var cert in issuerCerts)
            {
                issuerCertIdCollection.Add(new CertificateIdentifier(cert));
            }

            // verify cert with issuer chain
            var certValidator = new CertificateValidator();
            var issuerStore   = new CertificateTrustList();
            var trustedStore  = new CertificateTrustList {
                TrustedCertificates = issuerCertIdCollection
            };

            certValidator.Update(trustedStore, issuerStore, null);
            Assert.Throws <ServiceResultException>(() => certValidator.Validate(signedCert));
            issuerStore.TrustedCertificates = issuerCertIdCollection;
            certValidator.Update(issuerStore, trustedStore, null);
            certValidator.Validate(signedCert);
        }
Example #14
0
        /// <summary>
        /// 默认的构造函数,实例化一个新的OPC UA类
        /// </summary>
        public OpcUaClient( )
        {
            dic_subscriptions = new Dictionary <string, Subscription>( );

            var certificateValidator = new CertificateValidator( );

            certificateValidator.CertificateValidation += (sender, eventArgs) =>
            {
                if (ServiceResult.IsGood(eventArgs.Error))
                {
                    eventArgs.Accept = true;
                }
                else if (eventArgs.Error.StatusCode.Code == StatusCodes.BadCertificateUntrusted)
                {
                    eventArgs.Accept = true;
                }
                else
                {
                    throw new Exception(string.Format("Failed to validate certificate with error code {0}: {1}", eventArgs.Error.Code, eventArgs.Error.AdditionalInfo));
                }
            };

            SecurityConfiguration securityConfigurationcv = new SecurityConfiguration
            {
                AutoAcceptUntrustedCertificates = true,
                RejectSHA1SignedCertificates    = false,
                MinimumCertificateKeySize       = 1024,
            };

            certificateValidator.Update(securityConfigurationcv);

            // Build the application configuration
            application = new ApplicationInstance
            {
                ApplicationType          = ApplicationType.Client,
                ConfigSectionName        = OpcUaName,
                ApplicationConfiguration = new ApplicationConfiguration
                {
                    ApplicationName      = OpcUaName,
                    ApplicationType      = ApplicationType.Client,
                    CertificateValidator = certificateValidator,
                    ServerConfiguration  = new ServerConfiguration
                    {
                        MaxSubscriptionCount     = 100000,
                        MaxMessageQueueSize      = 1000000,
                        MaxNotificationQueueSize = 1000000,
                        MaxPublishRequestCount   = 10000000,
                    },

                    SecurityConfiguration = new SecurityConfiguration
                    {
                        AutoAcceptUntrustedCertificates = true,
                        RejectSHA1SignedCertificates    = false,
                        MinimumCertificateKeySize       = 1024,
                    },

                    TransportQuotas = new TransportQuotas
                    {
                        OperationTimeout      = 6000000,
                        MaxStringLength       = int.MaxValue,
                        MaxByteStringLength   = int.MaxValue,
                        MaxArrayLength        = 65535,
                        MaxMessageSize        = 419430400,
                        MaxBufferSize         = 65535,
                        ChannelLifetime       = -1,
                        SecurityTokenLifetime = -1
                    },
                    ClientConfiguration = new ClientConfiguration
                    {
                        DefaultSessionTimeout   = -1,
                        MinSubscriptionLifetime = -1,
                    },
                    DisableHiResClock = true
                }
            };

            // Assign a application certificate (when specified)
            // if (ApplicationCertificate != null)
            //    application.ApplicationConfiguration.SecurityConfiguration.ApplicationCertificate = new CertificateIdentifier(_options.ApplicationCertificate);


            m_configuration = application.ApplicationConfiguration;
        }
Example #15
0
        private ServiceResult UpdateCertificate(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            NodeId certificateGroupId,
            NodeId certificateTypeId,
            byte[] certificate,
            byte[][] issuerCertificates,
            string privateKeyFormat,
            byte[] privateKey,
            ref bool applyChangesRequired)
        {
            HasApplicationSecureAdminAccess(context);

            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            privateKeyFormat = privateKeyFormat?.ToUpper();
            if (!(String.IsNullOrEmpty(privateKeyFormat) || privateKeyFormat == "PEM" || privateKeyFormat == "PFX"))
            {
                throw new ServiceResultException(StatusCodes.BadNotSupported, "The private key format is not supported.");
            }

            ServerCertificateGroup certificateGroup = VerifyGroupAndTypeId(certificateGroupId, certificateTypeId);

            certificateGroup.UpdateCertificate = null;

            X509Certificate2Collection newIssuerCollection = new X509Certificate2Collection();
            X509Certificate2           newCert;

            try
            {
                // build issuer chain
                if (issuerCertificates != null)
                {
                    foreach (byte[] issuerRawCert in issuerCertificates)
                    {
                        var newIssuerCert = new X509Certificate2(issuerRawCert);
                        newIssuerCollection.Add(newIssuerCert);
                    }
                }

                newCert = new X509Certificate2(certificate);
            }
            catch
            {
                throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Certificate data is invalid.");
            }

            // validate new subject matches the previous subject
            if (!X509Utils.CompareDistinguishedName(certificateGroup.ApplicationCertificate.SubjectName, newCert.SubjectName.Name))
            {
                throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Subject Name of new certificate doesn't match the application.");
            }

            // self signed
            bool selfSigned = X509Utils.CompareDistinguishedName(newCert.Subject, newCert.Issuer);

            if (selfSigned && newIssuerCollection.Count != 0)
            {
                throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Issuer list not empty for self signed certificate.");
            }

            if (!selfSigned)
            {
                try
                {
                    // verify cert with issuer chain
                    CertificateValidator            certValidator    = new CertificateValidator();
                    CertificateTrustList            issuerStore      = new CertificateTrustList();
                    CertificateIdentifierCollection issuerCollection = new CertificateIdentifierCollection();
                    foreach (var issuerCert in newIssuerCollection)
                    {
                        issuerCollection.Add(new CertificateIdentifier(issuerCert));
                    }
                    issuerStore.TrustedCertificates = issuerCollection;
                    certValidator.Update(issuerStore, issuerStore, null);
                    certValidator.Validate(newCert);
                }
                catch
                {
                    throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Failed to verify integrity of the new certificate and the issuer list.");
                }
            }

            var updateCertificate = new UpdateCertificateData();

            try
            {
                var passwordProvider = m_configuration.SecurityConfiguration.CertificatePasswordProvider;
                switch (privateKeyFormat)
                {
                case null:
                case "":
                {
                    X509Certificate2 certWithPrivateKey = certificateGroup.ApplicationCertificate.LoadPrivateKeyEx(passwordProvider).Result;
                    updateCertificate.CertificateWithPrivateKey = CertificateFactory.CreateCertificateWithPrivateKey(newCert, certWithPrivateKey);
                    break;
                }

                case "PFX":
                {
                    X509Certificate2 certWithPrivateKey = X509Utils.CreateCertificateFromPKCS12(privateKey, passwordProvider?.GetPassword(certificateGroup.ApplicationCertificate));
                    updateCertificate.CertificateWithPrivateKey = CertificateFactory.CreateCertificateWithPrivateKey(newCert, certWithPrivateKey);
                    break;
                }

                case "PEM":
                {
                    updateCertificate.CertificateWithPrivateKey = CertificateFactory.CreateCertificateWithPEMPrivateKey(newCert, privateKey, passwordProvider?.GetPassword(certificateGroup.ApplicationCertificate));
                    break;
                }
                }
                updateCertificate.IssuerCollection = newIssuerCollection;
                updateCertificate.SessionId        = context.SessionId;
            }
            catch
            {
                throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Failed to verify integrity of the new certificate and the private key.");
            }

            certificateGroup.UpdateCertificate = updateCertificate;
            applyChangesRequired = true;

            if (updateCertificate != null)
            {
                try
                {
                    using (ICertificateStore appStore = certificateGroup.ApplicationCertificate.OpenStore())
                    {
                        Utils.LogCertificate(Utils.TraceMasks.Security, "Delete application certificate: ", certificateGroup.ApplicationCertificate.Certificate);
                        appStore.Delete(certificateGroup.ApplicationCertificate.Thumbprint).Wait();
                        Utils.LogCertificate(Utils.TraceMasks.Security, "Add new application certificate: ", updateCertificate.CertificateWithPrivateKey);
                        var passwordProvider = m_configuration.SecurityConfiguration.CertificatePasswordProvider;
                        appStore.Add(updateCertificate.CertificateWithPrivateKey, passwordProvider?.GetPassword(certificateGroup.ApplicationCertificate)).Wait();
                        // keep only track of cert without private key
                        var certOnly = new X509Certificate2(updateCertificate.CertificateWithPrivateKey.RawData);
                        updateCertificate.CertificateWithPrivateKey.Dispose();
                        updateCertificate.CertificateWithPrivateKey = certOnly;
                    }
                    using (ICertificateStore issuerStore = CertificateStoreIdentifier.OpenStore(certificateGroup.IssuerStorePath))
                    {
                        foreach (var issuer in updateCertificate.IssuerCollection)
                        {
                            try
                            {
                                Utils.LogCertificate(Utils.TraceMasks.Security, "Add new issuer certificate: ", issuer);
                                issuerStore.Add(issuer).Wait();
                            }
                            catch (ArgumentException)
                            {
                                // ignore error if issuer cert already exists
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Utils.LogError(Utils.TraceMasks.Security, ServiceResult.BuildExceptionTrace(ex));
                    throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Failed to update certificate.", ex);
                }
            }

            return(ServiceResult.Good);
        }
Example #16
0
        /// <summary>
        /// 默认的构造函数,实例化一个新的OPC UA类
        /// </summary>
        public OpcUaClient()
        {
            var certificateValidator = new CertificateValidator();

            certificateValidator.CertificateValidation += (sender, eventArgs) =>
            {
                if (ServiceResult.IsGood(eventArgs.Error))
                {
                    eventArgs.Accept = true;
                }
                else if (eventArgs.Error.StatusCode.Code == StatusCodes.BadCertificateUntrusted)
                {
                    eventArgs.Accept = true;
                }
                else
                {
                    LoggerService.Service.Warn("OpcClient", string.Format("Failed to validate certificate with error code {0}: {1}", eventArgs.Error.Code, eventArgs.Error.AdditionalInfo));
                }
            };

            SecurityConfiguration securityConfigurationcv = new SecurityConfiguration
            {
                AutoAcceptUntrustedCertificates = true,
                RejectSHA1SignedCertificates    = false,
                MinimumCertificateKeySize       = 1024,
            };

            certificateValidator.Update(securityConfigurationcv);

            // Build the application configuration
            var configuration = new ApplicationConfiguration
            {
                ApplicationName      = OpcUaName,
                ApplicationType      = ApplicationType.Client,
                CertificateValidator = certificateValidator,
                ApplicationUri       = "urn:SpiderOpcClient", //Kepp this syntax
                ProductUri           = "SpiderOpcClient",

                ServerConfiguration = new ServerConfiguration
                {
                    MaxSubscriptionCount     = 100000,
                    MaxMessageQueueSize      = 1000000,
                    MaxNotificationQueueSize = 1000000,
                    MaxPublishRequestCount   = 10000000,
                },

                SecurityConfiguration = new SecurityConfiguration
                {
                    AutoAcceptUntrustedCertificates = true,
                    RejectSHA1SignedCertificates    = false,
                    MinimumCertificateKeySize       = 1024,
                    SuppressNonceValidationErrors   = true,

                    ApplicationCertificate = new CertificateIdentifier
                    {
                        StoreType   = CertificateStoreType.X509Store,
                        StorePath   = "CurrentUser\\My",
                        SubjectName = OpcUaName,
                    },
                    TrustedIssuerCertificates = new CertificateTrustList
                    {
                        StoreType = CertificateStoreType.X509Store,
                        StorePath = "CurrentUser\\Root",
                    },
                    TrustedPeerCertificates = new CertificateTrustList
                    {
                        StoreType = CertificateStoreType.X509Store,
                        StorePath = "CurrentUser\\Root",
                    }
                },

                TransportQuotas = new TransportQuotas
                {
                    OperationTimeout      = 6000000,
                    MaxStringLength       = int.MaxValue,
                    MaxByteStringLength   = int.MaxValue,
                    MaxArrayLength        = 65535,
                    MaxMessageSize        = 419430400,
                    MaxBufferSize         = 65535,
                    ChannelLifetime       = -1,
                    SecurityTokenLifetime = -1
                },
                ClientConfiguration = new ClientConfiguration
                {
                    DefaultSessionTimeout   = -1,
                    MinSubscriptionLifetime = -1,
                },
                DisableHiResClock = true
            };

            configuration.Validate(ApplicationType.Client);
            m_configuration = configuration;
        }
Example #17
0
        private ServiceResult UpdateCertificate(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            NodeId certificateGroupId,
            NodeId certificateTypeId,
            byte[] certificate,
            byte[][] issuerCertificates,
            string privateKeyFormat,
            byte[] privateKey,
            ref bool applyChangesRequired)
        {
            HasApplicationSecureAdminAccess(context);

            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            privateKeyFormat = privateKeyFormat?.ToUpper();
            if (!(String.IsNullOrEmpty(privateKeyFormat) || privateKeyFormat == "PEM" || privateKeyFormat == "PFX"))
            {
                throw new ServiceResultException(StatusCodes.BadNotSupported, "The private key format is not supported.");
            }

            ServerCertificateGroup certificateGroup = VerifyGroupAndTypeId(certificateGroupId, certificateTypeId);

            certificateGroup.UpdateCertificate = null;

            X509Certificate2Collection newIssuerCollection = new X509Certificate2Collection();
            X509Certificate2           newCert;

            try
            {
                // build issuer chain
                if (issuerCertificates != null)
                {
                    foreach (byte[] issuerRawCert in issuerCertificates)
                    {
                        var newIssuerCert = new X509Certificate2(issuerRawCert);
                        newIssuerCollection.Add(newIssuerCert);
                    }
                }

                newCert = new X509Certificate2(certificate);
            }
            catch
            {
                throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Certificate data is invalid.");
            }

            // load existing application cert and private key
            if (!Utils.CompareDistinguishedName(certificateGroup.ApplicationCertificate.SubjectName, newCert.SubjectName.Name))
            {
                throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Subject Name of new certificate doesn't match the application.");
            }

            // self signed
            bool selfSigned = Utils.CompareDistinguishedName(newCert.Subject, newCert.Issuer);

            if (selfSigned && newIssuerCollection.Count != 0)
            {
                throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Issuer list not empty for self signed certificate.");
            }

            if (!selfSigned)
            {
                try
                {
                    // verify cert with issuer chain
                    CertificateValidator            certValidator    = new CertificateValidator();
                    CertificateTrustList            issuerStore      = new CertificateTrustList();
                    CertificateIdentifierCollection issuerCollection = new CertificateIdentifierCollection();
                    foreach (var issuerCert in newIssuerCollection)
                    {
                        issuerCollection.Add(new CertificateIdentifier(issuerCert));
                    }
                    issuerStore.TrustedCertificates = issuerCollection;
                    certValidator.Update(issuerStore, issuerStore, null);
                    certValidator.Validate(newCert);
                }
                catch
                {
                    throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Failed to verify integrity of the new certificate and the issuer list.");
                }
            }

            var updateCertificate = new UpdateCertificateData();

            try
            {
                string password = String.Empty;
                switch (privateKeyFormat)
                {
                case null:
                case "":
                {
                    X509Certificate2 certWithPrivateKey = certificateGroup.ApplicationCertificate.LoadPrivateKey(password).Result;
                    updateCertificate.CertificateWithPrivateKey = CertificateFactory.CreateCertificateWithPrivateKey(newCert, certWithPrivateKey);
                    break;
                }

                case "PFX":
                {
                    X509Certificate2 certWithPrivateKey = CertificateFactory.CreateCertificateFromPKCS12(privateKey, password);
                    updateCertificate.CertificateWithPrivateKey = CertificateFactory.CreateCertificateWithPrivateKey(newCert, certWithPrivateKey);
                    break;
                }

                case "PEM":
                {
                    updateCertificate.CertificateWithPrivateKey = CertificateFactory.CreateCertificateWithPEMPrivateKey(newCert, privateKey, password);
                    break;
                }
                }
                updateCertificate.IssuerCollection = newIssuerCollection;
                updateCertificate.SessionId        = context.SessionId;
            }
            catch
            {
                throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Failed to verify integrity of the new certificate and the private key.");
            }

            certificateGroup.UpdateCertificate = updateCertificate;
            applyChangesRequired = true;

            return(ServiceResult.Good);
        }
Example #18
0
        /// <summary>
        /// Validates a certificate and adds it to the trust list.
        /// </summary>
        private void ValidateAndImport(CertificateStoreIdentifier store, X509Certificate2 certificate)
        {
            if (store == null || certificate == null)
            {
                return;
            }

            // validate the certificate using the trust lists for the certificate tool.                                
            try
            {
                CertificateValidator validator = new CertificateValidator();
                validator.Update(m_configuration);
                validator.Validate(certificate);
            }
            catch (ServiceResultException exception)
            {
                if (!HandleValidationError(certificate, exception))
                {
                    return;
                }
            }

            // confirm import.
            StringBuilder buffer = new StringBuilder();

            buffer.Append("You are adding this certificate to a trust list that may be shared with other applications.");
            buffer.Append("\r\n");
            buffer.Append("\r\n");
            buffer.Append("Would you still like to accept the certificate?\r\n");
            buffer.Append("\r\n");
            buffer.Append("Target Trust List = ");
            buffer.Append(store.ToString());
            buffer.Append("\r\n");
            buffer.Append("Certificate to Add = ");
            buffer.Append(certificate.Subject);

            DialogResult result = new YesNoDlg().ShowDialog(buffer.ToString(), "Import Certificate to Trust List");

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

            // update store.
            ICertificateStore physicalStore = store.OpenStore();

            if (physicalStore.FindByThumbprint(certificate.Thumbprint) == null)
            {
                physicalStore.Add(new X509Certificate2(certificate.RawData));
            }
        }