Exemple #1
0
        /// <summary>
        /// Creates a new policy object.
        /// </summary>
        private static ServerSecurityPolicy CreatePolicy(string profileUri)
        {
            ServerSecurityPolicy policy = new ServerSecurityPolicy();

            policy.SecurityPolicyUri = profileUri;

            if (profileUri != null)
            {
                switch (profileUri)
                {
                case SecurityPolicies.None:
                {
                    policy.SecurityMode  = MessageSecurityMode.None;
                    policy.SecurityLevel = 0;
                    break;
                }

                case SecurityPolicies.Basic128Rsa15:
                {
                    policy.SecurityMode  = MessageSecurityMode.SignAndEncrypt;
                    policy.SecurityLevel = 1;
                    break;
                }

                case SecurityPolicies.Basic256:
                {
                    policy.SecurityMode  = MessageSecurityMode.SignAndEncrypt;
                    policy.SecurityLevel = 2;
                    break;
                }
                }
            }

            return(policy);
        }
Exemple #2
0
        /// <summary>
        /// Creates a new policy object.
        /// Always uses sign and encrypt for all security policies except none
        /// </summary>
        private static ServerSecurityPolicy CreatePolicy(string profileUri)
        {
            ServerSecurityPolicy policy = new ServerSecurityPolicy();

            policy.SecurityPolicyUri = profileUri;

            if (profileUri != null)
            {
                switch (profileUri)
                {
                case SecurityPolicies.None:
                {
                    policy.SecurityMode = MessageSecurityMode.None;
                    break;
                }

                case SecurityPolicies.Basic128Rsa15:
                case SecurityPolicies.Basic256:
                case SecurityPolicies.Basic256Sha256:
                case SecurityPolicies.Aes128_Sha256_RsaOaep:
                case SecurityPolicies.Aes256_Sha256_RsaPss:
                {
                    policy.SecurityMode = MessageSecurityMode.SignAndEncrypt;
                    break;
                }
                }
            }

            return(policy);
        }
        private ServerSecurityPolicy CreateSecurityPolicy(byte MessageMode, byte PolicyNumber)
        {
            try
            {
                ServerSecurityPolicy Policy = new ServerSecurityPolicy();
                switch (MessageMode)
                {
                case 0:
                    Policy.SecurityMode = MessageSecurityMode.None;
                    break;

                case 1:
                    Policy.SecurityMode = MessageSecurityMode.Sign;
                    break;

                case 2:
                    Policy.SecurityMode = MessageSecurityMode.SignAndEncrypt;
                    break;

                default:
                    Policy.SecurityMode = MessageSecurityMode.Invalid;
                    break;
                }
                switch (PolicyNumber)
                {
                case 0:
                    Policy.SecurityPolicyUri = SecurityPolicies.None;
                    break;

                case 1:
                    Policy.SecurityPolicyUri = SecurityPolicies.Basic128Rsa15;
                    break;

                case 2:
                    Policy.SecurityPolicyUri = SecurityPolicies.Basic256;
                    break;

                case 3:
                    Policy.SecurityPolicyUri = SecurityPolicies.Basic256Sha256;
                    break;
                }
            }
            catch (Exception exception)
            {
                ServerUtils.HandleException(this.Text, exception);
            }
            return(Policy);
        }
 private void DeletePolicies(ApplicationConfiguration configuration, ServerSecurityPolicy polici)
 {
     try
     {
         int i = 0;
         foreach (ServerSecurityPolicy policy in configuration.ServerConfiguration.SecurityPolicies)
         {
             if (polici == policy)
             {
                 configuration.ServerConfiguration.SecurityPolicies.Add(policy);
             }
             break;
         }
     }
     catch (Exception exception)
     {
         ServerUtils.HandleException(this.Text, exception);
     }
 }
 private void CheckSecurity()
 {
     try
     {
         ServerSecurityPolicy policy = new ServerSecurityPolicy();
         if (UA_SM_NoneCB.Checked)
         {
             policy = CreateSecurityPolicy(0, 0);
             Addpolicies(m_configuration, policy);
         }
         else
         {
             policy = CreateSecurityPolicy(0, 0);
             DeletePolicies(m_configuration, policy);
         };
         if ((UA_SM_SignCB.Checked) && (Basic128Rsa15_CB.Checked))
         {
             policy = CreateSecurityPolicy(1, 1);
             Addpolicies(m_configuration, policy);
         }
         else
         {
             policy = CreateSecurityPolicy(1, 1);
             DeletePolicies(m_configuration, policy);
         }
         if ((UA_SM_Sign_EnCB.Checked) && (Basic256Sha256_CB.Checked))
         {
             policy = CreateSecurityPolicy(2, 3);
             Addpolicies(m_configuration, policy);
         }
         else
         {
             policy = CreateSecurityPolicy(2, 3);
             DeletePolicies(m_configuration, policy);
         }
     }
     catch (Exception exception)
     {
         ServerUtils.HandleException(this.Text, exception);
     }
 }
        /// <summary>
        /// Add security policy if it doesn't exist yet.
        /// </summary>
        /// <param name="policies">The collection to which the policies are added.</param>
        /// <param name="securityMode">The message security mode.</param>
        /// <param name="policyUri">The security policy Uri.</param>
        private bool InternalAddPolicy(ServerSecurityPolicyCollection policies, MessageSecurityMode securityMode, string policyUri)
        {
            if (securityMode == MessageSecurityMode.Invalid)
            {
                throw new ArgumentException("Invalid security mode selected", nameof(securityMode));
            }
            var newPolicy = new ServerSecurityPolicy()
            {
                SecurityMode      = securityMode,
                SecurityPolicyUri = policyUri
            };

            if (policies.Find(s =>
                              s.SecurityMode == newPolicy.SecurityMode &&
                              string.Equals(s.SecurityPolicyUri, newPolicy.SecurityPolicyUri, StringComparison.Ordinal)
                              ) == null)
            {
                policies.Add(newPolicy);
                return(true);
            }
            return(false);
        }
        /// <summary>
        /// Configures all OPC stack settings
        /// </summary>
        public async Task ConfigureAsync()
        {
            // Instead of using a Config.xml we configure everything programmatically.

            //
            // OPC UA Application configuration
            //
            PublisherOpcApplicationConfiguration = new ApplicationConfiguration();

            // Passed in as command line argument
            PublisherOpcApplicationConfiguration.ApplicationName = ApplicationName;
            PublisherOpcApplicationConfiguration.ApplicationUri  = $"urn:{Utils.GetHostName()}:{PublisherOpcApplicationConfiguration.ApplicationName}:microsoft:";
            PublisherOpcApplicationConfiguration.ProductUri      = "https://github.com/Azure/iot-edge-opc-publisher";
            PublisherOpcApplicationConfiguration.ApplicationType = ApplicationType.ClientAndServer;


            //
            // Security configuration
            //
            PublisherOpcApplicationConfiguration.SecurityConfiguration = new SecurityConfiguration();

            // Application certificate
            PublisherOpcApplicationConfiguration.SecurityConfiguration.ApplicationCertificate             = new CertificateIdentifier();
            PublisherOpcApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.StoreType   = OpcOwnCertStoreType;
            PublisherOpcApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.StorePath   = OpcOwnCertStorePath;
            PublisherOpcApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.SubjectName = PublisherOpcApplicationConfiguration.ApplicationName;
            Logger.Information($"Application Certificate store type is: {PublisherOpcApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.StoreType}");
            Logger.Information($"Application Certificate store path is: {PublisherOpcApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.StorePath}");
            Logger.Information($"Application Certificate subject name is: {PublisherOpcApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.SubjectName}");

            // Use existing certificate, if it is there.
            X509Certificate2 certificate = await PublisherOpcApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.Find(true);

            if (certificate == null)
            {
                Logger.Information($"No existing Application certificate found. Create a self-signed Application certificate valid from yesterday for {CertificateFactory.defaultLifeTime} months,");
                Logger.Information($"with a {CertificateFactory.defaultKeySize} bit key and {CertificateFactory.defaultHashSize} bit hash.");
                certificate = CertificateFactory.CreateCertificate(
                    PublisherOpcApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.StoreType,
                    PublisherOpcApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null,
                    PublisherOpcApplicationConfiguration.ApplicationUri,
                    PublisherOpcApplicationConfiguration.ApplicationName,
                    PublisherOpcApplicationConfiguration.ApplicationName,
                    null,
                    CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize,
                    false,
                    null,
                    null
                    );
                PublisherOpcApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.Certificate = certificate ?? throw new Exception("OPC UA application certificate can not be created! Cannot continue without it!");
            }
            else
            {
                Logger.Information("Application certificate found in Application Certificate Store");
            }
            PublisherOpcApplicationConfiguration.ApplicationUri = Utils.GetApplicationUriFromCertificate(certificate);
            Logger.Information($"Application certificate is for Application URI '{PublisherOpcApplicationConfiguration.ApplicationUri}', Application '{PublisherOpcApplicationConfiguration.ApplicationName} and has Subject '{PublisherOpcApplicationConfiguration.ApplicationName}'");

            // TrustedIssuerCertificates
            PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedIssuerCertificates           = new CertificateTrustList();
            PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedIssuerCertificates.StoreType = OpcIssuerCertStoreType;
            PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedIssuerCertificates.StorePath = OpcIssuerCertStorePath;
            Logger.Information($"Trusted Issuer store type is: {PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedIssuerCertificates.StoreType}");
            Logger.Information($"Trusted Issuer Certificate store path is: {PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedIssuerCertificates.StorePath}");

            // TrustedPeerCertificates
            PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates           = new CertificateTrustList();
            PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StoreType = OpcTrustedCertStoreType;
            if (string.IsNullOrEmpty(OpcTrustedCertStorePath))
            {
                // Set default.
                PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StorePath = OpcTrustedCertStoreType == X509Store ? OpcTrustedCertX509StorePathDefault : OpcTrustedCertDirectoryStorePathDefault;
                if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_TPC_SP")))
                {
                    // Use environment variable.
                    PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StorePath = Environment.GetEnvironmentVariable("_TPC_SP");
                }
            }
            else
            {
                PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StorePath = OpcTrustedCertStorePath;
            }
            Logger.Information($"Trusted Peer Certificate store type is: {PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StoreType}");
            Logger.Information($"Trusted Peer Certificate store path is: {PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");

            // RejectedCertificateStore
            PublisherOpcApplicationConfiguration.SecurityConfiguration.RejectedCertificateStore           = new CertificateTrustList();
            PublisherOpcApplicationConfiguration.SecurityConfiguration.RejectedCertificateStore.StoreType = OpcRejectedCertStoreType;
            PublisherOpcApplicationConfiguration.SecurityConfiguration.RejectedCertificateStore.StorePath = OpcRejectedCertStorePath;
            Logger.Information($"Rejected certificate store type is: {PublisherOpcApplicationConfiguration.SecurityConfiguration.RejectedCertificateStore.StoreType}");
            Logger.Information($"Rejected Certificate store path is: {PublisherOpcApplicationConfiguration.SecurityConfiguration.RejectedCertificateStore.StorePath}");

            // AutoAcceptUntrustedCertificates
            // This is a security risk and should be set to true only for debugging purposes.
            PublisherOpcApplicationConfiguration.SecurityConfiguration.AutoAcceptUntrustedCertificates = false;

            // RejectSHA1SignedCertificates
            // We allow SHA1 certificates for now as many OPC Servers still use them
            PublisherOpcApplicationConfiguration.SecurityConfiguration.RejectSHA1SignedCertificates = false;
            Logger.Information($"Rejection of SHA1 signed certificates is {(PublisherOpcApplicationConfiguration.SecurityConfiguration.RejectSHA1SignedCertificates ? "enabled" : "disabled")}");

            // MinimunCertificatesKeySize
            // We allow a minimum key size of 1024 bit, as many OPC UA servers still use them
            PublisherOpcApplicationConfiguration.SecurityConfiguration.MinimumCertificateKeySize = 1024;
            Logger.Information($"Minimum certificate key size set to {PublisherOpcApplicationConfiguration.SecurityConfiguration.MinimumCertificateKeySize}");

            // We make the default reference stack behavior configurable to put our own certificate into the trusted peer store.
            if (TrustMyself)
            {
                // Ensure it is trusted
                try
                {
                    ICertificateStore store = PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();
                    if (store == null)
                    {
                        Logger.Information($"Can not open trusted peer store. StorePath={PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");
                    }
                    else
                    {
                        try
                        {
                            Logger.Information($"Adding publisher certificate to trusted peer store. StorePath={PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");
                            X509Certificate2           publicKey      = new X509Certificate2(certificate.RawData);
                            X509Certificate2Collection certCollection = await store.FindByThumbprint(publicKey.Thumbprint);

                            if (certCollection.Count > 0)
                            {
                                Logger.Information($"A certificate with the same thumbprint is already in the trusted store.");
                            }
                            else
                            {
                                await store.Add(publicKey);
                            }
                        }
                        finally
                        {
                            store.Close();
                        }
                    }
                }
                catch (Exception e)
                {
                    Logger.Error(e, $"Can not add publisher certificate to trusted peer store. StorePath={PublisherOpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");
                }
            }
            else
            {
                Logger.Information("Publisher certificate is not added to trusted peer store.");
            }


            //
            // TransportConfigurations
            //

            PublisherOpcApplicationConfiguration.TransportQuotas = new TransportQuotas();
            PublisherOpcApplicationConfiguration.TransportQuotas.MaxByteStringLength = 4 * 1024 * 1024;
            PublisherOpcApplicationConfiguration.TransportQuotas.MaxMessageSize      = 4 * 1024 * 1024;

            // the maximum string length could be set to ajust for large number of nodes when reading the list of published nodes
            PublisherOpcApplicationConfiguration.TransportQuotas.MaxStringLength = OpcMaxStringLength;

            // the OperationTimeout should be twice the minimum value for PublishingInterval * KeepAliveCount, so set to 120s
            PublisherOpcApplicationConfiguration.TransportQuotas.OperationTimeout = OpcOperationTimeout;
            Logger.Information($"OperationTimeout set to {PublisherOpcApplicationConfiguration.TransportQuotas.OperationTimeout}");


            //
            // ServerConfiguration
            //
            PublisherOpcApplicationConfiguration.ServerConfiguration = new ServerConfiguration();

            // BaseAddresses
            if (PublisherOpcApplicationConfiguration.ServerConfiguration.BaseAddresses.Count == 0)
            {
                // We do not use the localhost replacement mechanism of the configuration loading, to immediately show the base address here
                PublisherOpcApplicationConfiguration.ServerConfiguration.BaseAddresses.Add($"opc.tcp://{Utils.GetHostName()}:{PublisherServerPort}{PublisherServerPath}");
            }
            foreach (var endpoint in PublisherOpcApplicationConfiguration.ServerConfiguration.BaseAddresses)
            {
                Logger.Information($"Publisher server base address: {endpoint}");
            }

            // SecurityPolicies
            // We do not allow security policy SecurityPolicies.None, but always high security
            ServerSecurityPolicy newPolicy = new ServerSecurityPolicy()
            {
                SecurityMode      = MessageSecurityMode.SignAndEncrypt,
                SecurityPolicyUri = SecurityPolicies.Basic256Sha256
            };

            PublisherOpcApplicationConfiguration.ServerConfiguration.SecurityPolicies.Add(newPolicy);
            Logger.Information($"Security policy {newPolicy.SecurityPolicyUri} with mode {newPolicy.SecurityMode} added");

            // MaxRegistrationInterval
            PublisherOpcApplicationConfiguration.ServerConfiguration.MaxRegistrationInterval = LdsRegistrationInterval;
            Logger.Information($"LDS(-ME) registration intervall set to {LdsRegistrationInterval} ms (0 means no registration)");

            //
            // TraceConfiguration
            //
            //
            // TraceConfiguration
            //
            PublisherOpcApplicationConfiguration.TraceConfiguration            = new TraceConfiguration();
            PublisherOpcApplicationConfiguration.TraceConfiguration.TraceMasks = OpcStackTraceMask;
            PublisherOpcApplicationConfiguration.TraceConfiguration.ApplySettings();
            Utils.Tracing.TraceEventHandler += new EventHandler <TraceEventArgs>(LoggerOpcUaTraceHandler);
            Logger.Information($"opcstacktracemask set to: 0x{OpcStackTraceMask:X}");

            // add default client configuration
            PublisherOpcApplicationConfiguration.ClientConfiguration = new ClientConfiguration();

            // validate the configuration now
            await PublisherOpcApplicationConfiguration.Validate(PublisherOpcApplicationConfiguration.ApplicationType);
        }
Exemple #8
0
        /// <summary>
        /// Creates a minimal application configuration for a server.
        /// </summary>
        /// <remarks>
        /// In many cases the application configuration will be loaded from an XML file.
        /// This example populates the configuration in code.
        /// </remarks>
        public static ApplicationConfiguration CreateServerConfiguration()
        {
            // The application configuration can be loaded from any file.
            // ApplicationConfiguration.Load() method loads configuration by looking up a file path in the App.config.
            // This approach allows applications to share configuration files and to update them.
            ApplicationConfiguration configuration = new ApplicationConfiguration();

            // Step 1 - Specify the server identity.
            configuration.ApplicationName = "My Server Name";
            configuration.ApplicationType = ApplicationType.Server;
            configuration.ApplicationUri  = "http://localhost/VendorId/ApplicationId/InstanceId";
            configuration.ProductUri      = "http://VendorId/ProductId/VersionId";

            configuration.SecurityConfiguration = new SecurityConfiguration();

            // Step 2 - Specify the server's application instance certificate.

            // Application instance certificates must be placed in a windows certficate store because that is
            // the best way to protect the private key. Certificates in a store are identified with 4 parameters:
            // StoreLocation, StoreName, SubjectName and Thumbprint.
            //
            // In this example the following values are used:
            //
            //   LocalMachine    - use the machine wide certificate store.
            //   Personal        - use the store for individual certificates.
            //   ApplicationName - use the application name as a search key.

            configuration.SecurityConfiguration.ApplicationCertificate             = new CertificateIdentifier();
            configuration.SecurityConfiguration.ApplicationCertificate.StoreType   = CertificateStoreType.Windows;
            configuration.SecurityConfiguration.ApplicationCertificate.StorePath   = "LocalMachine\\My";
            configuration.SecurityConfiguration.ApplicationCertificate.SubjectName = configuration.ApplicationName;

            // trust all applications installed on the same machine.
            configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType = CertificateStoreType.Windows;
            configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = "LocalMachine\\My";

            // find the certificate in the store.
            X509Certificate2 serverCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find(true);

            // create a new certificate if one not found.
            if (serverCertificate == null)
            {
                // this code would normally be called as part of the installer - called here to illustrate.
                // create a new certificate an place it in the LocalMachine/Personal store.
                serverCertificate = CertificateFactory.CreateCertificate(
                    configuration.SecurityConfiguration.ApplicationCertificate.StoreType,
                    configuration.SecurityConfiguration.ApplicationCertificate.StorePath,
                    configuration.ApplicationUri,
                    configuration.ApplicationName,
                    null,
                    null,
                    1024,
                    300);

                Console.WriteLine("Created server certificate: {0}", serverCertificate.Subject);
            }

            // Step 4 - Specify the supported transport quotas.

            // The transport quotas are used to set limits on the contents of messages and are
            // used to protect against DOS attacks and rogue clients. They should be set to
            // reasonable values.
            configuration.TransportQuotas = new TransportQuotas();
            configuration.TransportQuotas.OperationTimeout = 60000;

            configuration.ServerConfiguration = new ServerConfiguration();

            // turn off registration with the discovery server.
            configuration.ServerConfiguration.MaxRegistrationInterval = 0;

            // Step 5 - Specify the based addresses - one per binding specified above.
            configuration.ServerConfiguration.BaseAddresses.Add(DefaultHttpUrl);
            configuration.ServerConfiguration.BaseAddresses.Add(DefaultTcpUrl);

            // Step 6 - Specify the security policies.

            // Security policies control what security must be used to connect to the server.
            // The SDK will automatically create EndpointDescriptions for each combination of
            // security policy and base address.
            //
            // Note that some bindings only allow one policy per URL so the SDK will append
            // text to the base addresses in order to ensure that each policy has a unique URL.
            // The first policy specified in the configuration is assigned the base address.

            // this policy requires signing and encryption.
            ServerSecurityPolicy policy1 = new ServerSecurityPolicy();

            policy1.SecurityMode      = MessageSecurityMode.SignAndEncrypt;
            policy1.SecurityPolicyUri = SecurityPolicies.Basic128Rsa15;
            policy1.SecurityLevel     = 1;

            configuration.ServerConfiguration.SecurityPolicies.Add(policy1);

            // this policy does not require any security.
            ServerSecurityPolicy policy2 = new ServerSecurityPolicy();

            policy2.SecurityMode      = MessageSecurityMode.None;
            policy2.SecurityPolicyUri = SecurityPolicies.None;
            policy2.SecurityLevel     = 0;

            configuration.ServerConfiguration.SecurityPolicies.Add(policy2);

            // specify the supported user token types.
            configuration.ServerConfiguration.UserTokenPolicies.Add(new UserTokenPolicy(UserTokenType.Anonymous));
            configuration.ServerConfiguration.UserTokenPolicies.Add(new UserTokenPolicy(UserTokenType.UserName));

            // Step 6 - Validate the configuration.

            // This step checks if the configuration is consistent and assigns a few internal variables
            // that are used by the SDK. This is called automatically if the configuration is loaded from
            // a file using the ApplicationConfiguration.Load() method.
            configuration.Validate(ApplicationType.Server);

            return(configuration);
        }
Exemple #9
0
        internal void OnDeserializedMethod(StreamingContext context)
        {
            // Validate configuration and set reasonable defaults

            Configuration.ApplicationUri = Configuration.ApplicationUri.Replace("localhost", Utils.GetHostName());

            Configuration.ApplicationType = ApplicationType.ClientAndServer;
            Configuration.TransportQuotas = new TransportQuotas {
                OperationTimeout = 15000
            };
            Configuration.ClientConfiguration = new ClientConfiguration();
            Configuration.ServerConfiguration = new ServerConfiguration();

            if (Configuration.SecurityConfiguration == null)
            {
                Configuration.SecurityConfiguration = new SecurityConfiguration();
            }

            if (Configuration.SecurityConfiguration.TrustedPeerCertificates == null)
            {
                Configuration.SecurityConfiguration.TrustedPeerCertificates = new CertificateTrustList();
            }

            if (Configuration.SecurityConfiguration.TrustedIssuerCertificates == null)
            {
                Configuration.SecurityConfiguration.TrustedIssuerCertificates = new CertificateTrustList();
            }

            if (Configuration.SecurityConfiguration.RejectedCertificateStore == null)
            {
                Configuration.SecurityConfiguration.RejectedCertificateStore = new CertificateTrustList();
            }

            if (Configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType == null)
            {
                Configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType = "Directory";
            }

            if (Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath == null)
            {
                Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = "CertificateStores/UA Applications";
                if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_TPC_SP")))
                {
                    Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = Environment.GetEnvironmentVariable("_TPC_SP");
                }
            }

            if (Configuration.SecurityConfiguration.TrustedIssuerCertificates.StoreType == null)
            {
                Configuration.SecurityConfiguration.TrustedIssuerCertificates.StoreType = "Directory";
            }

            if (Configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath == null)
            {
                Configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath = "CertificateStores/UA Certificate Authorities";
            }

            if (Configuration.SecurityConfiguration.RejectedCertificateStore.StoreType == null)
            {
                Configuration.SecurityConfiguration.RejectedCertificateStore.StoreType = "Directory";
            }

            if (Configuration.SecurityConfiguration.RejectedCertificateStore.StorePath == null)
            {
                Configuration.SecurityConfiguration.RejectedCertificateStore.StorePath = "CertificateStores/Rejected Certificates";
            }

            Configuration.SecurityConfiguration.ApplicationCertificate             = new CertificateIdentifier();
            Configuration.SecurityConfiguration.ApplicationCertificate.StoreType   = "X509Store";
            Configuration.SecurityConfiguration.ApplicationCertificate.StorePath   = "CurrentUser\\UA_MachineDefault";
            Configuration.SecurityConfiguration.ApplicationCertificate.SubjectName = Configuration.ApplicationName;

            X509Certificate2 certificate = Configuration.SecurityConfiguration.ApplicationCertificate.Find(true).Result;

            if (certificate == null)
            {
                certificate = CertificateFactory.CreateCertificate(
                    Configuration.SecurityConfiguration.ApplicationCertificate.StoreType,
                    Configuration.SecurityConfiguration.ApplicationCertificate.StorePath,
                    Configuration.ApplicationUri,
                    Configuration.ApplicationName,
                    Configuration.ApplicationName,
                    new List <string>()
                {
                    Configuration.ApplicationName
                }
                    );
            }
            if (certificate == null)
            {
                throw new Exception("Opc.Ua.Publisher.Module: OPC UA application certificate could not be created, cannot continue without it!");
            }

            Configuration.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            Configuration.ApplicationUri = Utils.GetApplicationUriFromCertificate(certificate);

            // Ensure it is trusted
            try
            {
                ICertificateStore store = Configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();
                if (store == null)
                {
                    Utils.Trace("Could not open trusted peer store. StorePath={0}", Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath);
                }
                else
                {
                    try
                    {
                        Utils.Trace(Utils.TraceMasks.Information, "Adding certificate to trusted peer store. StorePath={0}", Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath);
                        X509Certificate2 publicKey = new X509Certificate2(certificate.RawData);
                        store.Add(publicKey).Wait();
                    }
                    finally
                    {
                        store.Close();
                    }
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Could not add certificate to trusted peer store. StorePath={0}", Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath);
            }

            // patch our base address
            if (Configuration.ServerConfiguration.BaseAddresses.Count == 0)
            {
                Configuration.ServerConfiguration.BaseAddresses.Add("opc.tcp://" + Configuration.ApplicationName.ToLowerInvariant() + ":62222/UA/Publisher");
            }

            // tighten security policy by removing security policy "none"
            foreach (ServerSecurityPolicy policy in Configuration.ServerConfiguration.SecurityPolicies)
            {
                if (policy.SecurityMode == MessageSecurityMode.None)
                {
                    Configuration.ServerConfiguration.SecurityPolicies.Remove(policy);
                    break;
                }
            }

            // turn off LDS registration
            Configuration.ServerConfiguration.MaxRegistrationInterval = 0;

            // add sign & encrypt policy
            ServerSecurityPolicy newPolicy = new ServerSecurityPolicy();

            newPolicy.SecurityMode      = MessageSecurityMode.SignAndEncrypt;
            newPolicy.SecurityLevel     = 1;
            newPolicy.SecurityPolicyUri = SecurityPolicies.Basic128Rsa15;
            Configuration.ServerConfiguration.SecurityPolicies.Add(newPolicy);

            // enable logging
            Configuration.TraceConfiguration = new TraceConfiguration();
            Configuration.TraceConfiguration.DeleteOnLoad   = true;
            Configuration.TraceConfiguration.TraceMasks     = 519;
            Configuration.TraceConfiguration.OutputFilePath = "./Logs/" + Configuration.ApplicationName + ".log.txt";
            Configuration.TraceConfiguration.ApplySettings();

            // the OperationTimeout should be twice the minimum value for PublishingInterval * KeepAliveCount, so set to 120s
            Configuration.TransportQuotas.OperationTimeout = 120000;

            // validate the configuration now
            Configuration.Validate(Configuration.ApplicationType).Wait();
        }
Exemple #10
0
        public ModuleConfiguration(string applicationName)
        {
            // set reasonable defaults
            Configuration = new ApplicationConfiguration();
            Configuration.ApplicationName = applicationName;
            Configuration.ApplicationUri  = "urn:" + Utils.GetHostName() + ":microsoft:" + Configuration.ApplicationName;
            Configuration.ApplicationType = ApplicationType.ClientAndServer;
            Configuration.TransportQuotas = new TransportQuotas {
                OperationTimeout = 15000
            };
            Configuration.ClientConfiguration = new ClientConfiguration();
            Configuration.ServerConfiguration = new ServerConfiguration();

            // enable logging
            Configuration.TraceConfiguration            = new TraceConfiguration();
            Configuration.TraceConfiguration.TraceMasks = Utils.TraceMasks.Error | Utils.TraceMasks.Security | Utils.TraceMasks.StackTrace | Utils.TraceMasks.StartStop;
            if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_LOGP")))
            {
                Configuration.TraceConfiguration.OutputFilePath = Environment.GetEnvironmentVariable("_GW_LOGP");
            }
            else
            {
                Configuration.TraceConfiguration.OutputFilePath = "./Logs/" + Configuration.ApplicationName + ".log.txt";
            }
            Configuration.TraceConfiguration.ApplySettings();

            if (Configuration.SecurityConfiguration == null)
            {
                Configuration.SecurityConfiguration = new SecurityConfiguration();
            }

            if (Configuration.SecurityConfiguration.TrustedPeerCertificates == null)
            {
                Configuration.SecurityConfiguration.TrustedPeerCertificates = new CertificateTrustList();
            }

            if (Configuration.SecurityConfiguration.TrustedIssuerCertificates == null)
            {
                Configuration.SecurityConfiguration.TrustedIssuerCertificates = new CertificateTrustList();
            }

            if (Configuration.SecurityConfiguration.RejectedCertificateStore == null)
            {
                Configuration.SecurityConfiguration.RejectedCertificateStore = new CertificateTrustList();
            }

            if (Configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType == null)
            {
                Configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType = "Directory";
            }

            if (Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath == null)
            {
                Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = "CertificateStores/UA Applications";
                if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_TPC_SP")))
                {
                    Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = Environment.GetEnvironmentVariable("_TPC_SP");
                }
            }

            if (Configuration.SecurityConfiguration.TrustedIssuerCertificates.StoreType == null)
            {
                Configuration.SecurityConfiguration.TrustedIssuerCertificates.StoreType = "Directory";
            }

            if (Configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath == null)
            {
                Configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath = "CertificateStores/UA Certificate Authorities";
            }

            if (Configuration.SecurityConfiguration.RejectedCertificateStore.StoreType == null)
            {
                Configuration.SecurityConfiguration.RejectedCertificateStore.StoreType = "Directory";
            }

            if (Configuration.SecurityConfiguration.RejectedCertificateStore.StorePath == null)
            {
                Configuration.SecurityConfiguration.RejectedCertificateStore.StorePath = "CertificateStores/Rejected Certificates";
            }

            Configuration.SecurityConfiguration.ApplicationCertificate             = new CertificateIdentifier();
            Configuration.SecurityConfiguration.ApplicationCertificate.StoreType   = "X509Store";
            Configuration.SecurityConfiguration.ApplicationCertificate.StorePath   = "CurrentUser\\UA_MachineDefault";
            Configuration.SecurityConfiguration.ApplicationCertificate.SubjectName = Configuration.ApplicationName;

            X509Certificate2 certificate = Configuration.SecurityConfiguration.ApplicationCertificate.Find(true).Result;

            if (certificate == null)
            {
                certificate = CertificateFactory.CreateCertificate(
                    Configuration.SecurityConfiguration.ApplicationCertificate.StoreType,
                    Configuration.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null,
                    Configuration.ApplicationUri,
                    Configuration.ApplicationName,
                    Configuration.ApplicationName,
                    null,
                    CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize,
                    false,
                    null,
                    null
                    );
            }
            if (certificate == null)
            {
                throw new Exception("OPC UA application certificate could not be created, cannot continue without it!");
            }

            Configuration.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            Configuration.ApplicationUri = Utils.GetApplicationUriFromCertificate(certificate);

            // Ensure it is trusted
            try
            {
                ICertificateStore store = Configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();
                if (store == null)
                {
                    Program.Trace("Could not open trusted peer store. StorePath={0}", Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath);
                }
                else
                {
                    try
                    {
                        Program.Trace(Utils.TraceMasks.Information, "Adding certificate to trusted peer store. StorePath={0}", Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath);
                        X509Certificate2 publicKey = new X509Certificate2(certificate.RawData);
                        store.Add(publicKey).Wait();
                    }
                    finally
                    {
                        store.Close();
                    }
                }
            }
            catch (Exception e)
            {
                Program.Trace(e, "Could not add certificate to trusted peer store. StorePath={0}", Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath);
            }

            // patch our base address
            if (Configuration.ServerConfiguration.BaseAddresses.Count == 0)
            {
                Configuration.ServerConfiguration.BaseAddresses.Add("opc.tcp://" + Configuration.ApplicationName.ToLowerInvariant() + ":62222/UA/Publisher");
            }

            // tighten security policy by removing security policy "none"
            foreach (ServerSecurityPolicy policy in Configuration.ServerConfiguration.SecurityPolicies)
            {
                if (policy.SecurityMode == MessageSecurityMode.None)
                {
                    Configuration.ServerConfiguration.SecurityPolicies.Remove(policy);
                    break;
                }
            }

            // turn off LDS registration
            Configuration.ServerConfiguration.MaxRegistrationInterval = 0;

            // add sign & encrypt policy
            ServerSecurityPolicy newPolicy = new ServerSecurityPolicy();

            newPolicy.SecurityMode      = MessageSecurityMode.SignAndEncrypt;
            newPolicy.SecurityPolicyUri = SecurityPolicies.Basic128Rsa15;
            Configuration.ServerConfiguration.SecurityPolicies.Add(newPolicy);

            // the OperationTimeout should be twice the minimum value for PublishingInterval * KeepAliveCount, so set to 120s
            Configuration.TransportQuotas.OperationTimeout = 120000;

            // allow SHA1 certificates for now as many OPC Servers still use them
            Configuration.SecurityConfiguration.RejectSHA1SignedCertificates = false;

            // allow 1024 minimum key size as many OPC Servers still use them
            Configuration.SecurityConfiguration.MinimumCertificateKeySize = 1024;

            // validate the configuration now
            Configuration.Validate(Configuration.ApplicationType).Wait();
        }
        public ModuleConfiguration(string applicationName)
        {
            // set reasonable defaults
            Configuration = new ApplicationConfiguration()
            {
                ApplicationName = applicationName
            };
            Configuration.ApplicationUri  = "urn:" + Utils.GetHostName() + ":microsoft:" + Configuration.ApplicationName;
            Configuration.ApplicationType = ApplicationType.ClientAndServer;
            Configuration.TransportQuotas = new TransportQuotas {
                OperationTimeout = 15000
            };
            Configuration.ClientConfiguration = new ClientConfiguration();
            Configuration.ServerConfiguration = new ServerConfiguration();

            // initialize stack tracing
            Configuration.TraceConfiguration = new TraceConfiguration()
            {
                TraceMasks = Program.OpcStackTraceMask
            };
            Utils.SetTraceOutput(Utils.TraceOutput.FileOnly);
            if (string.IsNullOrEmpty(Program.LogFileName))
            {
                if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_LOGP")))
                {
                    Configuration.TraceConfiguration.OutputFilePath = Environment.GetEnvironmentVariable("_GW_LOGP");
                }
                else
                {
                    Configuration.TraceConfiguration.OutputFilePath = "./Logs/" + Configuration.ApplicationName + ".log.txt";
                }
            }
            else
            {
                Configuration.TraceConfiguration.OutputFilePath = Program.LogFileName;
            }
            Configuration.TraceConfiguration.ApplySettings();
            Trace($"Current directory is: {Directory.GetCurrentDirectory()}");
            Trace($"Log file is: {Utils.GetAbsoluteFilePath(Configuration.TraceConfiguration.OutputFilePath, true, false, false, true)}");
            Trace($"opcstacktracemask set to: 0x{Program.OpcStackTraceMask:X} ({Program.OpcStackTraceMask})");

            Configuration.SecurityConfiguration = new SecurityConfiguration();

            // Trusted cert store configuration.
            Configuration.SecurityConfiguration.TrustedPeerCertificates           = new CertificateTrustList();
            Configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType = Program.OpcTrustedCertStoreType;
            if (string.IsNullOrEmpty(Program.OpcTrustedCertStorePath))
            {
                // Set default.
                Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = Program.OpcTrustedCertStoreType == CertificateStoreType.X509Store ? Program.OpcTrustedCertX509StorePathDefault : Program.OpcTrustedCertDirectoryStorePathDefault;
                if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_TPC_SP")))
                {
                    // Use environment variable.
                    Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = Environment.GetEnvironmentVariable("_TPC_SP");
                }
            }
            else
            {
                Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = Program.OpcTrustedCertStorePath;
            }
            Trace($"Trusted Peer Certificate store type is: {Configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType}");
            Trace($"Trusted Peer Certificate store path is: {Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");

            // Trusted issuer cert store configuration.
            Configuration.SecurityConfiguration.TrustedIssuerCertificates           = new CertificateTrustList();
            Configuration.SecurityConfiguration.TrustedIssuerCertificates.StoreType = Program.OpcIssuerCertStoreType;
            Configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath = Program.OpcIssuerCertStorePath;
            Trace($"Trusted Issuer store type is: {Configuration.SecurityConfiguration.TrustedIssuerCertificates.StoreType}");
            Trace($"Trusted Issuer Certificate store path is: {Configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath}");

            // Rejected cert store configuration.
            Configuration.SecurityConfiguration.RejectedCertificateStore           = new CertificateTrustList();
            Configuration.SecurityConfiguration.RejectedCertificateStore.StoreType = Program.OpcRejectedCertStoreType;
            Configuration.SecurityConfiguration.RejectedCertificateStore.StorePath = Program.OpcRejectedCertStorePath;
            Trace($"Rejected certificate store type is: {Configuration.SecurityConfiguration.RejectedCertificateStore.StoreType}");
            Trace($"Rejected Certificate store path is: {Configuration.SecurityConfiguration.RejectedCertificateStore.StorePath}");

            Configuration.SecurityConfiguration.ApplicationCertificate = new CertificateIdentifier()
            {
                StoreType   = Program.OpcOwnCertStoreType,
                StorePath   = Program.OpcOwnCertStorePath,
                SubjectName = Configuration.ApplicationName
            };
            Trace($"Application Certificate store type is: {Configuration.SecurityConfiguration.ApplicationCertificate.StoreType}");
            Trace($"Application Certificate store path is: {Configuration.SecurityConfiguration.ApplicationCertificate.StorePath}");

            // Use existing certificate, if it is there.
            X509Certificate2 certificate = Configuration.SecurityConfiguration.ApplicationCertificate.Find(true).Result;

            if (certificate == null)
            {
                Trace($"Create a self-signed Application certificate valid from yesterday for {CertificateFactory.defaultLifeTime} months,");
                Trace($"with a {CertificateFactory.defaultKeySize} bit key and {CertificateFactory.defaultHashSize} bit hash.");
                certificate = CertificateFactory.CreateCertificate(
                    Configuration.SecurityConfiguration.ApplicationCertificate.StoreType,
                    Configuration.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null,
                    Configuration.ApplicationUri,
                    Configuration.ApplicationName,
                    Configuration.ApplicationName,
                    null,
                    CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize,
                    false,
                    null,
                    null
                    );
                Configuration.SecurityConfiguration.ApplicationCertificate.Certificate = certificate ?? throw new Exception("OPC UA application certificate could not be created! Cannot continue without it!");

                // Trust myself if requested.
                if (Program.TrustMyself)
                {
                    // Ensure it is trusted
                    try
                    {
                        ICertificateStore store = Configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();
                        if (store == null)
                        {
                            Trace($"Could not open trusted peer store. StorePath={Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");
                        }
                        else
                        {
                            try
                            {
                                Trace($"Adding publisher certificate to trusted peer store. StorePath={Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");
                                X509Certificate2 publicKey = new X509Certificate2(certificate.RawData);
                                store.Add(publicKey).Wait();
                            }
                            finally
                            {
                                store.Close();
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Trace(e, $"Could not add publisher certificate to trusted peer store. StorePath={Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");
                    }
                }
                else
                {
                    Trace("Publisher certificate is not added to trusted peer store.");
                }
            }
            else
            {
                Trace("Application certificate found in Application Certificate Store");
            }
            Configuration.ApplicationUri = Utils.GetApplicationUriFromCertificate(certificate);
            Trace($"Application certificate is for Application URI: {Configuration.ApplicationUri}");

            // patch our base address
            if (Configuration.ServerConfiguration.BaseAddresses.Count == 0)
            {
                Configuration.ServerConfiguration.BaseAddresses.Add($"opc.tcp://{Configuration.ApplicationName.ToLowerInvariant()}:{Program.PublisherServerPort}{Program.PublisherServerPath}");
            }
            foreach (var endpoint in Configuration.ServerConfiguration.BaseAddresses)
            {
                Trace($"Publisher server Endpoint URL: {endpoint}");
            }

            // Set LDS registration interval
            Configuration.ServerConfiguration.MaxRegistrationInterval = Program.LdsRegistrationInterval;
            Trace($"LDS(-ME) registration intervall set to {Program.LdsRegistrationInterval} ms (0 means no registration)");

            // add sign & encrypt policy
            ServerSecurityPolicy newPolicy = new ServerSecurityPolicy()
            {
                SecurityMode      = MessageSecurityMode.SignAndEncrypt,
                SecurityPolicyUri = SecurityPolicies.Basic256Sha256
            };

            Configuration.ServerConfiguration.SecurityPolicies.Add(newPolicy);
            Trace($"Security policy {newPolicy.SecurityPolicyUri} with mode {newPolicy.SecurityMode} added");

            // the OperationTimeout should be twice the minimum value for PublishingInterval * KeepAliveCount, so set to 120s
            Configuration.TransportQuotas.OperationTimeout = Program.OpcOperationTimeout;
            Trace($"OperationTimeout set to {Configuration.TransportQuotas.OperationTimeout}");

            // allow SHA1 certificates for now as many OPC Servers still use them
            Configuration.SecurityConfiguration.RejectSHA1SignedCertificates = false;
            Trace($"Rejection of SHA1 signed certificates is {(Configuration.SecurityConfiguration.RejectSHA1SignedCertificates ? "enabled" : "disabled")}");

            // allow 1024 minimum key size as many OPC Servers still use them
            Configuration.SecurityConfiguration.MinimumCertificateKeySize = 1024;
            Trace($"Minimum certificate key size set to {Configuration.SecurityConfiguration.MinimumCertificateKeySize}");

            // validate the configuration now
            Configuration.Validate(Configuration.ApplicationType).Wait();
        }
Exemple #12
0
        /// <summary>
        /// hardcoded application configuration of the collector server/client
        /// </summary>
        /// <returns>application configuration of the collector server/client</returns>
        public static ApplicationConfiguration getConfiguration()
        {
            //not fully implemented

            ApplicationConfiguration config = new ApplicationConfiguration();

            config.ApplicationName = "Collector Server";
            //config.ApplicationType = null;
            config.ApplicationUri = @"urn:localhost:UA:InformationModelServer";
            //config.CertificateValidator = null;
            //config.ClientConfiguration = null;
            //config.DisableHiResClock = null;
            //config.DiscoveryServerConfiguration = null;
            #region Extensions
            List <XmlElement> config_extensions = new List <XmlElement>();

            #endregion
            config.Extensions = new XmlElementCollection();
            //config.MessageContext = null;
            config.ProductUri = @"http://opcfoundation.org/UA/InformationModelServer";
            //config.Properties = null;
            //config.PropertiesLock = null;
            #region Security Configuration
            SecurityConfiguration config_security             = new SecurityConfiguration();
            CertificateIdentifier config_security_certificate = new CertificateIdentifier();
            config_security_certificate.StoreType   = "Directory";
            config_security_certificate.StorePath   = @"%CommonApplicationData%\OPC Foundation\pki\own";
            config_security_certificate.SubjectName = @"CN = Demo Server, C = US, S = Arizona, O = OPC Foundation, DC = localhost";
            config_security.ApplicationCertificate  = config_security_certificate;
            CertificateTrustList config_trustedIssuer = new CertificateTrustList();
            config_trustedIssuer.StoreType            = "Directory";
            config_trustedIssuer.StorePath            = @"%CommonApplicationData%\OPC Foundation\pki\issuer";
            config_security.TrustedIssuerCertificates = config_trustedIssuer;
            CertificateTrustList config_security_trustedPeer = new CertificateTrustList();
            config_security_trustedPeer.StoreType   = "Directory";
            config_security_trustedPeer.StorePath   = @"%CommonApplicationData%\OPC Foundation\pki\trusted";
            config_security.TrustedPeerCertificates = config_security_trustedPeer;
            CertificateStoreIdentifier config_security_rejected = new CertificateStoreIdentifier();
            config_security_rejected.StoreType       = "Directory";
            config_security_rejected.StorePath       = @"%CommonApplicationData%\OPC Foundation\pki\rejected";
            config_security.RejectedCertificateStore = config_security_rejected;
            #endregion
            config.SecurityConfiguration = config_security;
            //config_security.ApplicationCertificate = null;
            #region ServerConfiguration
            ServerConfiguration config_server            = new ServerConfiguration();
            List <string>       config_server_baseAdress = new List <string>();
            config_server_baseAdress.Add(@"https://*****:*****@"opc.tcp://localhost:51210/CollectorServer");
            config_server.BaseAddresses = new StringCollection(config_server_baseAdress);
            List <ServerSecurityPolicy> config_server_policies = new List <ServerSecurityPolicy>();
            ServerSecurityPolicy        tmp_pol1 = new ServerSecurityPolicy();
            tmp_pol1.SecurityMode      = MessageSecurityMode.SignAndEncrypt;
            tmp_pol1.SecurityPolicyUri = @"http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256";
            config_server_policies.Add(tmp_pol1);
            ServerSecurityPolicy tmp_pol2 = new ServerSecurityPolicy();
            tmp_pol2.SecurityMode      = MessageSecurityMode.None;
            tmp_pol2.SecurityPolicyUri = @"http://opcfoundation.org/UA/SecurityPolicy#None";
            config_server_policies.Add(tmp_pol2);
            ServerSecurityPolicy tmp_pol3 = new ServerSecurityPolicy();
            tmp_pol3.SecurityMode      = MessageSecurityMode.Sign;
            tmp_pol3.SecurityPolicyUri = @"";
            config_server_policies.Add(tmp_pol3);
            ServerSecurityPolicy tmp_pol4 = new ServerSecurityPolicy();
            tmp_pol4.SecurityMode      = MessageSecurityMode.SignAndEncrypt;
            tmp_pol4.SecurityPolicyUri = @"";
            ServerSecurityPolicyCollection config_server_policy = new ServerSecurityPolicyCollection(config_server_policies);
            config_server.SecurityPolicies = config_server_policy;
            List <UserTokenPolicy> config_server_userTokenPolicies = new List <UserTokenPolicy>();
            config_server_userTokenPolicies.Add(new UserTokenPolicy(UserTokenType.Anonymous));
            config_server_userTokenPolicies.Add(new UserTokenPolicy(UserTokenType.UserName));
            config_server_userTokenPolicies.Add(new UserTokenPolicy(UserTokenType.Certificate));
            config_server.UserTokenPolicies            = new UserTokenPolicyCollection(config_server_userTokenPolicies);
            config_server.DiagnosticsEnabled           = false;
            config_server.MaxSessionCount              = 100;
            config_server.MinSessionTimeout            = 10000;
            config_server.MaxSessionTimeout            = 3600000;
            config_server.MaxBrowseContinuationPoints  = 10;
            config_server.MaxQueryContinuationPoints   = 10;
            config_server.MaxHistoryContinuationPoints = 100;
            config_server.MaxRequestAge               = 600000;
            config_server.MinPublishingInterval       = 100;
            config_server.MaxPublishingInterval       = 3600000;
            config_server.PublishingResolution        = 50;
            config_server.MaxSubscriptionLifetime     = 3600000;
            config_server.MaxMessageQueueSize         = 10;
            config_server.MaxNotificationQueueSize    = 100;
            config_server.MaxNotificationsPerPublish  = 1000;
            config_server.MinMetadataSamplingInterval = 1000;
            List <SamplingRateGroup> config_server_samplingRateGroups = new List <SamplingRateGroup>();
            config_server_samplingRateGroups.Add(new SamplingRateGroup(5, 5, 20));
            config_server_samplingRateGroups.Add(new SamplingRateGroup(100, 100, 4));
            config_server_samplingRateGroups.Add(new SamplingRateGroup(500, 250, 2));
            config_server_samplingRateGroups.Add(new SamplingRateGroup(1000, 500, 20));
            config_server.AvailableSamplingRates  = new SamplingRateGroupCollection(config_server_samplingRateGroups);
            config_server.MaxRegistrationInterval = 30000;
            #endregion
            config.ServerConfiguration = config_server;
            //config.SourceFilePath = null;
            #region TraceConfiguration
            TraceConfiguration config_traceConfiguration = new TraceConfiguration();
            config_traceConfiguration.OutputFilePath = @"Logs\Quickstarts.BoilerServer.log.txt";
            config_traceConfiguration.DeleteOnLoad   = true;
            config_traceConfiguration.TraceMasks     = 515;
            #endregion
            config.TraceConfiguration      = config_traceConfiguration;
            config.TransportConfigurations = new TransportConfigurationCollection();
            #region TransportQuotas
            TransportQuotas config_transportQuotas = new TransportQuotas();
            config_transportQuotas.OperationTimeout      = 600000;
            config_transportQuotas.MaxStringLength       = 1048576;
            config_transportQuotas.MaxByteStringLength   = 1048576;
            config_transportQuotas.MaxArrayLength        = 65535;
            config_transportQuotas.ChannelLifetime       = 300000;
            config_transportQuotas.SecurityTokenLifetime = 3600000;
            #endregion
            config.TransportQuotas = config_transportQuotas;
            return(config);
        }
Exemple #13
0
        /// <summary>
        /// Creates a minimal application configuration for a server.
        /// </summary>
        /// <remarks>
        /// In many cases the application configuration will be loaded from an XML file. 
        /// This example populates the configuration in code.
        /// </remarks>
        public static ApplicationConfiguration CreateServerConfiguration()
        {
            // The application configuration can be loaded from any file.
            // ApplicationConfiguration.Load() method loads configuration by looking up a file path in the App.config.
            // This approach allows applications to share configuration files and to update them.
            ApplicationConfiguration configuration = new ApplicationConfiguration();

            // Step 1 - Specify the server identity.
            configuration.ApplicationName = "My Server Name";
            configuration.ApplicationType = ApplicationType.Server;
            configuration.ApplicationUri  = "http://localhost/VendorId/ApplicationId/InstanceId";
            configuration.ProductUri      = "http://VendorId/ProductId/VersionId";

            configuration.SecurityConfiguration = new SecurityConfiguration();

            // Step 2 - Specify the server's application instance certificate.

            // Application instance certificates must be placed in a windows certficate store because that is 
            // the best way to protect the private key. Certificates in a store are identified with 4 parameters:
            // StoreLocation, StoreName, SubjectName and Thumbprint.
            //
            // In this example the following values are used:
            // 
            //   LocalMachine    - use the machine wide certificate store.
            //   Personal        - use the store for individual certificates.
            //   ApplicationName - use the application name as a search key.   
             
            configuration.SecurityConfiguration.ApplicationCertificate               = new CertificateIdentifier();
            configuration.SecurityConfiguration.ApplicationCertificate.StoreType     = CertificateStoreType.Windows;
            configuration.SecurityConfiguration.ApplicationCertificate.StorePath     = "LocalMachine\\My";
            configuration.SecurityConfiguration.ApplicationCertificate.SubjectName   = configuration.ApplicationName;
            
            // trust all applications installed on the same machine.
            configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType = CertificateStoreType.Windows;
            configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = "LocalMachine\\My";

            // find the certificate in the store.
            X509Certificate2 serverCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find(true);

            // create a new certificate if one not found.
            if (serverCertificate == null)
            {
                // this code would normally be called as part of the installer - called here to illustrate.
                // create a new certificate an place it in the LocalMachine/Personal store.
                serverCertificate = CertificateFactory.CreateCertificate(
                    configuration.SecurityConfiguration.ApplicationCertificate.StoreType,
                    configuration.SecurityConfiguration.ApplicationCertificate.StorePath,
                    configuration.ApplicationUri,
                    configuration.ApplicationName,
                    null,
                    null,
                    1024,
                    300);

                Console.WriteLine("Created server certificate: {0}", serverCertificate.Subject);
            }
            
            // Step 4 - Specify the supported transport quotas.

            // The transport quotas are used to set limits on the contents of messages and are
            // used to protect against DOS attacks and rogue clients. They should be set to
            // reasonable values.
            configuration.TransportQuotas = new TransportQuotas();
            configuration.TransportQuotas.OperationTimeout = 60000;

            configuration.ServerConfiguration = new ServerConfiguration();

            // turn off registration with the discovery server.
            configuration.ServerConfiguration.MaxRegistrationInterval = 0;

            // Step 5 - Specify the based addresses - one per binding specified above.
            configuration.ServerConfiguration.BaseAddresses.Add(DefaultHttpUrl);
            configuration.ServerConfiguration.BaseAddresses.Add(DefaultTcpUrl);

            // Step 6 - Specify the security policies.
          
            // Security policies control what security must be used to connect to the server.
            // The SDK will automatically create EndpointDescriptions for each combination of 
            // security policy and base address. 
            //
            // Note that some bindings only allow one policy per URL so the SDK will append 
            // text to the base addresses in order to ensure that each policy has a unique URL.
            // The first policy specified in the configuration is assigned the base address.

            // this policy requires signing and encryption.
            ServerSecurityPolicy policy1 = new ServerSecurityPolicy();

            policy1.SecurityMode      = MessageSecurityMode.SignAndEncrypt;
            policy1.SecurityPolicyUri = SecurityPolicies.Basic128Rsa15;
            policy1.SecurityLevel     = 1;

            configuration.ServerConfiguration.SecurityPolicies.Add(policy1);

            // this policy does not require any security.
            ServerSecurityPolicy policy2 = new ServerSecurityPolicy();

            policy2.SecurityMode      = MessageSecurityMode.None;
            policy2.SecurityPolicyUri = SecurityPolicies.None;
            policy2.SecurityLevel     = 0;

            configuration.ServerConfiguration.SecurityPolicies.Add(policy2);

            // specify the supported user token types.
            configuration.ServerConfiguration.UserTokenPolicies.Add(new UserTokenPolicy(UserTokenType.Anonymous));
            configuration.ServerConfiguration.UserTokenPolicies.Add(new UserTokenPolicy(UserTokenType.UserName));

            // Step 6 - Validate the configuration.
        
            // This step checks if the configuration is consistent and assigns a few internal variables
            // that are used by the SDK. This is called automatically if the configuration is loaded from
            // a file using the ApplicationConfiguration.Load() method.          
            configuration.Validate(ApplicationType.Server);    
            
            return configuration;
        }
Exemple #14
0
        /// <inheritdoc/>
        /// <summary>
        /// Create a new service host for UA TCP.
        /// </summary>
        public List <EndpointDescription> CreateServiceHost(
            ServerBase serverBase,
            IDictionary <string, ServiceHost> hosts,
            ApplicationConfiguration configuration,
            IList <string> baseAddresses,
            ApplicationDescription serverDescription,
            List <ServerSecurityPolicy> securityPolicies,
            X509Certificate2 instanceCertificate,
            X509Certificate2Collection instanceCertificateChain)
        {
            // generate a unique host name.
            string hostName = "/Tcp";

            if (hosts.ContainsKey(hostName))
            {
                hostName += Utils.Format("/{0}", hosts.Count);
            }

            // build list of uris.
            List <Uri> uris = new List <Uri>();
            EndpointDescriptionCollection endpoints = new EndpointDescriptionCollection();

            // create the endpoint configuration to use.
            EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration);
            string computerName = Utils.GetHostName();

            for (int ii = 0; ii < baseAddresses.Count; ii++)
            {
                // UA TCP and HTTPS endpoints support multiple policies.
                if (!baseAddresses[ii].StartsWith(Utils.UriSchemeOpcTcp, StringComparison.Ordinal))
                {
                    continue;
                }

                UriBuilder uri = new UriBuilder(baseAddresses[ii]);

                if (String.Equals(uri.Host, "localhost", StringComparison.OrdinalIgnoreCase))
                {
                    uri.Host = computerName;
                }

                ITransportListener listener = this.Create();
                if (listener != null)
                {
                    EndpointDescriptionCollection listenerEndpoints = new EndpointDescriptionCollection();
                    uris.Add(uri.Uri);

                    foreach (ServerSecurityPolicy policy in securityPolicies)
                    {
                        // create the endpoint description.
                        EndpointDescription description = new EndpointDescription();

                        description.EndpointUrl = uri.ToString();
                        description.Server      = serverDescription;

                        description.SecurityMode        = policy.SecurityMode;
                        description.SecurityPolicyUri   = policy.SecurityPolicyUri;
                        description.SecurityLevel       = ServerSecurityPolicy.CalculateSecurityLevel(policy.SecurityMode, policy.SecurityPolicyUri);
                        description.UserIdentityTokens  = serverBase.GetUserTokenPolicies(configuration, description);
                        description.TransportProfileUri = Profiles.UaTcpTransport;

                        bool requireEncryption = ServerBase.RequireEncryption(description);

                        if (requireEncryption)
                        {
                            description.ServerCertificate = instanceCertificate.RawData;

                            // check if complete chain should be sent.
                            if (configuration.SecurityConfiguration.SendCertificateChain &&
                                instanceCertificateChain != null &&
                                instanceCertificateChain.Count > 0)
                            {
                                List <byte> serverCertificateChain = new List <byte>();

                                for (int i = 0; i < instanceCertificateChain.Count; i++)
                                {
                                    serverCertificateChain.AddRange(instanceCertificateChain[i].RawData);
                                }

                                description.ServerCertificate = serverCertificateChain.ToArray();
                            }
                        }

                        listenerEndpoints.Add(description);
                    }

                    serverBase.CreateServiceHostEndpoint(uri.Uri, listenerEndpoints, endpointConfiguration, listener,
                                                         configuration.CertificateValidator.GetChannelValidator()
                                                         );

                    endpoints.AddRange(listenerEndpoints);
                }
                else
                {
                    Utils.Trace(Utils.TraceMasks.Error, "Failed to create endpoint {0} because the transport profile is unsupported.", uri);
                }
            }

            hosts[hostName] = serverBase.CreateServiceHost(serverBase, uris.ToArray());

            return(endpoints);
        }
        /// <summary>
        /// Creates a new policy object.
        /// </summary>
        private static ServerSecurityPolicy CreatePolicy(string profileUri)
        {
            ServerSecurityPolicy policy = new ServerSecurityPolicy();
            policy.SecurityPolicyUri = profileUri;

            if (profileUri != null)
            {
                switch (profileUri)
                {
                    case SecurityPolicies.None:
                    {
                        policy.SecurityMode = MessageSecurityMode.None;
                        policy.SecurityLevel = 0;
                        break;
                    }

                    case SecurityPolicies.Basic128Rsa15:
                    {
                        policy.SecurityMode = MessageSecurityMode.SignAndEncrypt;
                        policy.SecurityLevel = 1;
                        break;
                    }

                    case SecurityPolicies.Basic256:
                    {
                        policy.SecurityMode = MessageSecurityMode.SignAndEncrypt;
                        policy.SecurityLevel = 2;
                        break;
                    }
                }
            }

            return policy;
        }
Exemple #16
0
        /// <inheritdoc/>
        /// <summary>
        /// Create a new service host for UA HTTPS.
        /// </summary>
        public List <EndpointDescription> CreateServiceHost(
            ServerBase serverBase,
            IDictionary <string, Task> hosts,
            ApplicationConfiguration configuration,
            IList <string> baseAddresses,
            ApplicationDescription serverDescription,
            List <ServerSecurityPolicy> securityPolicies,
            X509Certificate2 instanceCertificate,
            X509Certificate2Collection instanceCertificateChain
            )
        {
            // generate a unique host name.
            string hostName = String.Empty;

            if (hosts.ContainsKey(hostName))
            {
                hostName = "/Https";
            }

            if (hosts.ContainsKey(hostName))
            {
                hostName += Utils.Format("/{0}", hosts.Count);
            }

            // build list of uris.
            List <Uri> uris = new List <Uri>();
            EndpointDescriptionCollection endpoints = new EndpointDescriptionCollection();

            // create the endpoint configuration to use.
            EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration);
            string computerName = Utils.GetHostName();

            for (int ii = 0; ii < baseAddresses.Count; ii++)
            {
                if (!baseAddresses[ii].StartsWith(Utils.UriSchemeHttps, StringComparison.Ordinal))
                {
                    continue;
                }

                UriBuilder uri = new UriBuilder(baseAddresses[ii]);

                if (uri.Path[uri.Path.Length - 1] != '/')
                {
                    uri.Path += "/";
                }

                if (String.Compare(uri.Host, "localhost", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    uri.Host = computerName;
                }

                uris.Add(uri.Uri);

                if (uri.Scheme == Utils.UriSchemeHttps)
                {
                    // Can only support one policy with HTTPS
                    // So pick the first policy with security mode sign and encrypt
                    ServerSecurityPolicy bestPolicy = null;
                    foreach (ServerSecurityPolicy policy in securityPolicies)
                    {
                        if (policy.SecurityMode != MessageSecurityMode.SignAndEncrypt)
                        {
                            continue;
                        }

                        bestPolicy = policy;
                        break;
                    }

                    // Pick the first policy from the list if no policies with sign and encrypt defined
                    if (bestPolicy == null)
                    {
                        bestPolicy = securityPolicies[0];
                    }

                    EndpointDescription description = new EndpointDescription();

                    description.EndpointUrl = uri.ToString();
                    description.Server      = serverDescription;

                    if (instanceCertificate != null)
                    {
                        description.ServerCertificate = instanceCertificate.RawData;
                        // check if complete chain should be sent.
                        if (configuration.SecurityConfiguration.SendCertificateChain &&
                            instanceCertificateChain != null &&
                            instanceCertificateChain.Count > 0)
                        {
                            List <byte> serverCertificateChain = new List <byte>();

                            for (int i = 0; i < instanceCertificateChain.Count; i++)
                            {
                                serverCertificateChain.AddRange(instanceCertificateChain[i].RawData);
                            }

                            description.ServerCertificate = serverCertificateChain.ToArray();
                        }
                    }

                    description.SecurityMode        = bestPolicy.SecurityMode;
                    description.SecurityPolicyUri   = bestPolicy.SecurityPolicyUri;
                    description.SecurityLevel       = ServerSecurityPolicy.CalculateSecurityLevel(bestPolicy.SecurityMode, bestPolicy.SecurityPolicyUri);
                    description.UserIdentityTokens  = serverBase.GetUserTokenPolicies(configuration, description);
                    description.TransportProfileUri = Profiles.HttpsBinaryTransport;

                    ITransportListener listener = Create();
                    if (listener != null)
                    {
                        endpoints.Add(description);
                        serverBase.CreateServiceHostEndpoint(uri.Uri, endpoints, endpointConfiguration, listener,
                                                             configuration.CertificateValidator.GetChannelValidator());
                    }
                    else
                    {
                        Utils.Trace(Utils.TraceMasks.Error, "Failed to create endpoint {0} because the transport profile is unsupported.", uri);
                    }
                }
            }

            return(endpoints);
        }
Exemple #17
0
        public OpcStackConfiguration(string applicationName)
        {
            // Instead of using a Config.xml we configure everything programmatically.

            //
            // OPC UA Application configuration
            //
            Configuration = new ApplicationConfiguration();
            // Passed in as command line argument
            Configuration.ApplicationName = applicationName;
            Configuration.ApplicationUri  = $"urn:{Utils.GetHostName()}:{Configuration.ApplicationName}:microsoft:";
            Configuration.ProductUri      = "https://github.com/Azure/iot-edge-opc-publisher";
            Configuration.ApplicationType = ApplicationType.ClientAndServer;


            //
            // Security configuration
            //
            Configuration.SecurityConfiguration = new SecurityConfiguration();

            // Application certificate
            Configuration.SecurityConfiguration.ApplicationCertificate             = new CertificateIdentifier();
            Configuration.SecurityConfiguration.ApplicationCertificate.StoreType   = Program.OpcOwnCertStoreType;
            Configuration.SecurityConfiguration.ApplicationCertificate.StorePath   = Program.OpcOwnCertStorePath;
            Configuration.SecurityConfiguration.ApplicationCertificate.SubjectName = Configuration.ApplicationName;
            Trace($"Application Certificate store type is: {Configuration.SecurityConfiguration.ApplicationCertificate.StoreType}");
            Trace($"Application Certificate store path is: {Configuration.SecurityConfiguration.ApplicationCertificate.StorePath}");
            Trace($"Application Certificate subject name is: {Configuration.SecurityConfiguration.ApplicationCertificate.SubjectName}");

            // Use existing certificate, if it is there.
            X509Certificate2 certificate = Configuration.SecurityConfiguration.ApplicationCertificate.Find(true).Result;

            if (certificate == null)
            {
                Trace($"No existing Application certificate found. Create a self-signed Application certificate valid from yesterday for {CertificateFactory.defaultLifeTime} months,");
                Trace($"with a {CertificateFactory.defaultKeySize} bit key and {CertificateFactory.defaultHashSize} bit hash.");
                certificate = CertificateFactory.CreateCertificate(
                    Configuration.SecurityConfiguration.ApplicationCertificate.StoreType,
                    Configuration.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null,
                    Configuration.ApplicationUri,
                    Configuration.ApplicationName,
                    Configuration.ApplicationName,
                    null,
                    CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize,
                    false,
                    null,
                    null
                    );
                Configuration.SecurityConfiguration.ApplicationCertificate.Certificate = certificate ?? throw new Exception("OPC UA application certificate could not be created! Cannot continue without it!");
            }
            else
            {
                Trace("Application certificate found in Application Certificate Store");
            }
            Configuration.ApplicationUri = Utils.GetApplicationUriFromCertificate(certificate);
            Trace($"Application certificate is for Application URI '{Configuration.ApplicationUri}', Application '{Configuration.ApplicationName} and has Subject '{Configuration.ApplicationName}'");

            // TrustedIssuerCertificates
            Configuration.SecurityConfiguration.TrustedIssuerCertificates           = new CertificateTrustList();
            Configuration.SecurityConfiguration.TrustedIssuerCertificates.StoreType = Program.OpcIssuerCertStoreType;
            Configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath = Program.OpcIssuerCertStorePath;
            Trace($"Trusted Issuer store type is: {Configuration.SecurityConfiguration.TrustedIssuerCertificates.StoreType}");
            Trace($"Trusted Issuer Certificate store path is: {Configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath}");

            // TrustedPeerCertificates
            Configuration.SecurityConfiguration.TrustedPeerCertificates           = new CertificateTrustList();
            Configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType = Program.OpcTrustedCertStoreType;
            if (string.IsNullOrEmpty(Program.OpcTrustedCertStorePath))
            {
                // Set default.
                Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = Program.OpcTrustedCertStoreType == CertificateStoreType.X509Store ? Program.OpcTrustedCertX509StorePathDefault : Program.OpcTrustedCertDirectoryStorePathDefault;
                if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_TPC_SP")))
                {
                    // Use environment variable.
                    Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = Environment.GetEnvironmentVariable("_TPC_SP");
                }
            }
            else
            {
                Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath = Program.OpcTrustedCertStorePath;
            }
            Trace($"Trusted Peer Certificate store type is: {Configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType}");
            Trace($"Trusted Peer Certificate store path is: {Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");

            // RejectedCertificateStore
            Configuration.SecurityConfiguration.RejectedCertificateStore           = new CertificateTrustList();
            Configuration.SecurityConfiguration.RejectedCertificateStore.StoreType = Program.OpcRejectedCertStoreType;
            Configuration.SecurityConfiguration.RejectedCertificateStore.StorePath = Program.OpcRejectedCertStorePath;
            Trace($"Rejected certificate store type is: {Configuration.SecurityConfiguration.RejectedCertificateStore.StoreType}");
            Trace($"Rejected Certificate store path is: {Configuration.SecurityConfiguration.RejectedCertificateStore.StorePath}");

            // AutoAcceptUntrustedCertificates
            // This is a security risk and should be set to true only for debugging purposes.
            Configuration.SecurityConfiguration.AutoAcceptUntrustedCertificates = false;

            // RejectSHA1SignedCertificates
            // We allow SHA1 certificates for now as many OPC Servers still use them
            Configuration.SecurityConfiguration.RejectSHA1SignedCertificates = false;
            Trace($"Rejection of SHA1 signed certificates is {(Configuration.SecurityConfiguration.RejectSHA1SignedCertificates ? "enabled" : "disabled")}");

            // MinimunCertificatesKeySize
            // We allow a minimum key size of 1024 bit, as many OPC UA servers still use them
            Configuration.SecurityConfiguration.MinimumCertificateKeySize = 1024;
            Trace($"Minimum certificate key size set to {Configuration.SecurityConfiguration.MinimumCertificateKeySize}");

            // We make the default reference stack behavior configurable to put our own certificate into the trusted peer store.
            if (Program.TrustMyself)
            {
                // Ensure it is trusted
                try
                {
                    ICertificateStore store = Configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();
                    if (store == null)
                    {
                        Trace($"Could not open trusted peer store. StorePath={Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");
                    }
                    else
                    {
                        try
                        {
                            Trace($"Adding publisher certificate to trusted peer store. StorePath={Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");
                            X509Certificate2 publicKey = new X509Certificate2(certificate.RawData);
                            store.Add(publicKey).Wait();
                        }
                        finally
                        {
                            store.Close();
                        }
                    }
                }
                catch (Exception e)
                {
                    Trace(e, $"Could not add publisher certificate to trusted peer store. StorePath={Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");
                }
            }
            else
            {
                Trace("Publisher certificate is not added to trusted peer store.");
            }


            //
            // TransportConfigurations
            //

            Configuration.TransportQuotas = new TransportQuotas();
            // the OperationTimeout should be twice the minimum value for PublishingInterval * KeepAliveCount, so set to 120s
            Configuration.TransportQuotas.OperationTimeout = Program.OpcOperationTimeout;
            Trace($"OperationTimeout set to {Configuration.TransportQuotas.OperationTimeout}");


            //
            // ServerConfiguration
            //
            Configuration.ServerConfiguration = new ServerConfiguration();

            // BaseAddresses
            if (Configuration.ServerConfiguration.BaseAddresses.Count == 0)
            {
                // We do not use the localhost replacement mechanism of the configuration loading, to immediately show the base address here
                Configuration.ServerConfiguration.BaseAddresses.Add($"opc.tcp://{Utils.GetHostName()}:{Program.PublisherServerPort}{Program.PublisherServerPath}");
            }
            foreach (var endpoint in Configuration.ServerConfiguration.BaseAddresses)
            {
                Trace($"Publisher server base address: {endpoint}");
            }

            // SecurityPolicies
            // We do not allow security policy SecurityPolicies.None, but always high security
            ServerSecurityPolicy newPolicy = new ServerSecurityPolicy()
            {
                SecurityMode      = MessageSecurityMode.SignAndEncrypt,
                SecurityPolicyUri = SecurityPolicies.Basic256Sha256
            };

            Configuration.ServerConfiguration.SecurityPolicies.Add(newPolicy);
            Trace($"Security policy {newPolicy.SecurityPolicyUri} with mode {newPolicy.SecurityMode} added");

            // MaxRegistrationInterval
            Configuration.ServerConfiguration.MaxRegistrationInterval = Program.LdsRegistrationInterval;
            Trace($"LDS(-ME) registration intervall set to {Program.LdsRegistrationInterval} ms (0 means no registration)");

            //
            // TraceConfiguration
            //
            Configuration.TraceConfiguration = new TraceConfiguration();
            // Due to a bug in a stack we need to do console output ourselve.
            Utils.SetTraceOutput(Utils.TraceOutput.FileOnly);

            // OutputFilePath
            if (string.IsNullOrEmpty(Program.LogFileName))
            {
                if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_LOGP")))
                {
                    Configuration.TraceConfiguration.OutputFilePath = Environment.GetEnvironmentVariable("_GW_LOGP");
                }
                else
                {
                    Configuration.TraceConfiguration.OutputFilePath = "./Logs/" + Configuration.ApplicationName + ".log.txt";
                }
            }
            else
            {
                Configuration.TraceConfiguration.OutputFilePath = Program.LogFileName;
            }

            // DeleteOnLoad
            Configuration.TraceConfiguration.DeleteOnLoad = false;

            // TraceMasks
            Configuration.TraceConfiguration.TraceMasks = Program.OpcStackTraceMask;

            // Apply the settings
            Configuration.TraceConfiguration.ApplySettings();
            Trace($"Current directory is: {Directory.GetCurrentDirectory()}");
            Trace($"Log file is: {Utils.GetAbsoluteFilePath(Configuration.TraceConfiguration.OutputFilePath, true, false, false, true)}");
            Trace($"opcstacktracemask set to: 0x{Program.OpcStackTraceMask:X} ({Program.OpcStackTraceMask})");

            Configuration.ClientConfiguration = new ClientConfiguration();

            // validate the configuration now
            Configuration.Validate(Configuration.ApplicationType).Wait();
        }