コード例 #1
0
        public virtual async Task <X509Certificate2> SigningRequestAsync(
            ApplicationRecordDataType application,
            string[] domainNames,
            byte[] certificateRequest)
        {
            try
            {
                var pkcs10CertificationRequest = new Org.BouncyCastle.Pkcs.Pkcs10CertificationRequest(certificateRequest);

                if (!pkcs10CertificationRequest.Verify())
                {
                    throw new ServiceResultException(StatusCodes.BadInvalidArgument, "CSR signature invalid.");
                }

                var info             = pkcs10CertificationRequest.GetCertificationRequestInfo();
                var altNameExtension = GetAltNameExtensionFromCSRInfo(info);
                if (altNameExtension != null)
                {
                    if (altNameExtension.Uris.Count > 0)
                    {
                        if (!altNameExtension.Uris.Contains(application.ApplicationUri))
                        {
                            throw new ServiceResultException(StatusCodes.BadCertificateUriInvalid,
                                                             "CSR AltNameExtension does not match " + application.ApplicationUri);
                        }
                    }

                    if (altNameExtension.IPAddresses.Count > 0 || altNameExtension.DomainNames.Count > 0)
                    {
                        var domainNameList = new List <string>();
                        domainNameList.AddRange(altNameExtension.DomainNames);
                        domainNameList.AddRange(altNameExtension.IPAddresses);
                        domainNames = domainNameList.ToArray();
                    }
                }

                DateTime yesterday = DateTime.UtcNow.AddDays(-1);
                using (var signingKey = await LoadSigningKeyAsync(Certificate, string.Empty))
                {
                    return(CertificateFactory.CreateCertificate(
                               null, null, null,
                               application.ApplicationUri ?? "urn:ApplicationURI",
                               application.ApplicationNames.Count > 0 ? application.ApplicationNames[0].Text : "ApplicationName",
                               info.Subject.ToString(),
                               domainNames,
                               Configuration.DefaultCertificateKeySize,
                               yesterday,
                               Configuration.DefaultCertificateLifetime,
                               Configuration.DefaultCertificateHashSize,
                               false,
                               signingKey,
                               info.SubjectPublicKeyInfo.GetEncoded()));
                }
            }
            catch (Exception ex)
            {
                if (ex is ServiceResultException)
                {
                    throw ex as ServiceResultException;
                }
                throw new ServiceResultException(StatusCodes.BadInvalidArgument, ex.Message);
            }
        }
コード例 #2
0
 private X509Certificate2 GetTestCert()
 {
     return(m_testCertificate ??
            (m_testCertificate = CertificateFactory.CreateCertificate(X509StoreSubject).CreateForRSA()));
 }
コード例 #3
0
        /// <summary>
        /// Validates the identity token supplied by the client.
        /// </summary>
        private UserIdentityToken ValidateUserIdentityToken(
            ExtensionObject identityToken,
            SignatureData userTokenSignature,
            out UserTokenPolicy policy)
        {
            policy = null;

            // check for empty token.
            if (identityToken == null || identityToken.Body == null ||
                identityToken.Body.GetType() == typeof(Opc.Ua.AnonymousIdentityToken))
            {
                // check if an anonymous login is permitted.
                if (m_endpoint.UserIdentityTokens != null && m_endpoint.UserIdentityTokens.Count > 0)
                {
                    bool found = false;

                    for (int ii = 0; ii < m_endpoint.UserIdentityTokens.Count; ii++)
                    {
                        if (m_endpoint.UserIdentityTokens[ii].TokenType == UserTokenType.Anonymous)
                        {
                            found  = true;
                            policy = m_endpoint.UserIdentityTokens[ii];
                            break;
                        }
                    }

                    if (!found)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Anonymous user token policy not supported.");
                    }
                }

                // create an anonymous token to use for subsequent validation.
                AnonymousIdentityToken anonymousToken = new AnonymousIdentityToken();
                anonymousToken.PolicyId = policy.PolicyId;
                return(anonymousToken);
            }

            UserIdentityToken token = null;

            // check for unrecognized token.
            if (!typeof(UserIdentityToken).IsInstanceOfType(identityToken.Body))
            {
                //handle the use case when the UserIdentityToken is binary encoded over xml message encoding
                if (identityToken.Encoding == ExtensionObjectEncoding.Binary && typeof(byte[]).IsInstanceOfType(identityToken.Body))
                {
                    UserIdentityToken newToken = BaseVariableState.DecodeExtensionObject(null, typeof(UserIdentityToken), identityToken, false) as UserIdentityToken;
                    if (newToken == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Invalid user identity token provided.");
                    }

                    policy = m_endpoint.FindUserTokenPolicy(newToken.PolicyId);
                    if (policy == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "User token policy not supported.", "Opc.Ua.Server.Session.ValidateUserIdentityToken");
                    }
                    switch (policy.TokenType)
                    {
                    case UserTokenType.Anonymous:
                        token = BaseVariableState.DecodeExtensionObject(null, typeof(AnonymousIdentityToken), identityToken, true) as AnonymousIdentityToken;
                        break;

                    case UserTokenType.UserName:
                        token = BaseVariableState.DecodeExtensionObject(null, typeof(UserNameIdentityToken), identityToken, true) as UserNameIdentityToken;
                        break;

                    case UserTokenType.Certificate:
                        token = BaseVariableState.DecodeExtensionObject(null, typeof(X509IdentityToken), identityToken, true) as X509IdentityToken;
                        break;

                    case UserTokenType.IssuedToken:
                        token = BaseVariableState.DecodeExtensionObject(null, typeof(IssuedIdentityToken), identityToken, true) as IssuedIdentityToken;
                        break;

                    default:
                        throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Invalid user identity token provided.");
                    }
                }
                else
                {
                    throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Invalid user identity token provided.");
                }
            }
            else
            {
                // get the token.
                token = (UserIdentityToken)identityToken.Body;
            }

            // find the user token policy.
            policy = m_endpoint.FindUserTokenPolicy(token.PolicyId);

            if (policy == null)
            {
                throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, "User token policy not supported.");
            }

            if (token is IssuedIdentityToken issuedToken)
            {
                if (policy.IssuedTokenType == Profiles.JwtUserToken)
                {
                    issuedToken.IssuedTokenType = IssuedTokenType.JWT;
                }
            }

            // determine the security policy uri.
            string securityPolicyUri = policy.SecurityPolicyUri;

            if (String.IsNullOrEmpty(securityPolicyUri))
            {
                securityPolicyUri = m_endpoint.SecurityPolicyUri;
            }

            if (ServerBase.RequireEncryption(m_endpoint))
            {
                // decrypt the token.
                if (m_serverCertificate == null)
                {
                    m_serverCertificate = CertificateFactory.Create(m_endpoint.ServerCertificate, true);

                    // check for valid certificate.
                    if (m_serverCertificate == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "ApplicationCertificate cannot be found.");
                    }
                }

                try
                {
                    token.Decrypt(m_serverCertificate, m_serverNonce, securityPolicyUri);
                }
                catch (Exception e)
                {
                    if (e is ServiceResultException)
                    {
                        throw;
                    }

                    throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, e, "Could not decrypt identity token.");
                }

                // verify the signature.
                if (securityPolicyUri != SecurityPolicies.None)
                {
                    byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce);

                    if (!token.Verify(dataToSign, userTokenSignature, securityPolicyUri))
                    {
                        // verify for certificate chain in endpoint.
                        // validate the signature with complete chain if the check with leaf certificate failed.
                        X509Certificate2Collection serverCertificateChain = Utils.ParseCertificateChainBlob(m_endpoint.ServerCertificate);

                        if (serverCertificateChain.Count > 1)
                        {
                            List <byte> serverCertificateChainList = new List <byte>();

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

                            byte[] serverCertificateChainData = serverCertificateChainList.ToArray();
                            dataToSign = Utils.Append(serverCertificateChainData, m_serverNonce);

                            if (!token.Verify(dataToSign, userTokenSignature, securityPolicyUri))
                            {
                                throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected, "Invalid user signature!");
                            }
                        }
                        else
                        {
                            throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected, "Invalid user signature!");
                        }
                    }
                }
            }

            // validate user identity token.
            return(token);
        }
コード例 #4
0
 public override IXmlSigner GetSigner(SignatureLocation signatureLocation = SignatureLocation.Enveloped) => new RsaXmlSigner(CertificateFactory.GetSigningSha256Certificate())
 {
     SignatureLocation = signatureLocation
 };                                                                                                                                                         // SHA1 also works with this cert
コード例 #5
0
        public virtual async Task <X509Certificate2> SigningRequestAsync(
            ApplicationRecordDataType application,
            string[] domainNames,
            byte[] certificateRequest)
        {
            try
            {
                var pkcs10CertificationRequest = new Org.BouncyCastle.Pkcs.Pkcs10CertificationRequest(certificateRequest);

                if (!pkcs10CertificationRequest.Verify())
                {
                    throw new ServiceResultException(StatusCodes.BadInvalidArgument, "CSR signature invalid.");
                }

                var info             = pkcs10CertificationRequest.GetCertificationRequestInfo();
                var altNameExtension = GetAltNameExtensionFromCSRInfo(info);
                if (altNameExtension != null)
                {
                    if (altNameExtension.Uris.Count > 0)
                    {
                        if (!altNameExtension.Uris.Contains(application.ApplicationUri))
                        {
                            throw new ServiceResultException(StatusCodes.BadCertificateUriInvalid,
                                                             "CSR AltNameExtension does not match " + application.ApplicationUri);
                        }
                    }

                    if (altNameExtension.IPAddresses.Count > 0 || altNameExtension.DomainNames.Count > 0)
                    {
                        var domainNameList = new List <string>();
                        domainNameList.AddRange(altNameExtension.DomainNames);
                        domainNameList.AddRange(altNameExtension.IPAddresses);
                        domainNames = domainNameList.ToArray();
                    }
                }

                DateTime yesterday = DateTime.Today.AddDays(-1);
                using (var signingKey = await LoadSigningKeyAsync(Certificate, string.Empty).ConfigureAwait(false))
                {
                    return(CertificateFactory.CreateCertificate(
                               application.ApplicationUri,
                               null,
                               info.Subject.ToString(),
                               domainNames)
                           .SetNotBefore(yesterday)
                           .SetLifeTime(Configuration.DefaultCertificateLifetime)
                           .SetHashAlgorithm(X509Utils.GetRSAHashAlgorithmName(Configuration.DefaultCertificateHashSize))
                           .SetIssuer(signingKey)
                           .SetRSAPublicKey(info.SubjectPublicKeyInfo.GetEncoded())
                           .CreateForRSA());
                }
            }
            catch (Exception ex)
            {
                if (ex is ServiceResultException)
                {
                    throw ex as ServiceResultException;
                }
                throw new ServiceResultException(StatusCodes.BadInvalidArgument, ex.Message);
            }
        }
コード例 #6
0
        /// <summary>
        /// Creates a cert with the connectionstring (token) and stores it in the given cert store.
        /// </summary>
        public async static Task WriteAsync(string name, string connectionString, string storeType, string storePath)
        {
            if (string.IsNullOrEmpty(connectionString))
            {
                throw new ArgumentException("Token not found in X509Store and no new token provided!");
            }

            SecureRandom random = new SecureRandom();
            KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, 2048);
            RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();
            keyPairGenerator.Init(keyGenerationParameters);
            AsymmetricCipherKeyPair keys = keyPairGenerator.GenerateKeyPair();

            ArrayList nameOids = new ArrayList();
            nameOids.Add(X509Name.CN);
            ArrayList nameValues = new ArrayList();
            nameValues.Add(name);
            X509Name subjectDN = new X509Name(nameOids, nameValues);
            X509Name issuerDN = subjectDN;

            X509V3CertificateGenerator cg = new X509V3CertificateGenerator();
            cg.SetSerialNumber(BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random));
            cg.SetIssuerDN(issuerDN);
            cg.SetSubjectDN(subjectDN);
            cg.SetNotBefore(DateTime.Now);
            cg.SetNotAfter(DateTime.Now.AddMonths(12));
            cg.SetPublicKey(keys.Public);
            cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DataEncipherment));

            // encrypt the token with the public key so only the owner of the assoc. private key can decrypt it and
            // "hide" it in the instruction code cert extension
            RSA rsa = RSA.Create();
            RSAParameters rsaParams = new RSAParameters();
            RsaKeyParameters keyParams = (RsaKeyParameters)keys.Public;

            rsaParams.Modulus = new byte[keyParams.Modulus.ToByteArrayUnsigned().Length];
            keyParams.Modulus.ToByteArrayUnsigned().CopyTo(rsaParams.Modulus, 0);

            rsaParams.Exponent = new byte[keyParams.Exponent.ToByteArrayUnsigned().Length];
            keyParams.Exponent.ToByteArrayUnsigned().CopyTo(rsaParams.Exponent, 0);

            rsa.ImportParameters(rsaParams);
            if (rsa != null)
            {
                byte[] bytes = rsa.Encrypt(Encoding.ASCII.GetBytes(connectionString), RSAEncryptionPadding.OaepSHA1);
                if (bytes != null)
                {
                    cg.AddExtension(X509Extensions.InstructionCode, false, bytes);
                }
                else
                {
                    throw new CryptographicException("Can not encrypt IoTHub security token using generated public key!");
                }
            }

            // sign the cert with the private key
            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", keys.Private, random);
            Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory);

            // create a PKCS12 store for the cert and its private key
            X509Certificate2 certificate = null;
            using (MemoryStream pfxData = new MemoryStream())
            {
                Pkcs12StoreBuilder builder = new Pkcs12StoreBuilder();
                builder.SetUseDerEncoding(true);
                Pkcs12Store pkcsStore = builder.Build();
                X509CertificateEntry[] chain = new X509CertificateEntry[1];
                string passcode = Guid.NewGuid().ToString();
                chain[0] = new X509CertificateEntry(x509);
                pkcsStore.SetKeyEntry(name, new AsymmetricKeyEntry(keys.Private), chain);
                pkcsStore.Save(pfxData, passcode.ToCharArray(), random);

                // create X509Certificate2 object from PKCS12 file
                certificate = CertificateFactory.CreateCertificateFromPKCS12(pfxData.ToArray(), passcode);

                // handle each store type differently
                switch (storeType)
                {
                    case CertificateStoreType.Directory:
                        {
                            // Add to DirectoryStore
                            using (DirectoryCertificateStore store = new DirectoryCertificateStore())
                            {
                                store.Open(storePath);
                                X509CertificateCollection certificates = await store.Enumerate().ConfigureAwait(false);

                                // remove any existing cert with our name from the store
                                foreach (X509Certificate2 cert in certificates)
                                {
                                    if (cert.SubjectName.Decode(X500DistinguishedNameFlags.None | X500DistinguishedNameFlags.DoNotUseQuotes).Equals("CN=" + name, StringComparison.OrdinalIgnoreCase))
                                    {
                                        await store.Delete(cert.Thumbprint).ConfigureAwait(false);
                                    }
                                }

                                // add new one
                                await store.Add(certificate).ConfigureAwait(false);
                            }
                            break;
                        }
                    case CertificateStoreType.X509Store:
                        {
                            // Add to X509Store
                            using (X509Store store = new X509Store(storePath, StoreLocation.CurrentUser))
                            {
                                store.Open(OpenFlags.ReadWrite);

                                // remove any existing cert with our name from the store
                                foreach (X509Certificate2 cert in store.Certificates)
                                {
                                    if (cert.SubjectName.Decode(X500DistinguishedNameFlags.None | X500DistinguishedNameFlags.DoNotUseQuotes).Equals("CN=" + name, StringComparison.OrdinalIgnoreCase))
                                    {
                                        store.Remove(cert);
                                    }
                                }

                                // add new cert to store
                                try
                                {
                                    store.Add(certificate);
                                }
                                catch (Exception e)
                                {
                                    throw new Exception($"Not able to add cert to the requested store type '{storeType}' (exception message: '{e.Message}'.");
                                }
                            }
                            break;
                        }
                    default:
                        {
                            throw new Exception($"The requested store type '{storeType}' is not supported. Please change.");
                        }
                }
                return;
            }
        }
コード例 #7
0
        public async void CreateCertificate(AssetManager assets)
        {
            ApplicationInstance application = new ApplicationInstance
            {
                ApplicationType   = ApplicationType.Client,
                ConfigSectionName = "Opc.Ua.AIS_Demonstrator"   /// [...] sets the name of the config section containing the path to the application configuration file.
            };

            /*
             * // Old code to find location of config.xml file + load its content into "context" variable.
             * // Instead, the CreateCertificate Variable is now called with the content string as a parameter since the AssetManager needs to be instantiated in an Activity
             * string currentFolder = DependencyService.Get<IPathService>().PublicExternalFolder.ToString();
             * string filename = application.ConfigSectionName + ".Config.xml";
             * string content = DependencyService.Get<IAssetService>().LoadFile(filename);
             * File.WriteAllText(currentFolder + filename, content);
             */

            // new code to find location of config.xml file + load its content into "context" variable
            // the CreateCertificate Variable is now called with the content string as a parameter since the AssetManager needs to be instantiated in an Activity
            string configFilename     = application.ConfigSectionName + ".Config.xml";
            string serverCertFilename = "server_selfsigned_cert_2048.pem";
            string clientCertFilename = "client_selfsigned_cert_2048.pem";
            string currentFolder      = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // gets the path of the Internal Storage as a string
            string PKIPath            = "/storage/emulated/0/OPC Foundation/PKI/";

            Directory.CreateDirectory(PKIPath + "trusted/");
            Directory.CreateDirectory(PKIPath + "own/");
            ServerCertPath = PKIPath + "trusted/" + serverCertFilename;
            ClientCertPath = PKIPath + "own/" + clientCertFilename;
            configPath     = currentFolder + configFilename;

            // in case the config file doesn't exist: create new config file in internal storage as a copy of the Asset config
            if (!File.Exists(currentFolder + configFilename))
            {
                string content;
                using (StreamReader sr = new StreamReader(assets.Open(configFilename)))
                {
                    content = sr.ReadToEnd();
                }
                File.WriteAllText(currentFolder + configFilename, content);
            }
            else
            {   // The config file already exists
                // Load configuration from file
                config = await application.LoadApplicationConfiguration(currentFolder + configFilename, false);
            }

            // in case the server certificate file doesn't exist: create new certificate file in internal storage as a copy of the Asset server certificate
            if (!File.Exists(ServerCertPath))
            {
                assets.Open(serverCertFilename).CopyTo(File.Create(ServerCertPath));

                /* string content;
                 * using (StreamReader sr = new StreamReader(assets.Open(serverCertFilename)))
                 * {
                 *  content = sr.ReadToEnd();
                 * }
                 * File.WriteAllText(ServerCertPath, content);*/
            }



            // check the application certificate.
            haveAppCertificate = await application.CheckApplicationInstanceCertificate(false, 0);

            // haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;   // ToDo Delete this line or the one above

            // Create a new app certificate if no certificate is present
            if (!haveAppCertificate)
            {
                X509Certificate2 appCertificate = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,          // string storeType
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,          // string storePath
                    null,                                                                   // string password
                    config.ApplicationUri,                                                  // string applicationUri
                    config.ApplicationName,                                                 // string applicationName
                    config.SecurityConfiguration.ApplicationCertificate.SubjectName,        // string subjectName
                    null,                                                                   // IList<string> domainNames
                    2048,                                                                   // ushort KeySize
                    DateTime.UtcNow - TimeSpan.FromDays(1),                                 // DateTime startDate
                    24,                                                                     // ushort lifetimeInMonths
                    256,                                                                    // ushort hashSizeInBits
                    false,                                                                  // bool isCA; default = false
                    null,                                                                   // X509certificate2 issuerCACertKey
                    null                                                                    // byte[] publicKey; default = null
                    );

                config.SecurityConfiguration.ApplicationCertificate.Certificate = appCertificate;
            }

            if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);

                config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
            }
        }
コード例 #8
0
        public static async Task ConsoleSampleClient(string endpointURL, int timeOut, bool autoAccept)
        {
            Console.WriteLine("1 - Create an Application Configuration.");
            exitCode = ExitCode.ErrorCreateApplication;

            Utils.SetTraceOutput(Utils.TraceOutput.DebugAndFile);
            var config = new ApplicationConfiguration()
            {
                ApplicationName       = "UA Core Sample Client",
                ApplicationType       = ApplicationType.Client,
                ApplicationUri        = "urn:" + Utils.GetHostName() + ":OPCFoundation:CoreSampleClient",
                SecurityConfiguration = new SecurityConfiguration
                {
                    ApplicationCertificate = new CertificateIdentifier
                    {
                        StoreType   = "X509Store",
                        StorePath   = "CurrentUser\\My",
                        SubjectName = "UA Core Sample Client"
                    },
                    TrustedPeerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Applications",
                    },
                    TrustedIssuerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities",
                    },
                    RejectedCertificateStore = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/RejectedCertificates",
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = autoAccept
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas         = new TransportQuotas {
                    OperationTimeout = 15000
                },
                ClientConfiguration = new ClientConfiguration {
                    DefaultSessionTimeout = 60000
                }
            };

            await config.Validate(ApplicationType.Client);

            bool haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (!haveAppCertificate)
            {
                Console.WriteLine("    INFO: Creating new application certificate: {0}", config.ApplicationName);

                X509Certificate2 certificate = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null,
                    config.ApplicationUri,
                    config.ApplicationName,
                    config.SecurityConfiguration.ApplicationCertificate.SubjectName,
                    null,
                    CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize,
                    false,
                    null,
                    null
                    );

                config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            }

            haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);

                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
                }
            }
            else
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecure connection.");
            }

            Console.WriteLine("2 - Discover endpoints of {0}.", endpointURL);
            exitCode = ExitCode.ErrorDiscoverEndpoints;
            var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointURL, haveAppCertificate, 15000);

            Console.WriteLine("    Selected endpoint uses: {0}",
                              selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1));

            Console.WriteLine("3 - Create a session with OPC UA server.");
            exitCode = ExitCode.ErrorCreateSession;
            var endpointConfiguration = EndpointConfiguration.Create(config);
            var endpoint = new ConfiguredEndpoint(null, selectedEndpoint, endpointConfiguration);
            var session  = await Session.Create(config, endpoint, false, ".Net Core OPC UA Console Client", 60000, new UserIdentity(new AnonymousIdentityToken()), null);

            Console.WriteLine("4 - Browse the OPC UA server namespace.");
            exitCode = ExitCode.ErrorBrowseNamespace;
            ReferenceDescriptionCollection references;

            Byte[] continuationPoint;

            references = session.FetchReferences(ObjectIds.ObjectsFolder);

            session.Browse(
                null,
                null,
                ObjectIds.ObjectsFolder,
                0u,
                BrowseDirection.Forward,
                ReferenceTypeIds.HierarchicalReferences,
                true,
                (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                out continuationPoint,
                out references);

            Console.WriteLine(" DisplayName, BrowseName, NodeClass");
            foreach (var rd in references)
            {
                Console.WriteLine(" {0}, {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass);
                ReferenceDescriptionCollection nextRefs;
                byte[] nextCp;
                session.Browse(
                    null,
                    null,
                    ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris),
                    0u,
                    BrowseDirection.Forward,
                    ReferenceTypeIds.HierarchicalReferences,
                    true,
                    (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                    out nextCp,
                    out nextRefs);

                foreach (var nextRd in nextRefs)
                {
                    Console.WriteLine("   + {0}, {1}, {2}", nextRd.DisplayName, nextRd.BrowseName, nextRd.NodeClass);
                }
            }

            Console.WriteLine("5 - Create a subscription with publishing interval of 1 second.");
            exitCode = ExitCode.ErrorCreateSubscription;
            var subscription = new Subscription(session.DefaultSubscription)
            {
                PublishingInterval = 1000
            };

            Console.WriteLine("6 - Add a list of items (server current time and status) to the subscription.");
            exitCode = ExitCode.ErrorMonitoredItem;
            var list = new List <MonitoredItem> {
                new MonitoredItem(subscription.DefaultItem)
                {
                    DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=" + Variables.Server_ServerStatus_CurrentTime.ToString()
                }
            };

            list.ForEach(i => i.Notification += OnNotification);
            subscription.AddItems(list);

            Console.WriteLine("7 - Add the subscription to the session.");
            exitCode = ExitCode.ErrorAddSubscription;
            session.AddSubscription(subscription);
            subscription.Create();

            Console.WriteLine("8 - Running...Press Ctrl-C to exit...");
            exitCode = ExitCode.ErrorRunning;

            ManualResetEvent quitEvent = new ManualResetEvent(false);

            try
            {
                Console.CancelKeyPress += (sender, eArgs) =>
                {
                    quitEvent.Set();
                    eArgs.Cancel = true;
                };
            }
            catch
            {
            }

            // wait for timeout or Ctrl-C
            quitEvent.WaitOne(timeOut);

            // return error conditions
            if (session.KeepAliveStopped)
            {
                exitCode = ExitCode.ErrorNoKeepAlive;
                return;
            }
            exitCode = ExitCode.Ok;
        }
コード例 #9
0
        private HttpMessageHandler CreateClientHandler()
        {
            var clusterOptions = _context.ClusterOptions;

            if (clusterOptions.IsCapella && !clusterOptions.EffectiveEnableTls)
            {
                _logger.LogWarning("TLS is required when connecting to Couchbase Capella. Please enable TLS by prefixing the connection string with \"couchbases://\" (note the final 's').");
            }

#if !NETCOREAPP3_1_OR_GREATER
            var handler = new HttpClientHandler();

            //for x509 cert authentication
            if (_context.ClusterOptions.X509CertificateFactory != null)
            {
                handler.ClientCertificateOptions = ClientCertificateOption.Manual;
                handler.SslProtocols             = _context.ClusterOptions.EnabledSslProtocols;
                handler.ClientCertificates.AddRange(_context.ClusterOptions.X509CertificateFactory.GetCertificates());
            }

            try
            {
                handler.CheckCertificateRevocationList            = _context.ClusterOptions.EnableCertificateRevocation;
                handler.ServerCertificateCustomValidationCallback =
                    CreateCertificateValidator(_context.ClusterOptions);
            }
            catch (PlatformNotSupportedException)
            {
                _logger.LogDebug(
                    "Cannot set ServerCertificateCustomValidationCallback, not supported on this platform");
            }
            catch (NotImplementedException)
            {
                _logger.LogDebug(
                    "Cannot set ServerCertificateCustomValidationCallback, not implemented on this platform");
            }
#else
            var handler = new SocketsHttpHandler();

            //for x509 cert authentication
            if (_context.ClusterOptions.X509CertificateFactory != null)
            {
                handler.SslOptions.EnabledSslProtocols = _context.ClusterOptions.EnabledSslProtocols;

                var certificates = _context.ClusterOptions.X509CertificateFactory.GetCertificates();
                handler.SslOptions.ClientCertificates = certificates;

                // This emulates the behavior of HttpClientHandler in Manual mode, which selects the first certificate
                // from the list which is eligible for use as a client certificate based on having a private key and
                // the correct key usage flags.
                handler.SslOptions.LocalCertificateSelectionCallback =
                    (_, _, _, _, _) => GetClientCertificate(certificates) !;
            }

            // We don't need to check for unsupported platforms here, because this code path only applies to recent
            // versions of .NET which all support certificate validation callbacks
            handler.SslOptions.CertificateRevocationCheckMode = _context.ClusterOptions.EnableCertificateRevocation
                ? X509RevocationMode.Online
                : X509RevocationMode.NoCheck;

            RemoteCertificateValidationCallback?certValidationCallback = _context.ClusterOptions.HttpCertificateCallbackValidation;
            if (certValidationCallback == null)
            {
                certValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
                {
                    if (_context.ClusterOptions.HttpIgnoreRemoteCertificateMismatch &&
                        CertificateFactory.ValidatorWithIgnoreNameMismatch(sender, certificate, chain, sslPolicyErrors))
                    {
                        return(true);
                    }

                    return(CertificateFactory.ValidateWithDefaultCertificates(sender, certificate, chain, sslPolicyErrors));
                };
            }

            handler.SslOptions.RemoteCertificateValidationCallback = certValidationCallback;

            if (_context.ClusterOptions.EnabledTlsCipherSuites.Count > 0)
            {
                handler.SslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(_context.ClusterOptions.EnabledTlsCipherSuites);
            }

            if (_context.ClusterOptions.IdleHttpConnectionTimeout > TimeSpan.Zero)
            {
                //https://issues.couchbase.com/browse/MB-37032
                handler.PooledConnectionIdleTimeout = _context.ClusterOptions.IdleHttpConnectionTimeout;
            }

            if (_context.ClusterOptions.HttpConnectionLifetime > TimeSpan.Zero)
            {
                handler.PooledConnectionLifetime = _context.ClusterOptions.HttpConnectionLifetime;
            }
#endif

#if NET5_0_OR_GREATER
            if (_context.ClusterOptions.EnableTcpKeepAlives)
            {
                handler.KeepAlivePingDelay   = _context.ClusterOptions.TcpKeepAliveInterval;
                handler.KeepAlivePingTimeout = _context.ClusterOptions.TcpKeepAliveTime;
                handler.KeepAlivePingPolicy  = HttpKeepAlivePingPolicy.Always;
            }
#endif
            try
            {
                if (_context.ClusterOptions.MaxHttpConnections > 0)
                {
                    //0 means the WinHttpHandler default size of Int.MaxSize is used
                    handler.MaxConnectionsPerServer = _context.ClusterOptions.MaxHttpConnections;
                }
            }
            catch (PlatformNotSupportedException e)
            {
                _logger.LogDebug(e, "Cannot set MaxConnectionsPerServer, not supported on this platform");
            }

            var authenticatingHandler = _context.ClusterOptions.X509CertificateFactory == null
                ? (HttpMessageHandler) new AuthenticatingHttpMessageHandler(handler, _context)
                : handler;

            return(authenticatingHandler);
        }
コード例 #10
0
 public void InitializeSignerNullCertTest()
 {
     new EncryptedNewKeySignedXmlCipher(CertificateFactory.GetDecryptingCertificate());
 }
コード例 #11
0
 public override IXmlCipher GetCipher() => new EncryptedNewKeySignedXmlCipher(
     CertificateFactory.GetDecryptingCertificate(),
     CertificateFactory.GetSigningCertificate());                                                 // default SHA1, SHA256 doesn't work here
コード例 #12
0
 public void NullSignCertGetCipherTest()
 {
     new EncryptedNewKeySignedXmlCipher(
         CertificateFactory.GetDecryptingCertificate(),
         null);     // default SHA1, SHA256 doesn't work here
 }
コード例 #13
0
            CertificateFactory.GetSigningCertificate());                                                 // default SHA1, SHA256 doesn't work here

        public IXmlCipher GetPublicCertCipher() => new EncryptedNewKeySignedXmlCipher(
            CertificateFactory.GetEncryptingCertificate(),
            CertificateFactory.GetSignVerifyCertificate());                                                 // default SHA1, SHA256 doesn't work here
コード例 #14
0
        public static X509Certificate ConvertCertificate(X509Certificate2 certificate)
        {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");

            return((X509Certificate)cf.generateCertificate(new ByteArrayInputStream(certificate.RawData)));
        }
コード例 #15
0
        private async void CertificateRequestTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                NodeId requestId = NodeId.Parse(m_application.CertificateRequestId);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                    m_certificate = newCert;
                }
                else
                {
#if TODO_SERVERPUSH
                    if (privateKeyPFX != null && privateKeyPFX.Length > 0)
                    {
                        var x509 = new X509Certificate2(privateKeyPFX, m_certificatePassword, X509KeyStorageFlags.Exportable);
                        privateKeyPFX = x509.Export(X509ContentType.Pfx);
                    }
                    bool applyChanges = m_server.UpdateCertificate(null, null, certificate, GetPrivateKeyFormat(), privateKeyPFX, issuerCertificates);

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

                        ApplyChangesButton.Enabled = true;
                    }
#else
                    throw new ServiceResultException("Server Push is not yet implemented.");
#endif
                }

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

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

                Opc.Ua.Client.Controls.ExceptionDlg.Show(Text, exception);
                CertificateRequestTimer.Enabled = false;
            }
        }
コード例 #16
0
        public static async Task ConsoleSampleClient(string endpointURL)
        {
            Console.WriteLine("1 - Create an Application Configuration.");
            var config = new ApplicationConfiguration
            {
                ApplicationName = "UA Core Sample Client",
                ApplicationType = ApplicationType.Client,
                ApplicationUri = "urn:"+Utils.GetHostName()+":OPCFoundation:CoreSampleClient",
                SecurityConfiguration = new SecurityConfiguration
                {
                    ApplicationCertificate = new CertificateIdentifier
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/MachineDefault",
                        SubjectName = "UA Core Sample Client"
                    },
                    TrustedPeerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Applications",
                    },
                    TrustedIssuerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities",
                    },
                    RejectedCertificateStore = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/RejectedCertificates",
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = true
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas = new TransportQuotas { OperationTimeout = 120000 },
                ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 120000 }
            };

            await config.Validate(ApplicationType.Client);

            bool haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (!haveAppCertificate)
            {
                Console.WriteLine("    INFO: Creating new application certificate: {0}", config.ApplicationName);

                X509Certificate2 certificate = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,
                    config.ApplicationUri,
                    config.ApplicationName,
                    config.SecurityConfiguration.ApplicationCertificate.SubjectName
                    );

                config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            }

            haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);

                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
                }
            }
            else
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecure connection.");
            }

            Console.WriteLine("2 - Discover endpoints of {0}.", endpointURL);
            Uri endpointURI = new Uri(endpointURL);
            var endpointCollection = DiscoverEndpoints(config, endpointURI, 10);
            var selectedEndpoint = SelectUaTcpEndpoint(endpointCollection, haveAppCertificate);
            Console.WriteLine("    Selected endpoint uses: {0}",
                selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1));

#if PERF
        for (int i = 1; ; i++)
        {
#endif
            Console.WriteLine("3 - Create a session with OPC UA server.");
            var endpointConfiguration = EndpointConfiguration.Create(config);
            var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);
            endpoint.Update(selectedEndpoint);
            var session = await Session.Create(config, endpoint, true, ".Net Core OPC UA Console Client", 60000, null,
                null);

            // Access underlying proxy socket
            var channel = session.TransportChannel as IMessageSocketChannel;
            var socket = channel.Socket as ProxyMessageSocket;
            var proxySocket = socket.ProxySocket;
            Console.WriteLine("    Connected through proxy {0}.", proxySocket.LocalEndPoint.ToString());

            ReferenceDescriptionCollection references;
            Byte[] continuationPoint;

            references = session.FetchReferences(ObjectIds.ObjectsFolder);
            Stopwatch w = Stopwatch.StartNew();

            Console.WriteLine($"4 - Browse the OPC UA server namespace.");

            session.Browse(
                null,
                null,
                ObjectIds.ObjectsFolder,
                0u,
                BrowseDirection.Forward,
                ReferenceTypeIds.HierarchicalReferences,
                true,
                (uint) NodeClass.Variable | (uint) NodeClass.Object | (uint) NodeClass.Method,
                out continuationPoint,
                out references);

            Console.WriteLine(" DisplayName, BrowseName, NodeClass");
            BrowseChildren("", references, session);
            Console.WriteLine($" ....        took {w.ElapsedMilliseconds} ms...");
#if PERF
            session.Close();
        }
#else

            Console.WriteLine("5 - Create a subscription with publishing interval of 1 second.");
            var subscription = new Subscription(session.DefaultSubscription) { PublishingInterval = 1000 };

            Console.WriteLine("6 - Add a list of items (server current time and status) to the subscription.");
            var list = new List<MonitoredItem> {
                new MonitoredItem(subscription.DefaultItem)
                {
                    DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=2258"
                }
            };
            list.ForEach(i => i.Notification += OnNotification);
            subscription.AddItems(list);

            Console.WriteLine("7 - Add the subscription to the session.");
            session.AddSubscription(subscription);
            subscription.Create();

            Console.WriteLine("8 - Running...Press any key to exit...");
#endif
        }
コード例 #17
0
            /// <summary>
            /// Validates the identity token supplied by the client.
            /// </summary>
            /// <param name="identityToken"></param>
            /// <param name="userTokenSignature"></param>
            /// <returns></returns>
            private bool ValidateUserIdentityToken(ExtensionObject identityToken,
                                                   SignatureData userTokenSignature)
            {
                UserIdentityToken token = null;
                UserTokenPolicy   policy;

                if (identityToken == null || identityToken.Body == null)
                {
                    if (_activated)
                    {
                        // not changing the token if already activated.
                        return(false);
                    }
                    policy = Endpoint.UserIdentityTokens?
                             .FirstOrDefault(t => t.TokenType == UserTokenType.Anonymous);
                    if (policy == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied,
                                                            "Anonymous user token policy not supported.");
                    }
                    // create an anonymous token to use for subsequent validation.
                    token = new AnonymousIdentityToken {
                        PolicyId = policy.PolicyId
                    };
                }
                else if (!typeof(UserIdentityToken).IsInstanceOfType(identityToken.Body))
                {
                    // Decode identity token from binary.
                    token = DecodeUserIdentityToken(identityToken, out policy);
                }
                else
                {
                    token = (UserIdentityToken)identityToken.Body;
                    // find the user token policy.
                    policy = Endpoint.FindUserTokenPolicy(token.PolicyId);
                    if (policy == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid,
                                                            "User token policy not supported.");
                    }
                }

                // determine the security policy uri.
                var securityPolicyUri = policy.SecurityPolicyUri;

                if (string.IsNullOrEmpty(securityPolicyUri))
                {
                    securityPolicyUri = Endpoint.SecurityPolicyUri;
                }

                if (securityPolicyUri != SecurityPolicies.None)
                {
                    // decrypt the user identity token.
                    if (_serverCertificate == null)
                    {
                        _serverCertificate = CertificateFactory.Create(
                            Endpoint.ServerCertificate, true);
                        // check for valid certificate.
                        if (_serverCertificate == null)
                        {
                            throw ServiceResultException.Create(StatusCodes.BadConfigurationError,
                                                                "ApplicationCertificate cannot be found.");
                        }
                    }
                    try {
                        token.Decrypt(_serverCertificate, _serverNonce, securityPolicyUri);
                    }
                    catch (ServiceResultException) {
                        throw;
                    }
                    catch (Exception e) {
                        throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid,
                                                            e, "Could not decrypt identity token.");
                    }
                    // ... and verify the signature if any.
                    VerifyUserTokenSignature(userTokenSignature, token, securityPolicyUri);
                }

                // We have a valid token - validate it through the handler chain.
                var arg = new UserIdentityHandlerArgs {
                    CurrentIdentities = Identities,
                    Token             = token
                };

                _validator?.Invoke(this, arg);
                if (arg.ValidationException != null)
                {
                    throw arg.ValidationException;
                }
                if (arg.NewIdentities != null)
                {
                    Identities = arg.NewIdentities;
                    return(true);
                }
                return(false); // No new identities
            }
コード例 #18
0
        internal void OnDeserializedMethod(StreamingContext context)
        {
            // Validate configuration and set reasonable defaults

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

            if (Configuration.TransportQuotas == null)
            {
                Configuration.TransportQuotas = new TransportQuotas {
                    OperationTimeout = 15000
                }
            }
            ;

            if (Configuration.ClientConfiguration == null)
            {
                Configuration.ClientConfiguration = new ClientConfiguration();
            }
            if (Configuration.ServerConfiguration == null)
            {
                Configuration.ServerConfiguration = new ServerConfiguration();
            }

            if (Configuration.SecurityConfiguration.TrustedPeerCertificates == null)
            {
                Configuration.SecurityConfiguration.TrustedPeerCertificates = new CertificateTrustList();
            }
            if (Configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType == null)
            {
                Configuration.SecurityConfiguration.TrustedPeerCertificates.StoreType =
                    "Directory";
            }
            if (Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath == null)
            {
                Configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath =
                    "OPC Foundation/CertificateStores/UA Applications";
            }

            if (Configuration.SecurityConfiguration.TrustedIssuerCertificates == null)
            {
                Configuration.SecurityConfiguration.TrustedIssuerCertificates = new CertificateTrustList();
            }
            if (Configuration.SecurityConfiguration.TrustedIssuerCertificates.StoreType == null)
            {
                Configuration.SecurityConfiguration.TrustedIssuerCertificates.StoreType =
                    "Directory";
            }
            if (Configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath == null)
            {
                Configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath =
                    "OPC Foundation/CertificateStores/UA Certificate Authorities";
            }

            if (Configuration.SecurityConfiguration.RejectedCertificateStore == null)
            {
                Configuration.SecurityConfiguration.RejectedCertificateStore = new CertificateTrustList();
            }
            if (Configuration.SecurityConfiguration.RejectedCertificateStore.StoreType == null)
            {
                Configuration.SecurityConfiguration.RejectedCertificateStore.StoreType =
                    "Directory";
            }
            if (Configuration.SecurityConfiguration.RejectedCertificateStore.StorePath == null)
            {
                Configuration.SecurityConfiguration.RejectedCertificateStore.StorePath =
                    "OPC Foundation/CertificateStores/RejectedCertificates";
            }

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

            Configuration.Validate(Configuration.ApplicationType).Wait();

            if (Configuration.SecurityConfiguration.ApplicationCertificate.Certificate == null)
            {
                X509Certificate2 certificate = CertificateFactory.CreateCertificate(
                    Configuration.SecurityConfiguration.ApplicationCertificate.StoreType,
                    Configuration.SecurityConfiguration.ApplicationCertificate.StorePath,
                    Configuration.ApplicationUri,
                    Configuration.ApplicationName,
                    Configuration.SecurityConfiguration.ApplicationCertificate.SubjectName
                    );
                Configuration.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            }

            if (Configuration.SecurityConfiguration.ApplicationCertificate.Certificate != null)
            {
                Configuration.ApplicationUri = Utils.GetApplicationUriFromCertificate(
                    Configuration.SecurityConfiguration.ApplicationCertificate.Certificate);
            }
            else
            {
                Console.WriteLine("Opc.Ua.Client.SampleModule: WARNING: missing application certificate, using unsecure connection.");
            }

            if (Configuration.SecurityConfiguration.AutoAcceptUntrustedCertificates)
            {
                Configuration.CertificateValidator.CertificateValidation +=
                    new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
            }
        }
コード例 #19
0
ファイル: Program.cs プロジェクト: cnarasimhagit/vm
        static void Main(string[] args)
        {
            var ai = new TelemetryClient();

            TelemetryConfiguration.Active.InstrumentationKey = "1ea142b2-1d97-453e-a0f4-32b15523dd7d";

            try
            {
                ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, errors) => true;
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

                foreach (var pattern in _patternsAddressesAndBindings)
                {
                    using (var host = new RequestResponseServiceHostFactory(pattern.AddressesAndBindings, pattern.PatternName).CreateHost())
                    {
                        try
                        {
                            if (new[]
                            {
                                RequestResponseTransportConfigurator.PatternName,
                                RequestResponseMessageConfigurator.PatternName,

                                RequestResponseTransportClientCertificateAuthenticationConfigurator.PatternName,
                                RequestResponseMessageClientCertificateAuthenticationConfigurator.PatternName,

                                RequestResponseTransportClientWindowsAuthenticationConfigurator.PatternName,
                                RequestResponseMessageClientWindowsAuthenticationConfigurator.PatternName,
                            }.Contains(pattern.PatternName))
                            {
                                host.SetServiceCredentials(
                                    CertificateFactory.GetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "351ae52cb2c3ac15ec12a3bdce838554fc63da95"));
                            }

                            host.Open();

                            Console.WriteLine($"\nA service host for {host.Description.ServiceType.Name} service is initializing for pattern {pattern.PatternName}:");
                            foreach (var ep in host.Description.Endpoints)
                            {
                                Console.WriteLine("    {0}", ep.ListenUri.AbsoluteUri.ToString());
                            }

                            foreach (var ab in pattern.AddressesAndBindings)
                            {
                                try
                                {
                                    var binding = ab.BindingFactory();
                                    var client  = new RequestResponseClient(binding, ab.Address, ServiceIdentity.None, "", pattern.PatternName);

                                    using (client)
                                    {
                                        var s = client.GetStrings(2);
                                        Console.WriteLine($"{ab.Address} => successfully got {s.Count()} strings.");
                                    }
                                }
                                catch (Exception x)
                                {
                                    Facility.LogWriter.ExceptionError(x);
                                    VmAspectsEventSource.Log.Exception(x);
                                    ai.TrackException(x);

                                    Console.WriteLine($"{ab.Address} => failed:");
                                    Console.WriteLine(x.DumpString());
                                    Debug.WriteLine(x.DumpString());
                                }
                            }

                            host.Close();
                        }
                        catch (Exception x)
                        {
                            Facility.LogWriter.ExceptionError(x);
                            VmAspectsEventSource.Log.Exception(x);
                            ai.TrackException(x);

                            host.Abort();
                            Console.WriteLine($"The host with pattern {pattern.PatternName} => failed:");
                            Console.WriteLine(x.DumpString());
                            Debug.WriteLine(x.DumpString());
                        }

                        ai.Flush();
                        Task.Delay(1000).Wait();

                        Console.Write("Press any key to continue...");
                        Console.ReadKey(false);
                        Console.WriteLine();
                        Console.WriteLine();
                    }
                }
            }
            catch (Exception x)
            {
                Facility.LogWriter.ExceptionError(x);
                VmAspectsEventSource.Log.Exception(x);
                ai.TrackException(x);

                Console.WriteLine(x.DumpString());
                Debug.WriteLine(x.DumpString());

                Console.Write("Press any key to finish...");
                Console.ReadKey(false);
            }

            ai.Flush();
            Task.Delay(1000).Wait();
        }
コード例 #20
0
        /// <summary>
        /// Start server
        /// </summary>
        /// <param name="ports"></param>
        /// <returns></returns>
        private async Task StartServerInternal(IEnumerable <int> ports)
        {
            _logger.Information("Starting server...");
            ApplicationInstance.MessageDlg = new DummyDialog();

            var config = _factory.CreateServer(ports, out _server);

            config = ApplicationInstance.FixupAppConfig(config);
            await config.Validate(ApplicationType.Server);

            config.CertificateValidator.CertificateValidation += (v, e) => {
                if (e.Error.StatusCode ==
                    StatusCodes.BadCertificateUntrusted)
                {
                    e.Accept = AutoAccept;
                    _logger.Information((e.Accept ? "Accepted" : "Rejected") +
                                        " Certificate {subject}", e.Certificate.Subject);
                }
            };

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

            // Use existing certificate, if it is there.
            var cert = await config.SecurityConfiguration.ApplicationCertificate
                       .Find(true);

            if (cert == null)
            {
                // Create cert
                cert = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null, config.ApplicationUri, config.ApplicationName,
                    config.SecurityConfiguration.ApplicationCertificate.SubjectName,
                    null, CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize,
                    false, null, null);
            }

            if (cert != null)
            {
                config.SecurityConfiguration.ApplicationCertificate.Certificate = cert;
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(cert);
            }

            var application = new ApplicationInstance(config);

            // check the application certificate.
            var haveAppCertificate =
                await application.CheckApplicationInstanceCertificate(false, 0);

            if (!haveAppCertificate)
            {
                throw new Exception(
                          "Application instance certificate invalid!");
            }

            // start the server.
            await application.Start(_server);

            foreach (var ep in config.ServerConfiguration.BaseAddresses)
            {
                _logger.Information("Listening on {ep}", ep);
            }
            _logger.Information("Server started.");
        }
コード例 #21
0
        /// <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);
        }
コード例 #22
0
        public static void Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("Usage: CreateCerts <OutputPath> <ApplicationName> <ApplicationURI>");
            }
            else
            {
                Console.WriteLine("Output directory: " + args[0]);

                // cleanup previous runs
                try
                {
                    Directory.Delete(args[0] + Path.DirectorySeparatorChar + "certs", true);
                    Directory.Delete(args[0] + Path.DirectorySeparatorChar + "private", true);
                }
                catch (Exception)
                {
                    // do nothing
                }

                // create certs
                string           storeType        = "Directory";
                string           storePath        = args[0];
                string           password         = "******";
                string           applicationURI   = args[2];
                string           applicationName  = args[1];
                string           subjectName      = applicationName;
                List <string>    domainNames      = null; // not used
                const ushort     keySizeInBits    = 2048;
                DateTime         startTime        = DateTime.UtcNow - TimeSpan.FromDays(1);
                const ushort     lifetimeInMonths = 120;
                const ushort     hashSizeInBits   = 256;
                bool             isCA             = false;
                X509Certificate2 issuerCAKeyCert  = null; // not used

                if (!applicationURI.StartsWith("urn:"))
                {
                    applicationURI = "urn:" + applicationURI;
                }

                CertificateFactory.CreateCertificate(
                    storeType,
                    storePath,
                    password,
                    applicationURI,
                    applicationName,
                    subjectName,
                    domainNames,
                    keySizeInBits,
                    startTime,
                    lifetimeInMonths,
                    hashSizeInBits,
                    isCA,
                    issuerCAKeyCert);

                // rename cert files to something we can copy easily
                DirectoryInfo dir = new DirectoryInfo(args[0] + Path.DirectorySeparatorChar + "certs");
                foreach (FileInfo file in dir.EnumerateFiles())
                {
                    if (file.Extension == ".der")
                    {
                        File.Move(file.FullName, file.DirectoryName + Path.DirectorySeparatorChar + args[1].Replace(" ", "") + file.Extension);
                    }
                }
                dir = new DirectoryInfo(args[0] + Path.DirectorySeparatorChar + "private");
                foreach (FileInfo file in dir.EnumerateFiles())
                {
                    if (file.Extension == ".pfx")
                    {
                        File.Move(file.FullName, file.DirectoryName + Path.DirectorySeparatorChar + args[1].Replace(" ", "") + file.Extension);
                    }
                }
            }
        }
コード例 #23
0
        public void VerifyCrlCerts(
            KeyHashPair keyHashPair
            )
        {
            int pathLengthConstraint = (keyHashPair.KeySize / 512) - 3;
            X509Certificate2 issuerCertificate;

            if (!m_rootCACertificate.TryGetValue(keyHashPair.KeySize, out issuerCertificate))
            {
                Assert.Ignore($"Could not load Issuer Cert.");
            }
            Assert.True(X509Utils.VerifySelfSigned(issuerCertificate));

            var otherIssuerCertificate = CertificateFactory.CreateCertificate(issuerCertificate.Subject)
                                         .SetLifeTime(TimeSpan.FromDays(180))
                                         .SetHashAlgorithm(keyHashPair.HashAlgorithmName)
                                         .SetCAConstraint(pathLengthConstraint)
                                         .CreateForRSA();

            Assert.True(X509Utils.VerifySelfSigned(otherIssuerCertificate));

            X509Certificate2Collection revokedCerts = new X509Certificate2Collection();

            for (int i = 0; i < 10; i++)
            {
                var cert = CertificateFactory.CreateCertificate($"CN=Test Cert {i}")
                           .SetIssuer(issuerCertificate)
                           .SetRSAKeySize(keyHashPair.KeySize <= 2048 ? keyHashPair.KeySize : 2048)
                           .CreateForRSA();
                revokedCerts.Add(cert);
                Assert.False(X509Utils.VerifySelfSigned(cert));
            }

            Assert.NotNull(issuerCertificate);
            Assert.NotNull(issuerCertificate.RawData);
            Assert.True(issuerCertificate.HasPrivateKey);
            using (var rsa = issuerCertificate.GetRSAPrivateKey())
            {
                Assert.NotNull(rsa);
            }

            using (var plainCert = new X509Certificate2(issuerCertificate.RawData))
            {
                Assert.NotNull(plainCert);
                VerifyCACert(plainCert, issuerCertificate.Subject, pathLengthConstraint);
            }
            X509Utils.VerifySelfSigned(issuerCertificate);
            X509Utils.VerifyRSAKeyPair(issuerCertificate, issuerCertificate);

            var crl = CertificateFactory.RevokeCertificate(issuerCertificate, null, null);

            Assert.NotNull(crl);
            Assert.True(crl.VerifySignature(issuerCertificate, true));
            var extension  = X509Extensions.FindExtension <X509CrlNumberExtension>(crl.CrlExtensions);
            var crlCounter = new BigInteger(1);

            Assert.AreEqual(crlCounter, extension.CrlNumber);
            var revokedList = new List <X509CRL>();

            revokedList.Add(crl);
            foreach (var cert in revokedCerts)
            {
                Assert.Throws <CryptographicException>(() => crl.VerifySignature(otherIssuerCertificate, true));
                Assert.False(crl.IsRevoked(cert));
                var nextCrl = CertificateFactory.RevokeCertificate(issuerCertificate, revokedList, new X509Certificate2Collection(cert));
                crlCounter++;
                Assert.NotNull(nextCrl);
                Assert.True(nextCrl.IsRevoked(cert));
                extension = X509Extensions.FindExtension <X509CrlNumberExtension>(nextCrl.CrlExtensions);
                Assert.AreEqual(crlCounter, extension.CrlNumber);
                Assert.True(crl.VerifySignature(issuerCertificate, true));
                revokedList.Add(nextCrl);
                crl = nextCrl;
            }

            foreach (var cert in revokedCerts)
            {
                Assert.True(crl.IsRevoked(cert));
            }
        }
コード例 #24
0
        private async Task <ApplicationConfiguration> CreateConfiguration()
        {
            Console.WriteLine("1 - Create an Application Configuration.");
            Utils.SetTraceOutput(Utils.TraceOutput.DebugAndFile);
            var config = new ApplicationConfiguration
            {
                ApplicationName = "UA Core Sample Client",
                ApplicationType = ApplicationType.Client,
                ApplicationUri  = "urn:" + Utils.GetHostName() + ":OPCFoundation:CoreSampleClient",

                SecurityConfiguration = new SecurityConfiguration
                {
                    ApplicationCertificate = new CertificateIdentifier
                    {
                        StoreType   = "X509Store",
                        StorePath   = "CurrentUser\\UA_MachineDefault",
                        SubjectName = "PLC-1/OPCUA-1-6"
                    },
                    TrustedPeerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Applications"
                    },
                    TrustedIssuerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities"
                    },
                    RejectedCertificateStore = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/RejectedCertificates"
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = true,
                    RejectSHA1SignedCertificates    = false
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas         = new TransportQuotas {
                    OperationTimeout = 15000
                },
                ClientConfiguration = new ClientConfiguration {
                    DefaultSessionTimeout = 60000
                }
            };

            await config.Validate(ApplicationType.Client);

            var haveAppCertificate = HasAppCertificate(config);

            if (!haveAppCertificate)
            {
                Console.WriteLine("    INFO: Creating new application certificate: {0}", config.ApplicationName);

                var certificate = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null,
                    config.ApplicationUri,
                    config.ApplicationName,
                    config.SecurityConfiguration.ApplicationCertificate.SubjectName,
                    null,
                    CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize,
                    false,
                    null,
                    null
                    );

                config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            }

            haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);

                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    config.CertificateValidator.CertificateValidation += CertificateValidator_CertificateValidation;
                }
            }
            else
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecure connection.");
            }
            return(config);
        }
コード例 #25
0
        /// <summary>
        /// Revoke the CA signed certificate.
        /// The issuer CA public key, the private key and the crl reside in the storepath.
        /// The CRL number is increased by one and existing CRL for the issuer are deleted from the store.
        /// </summary>
        public static async Task <X509CRL> RevokeCertificateAsync(
            string storePath,
            X509Certificate2 certificate,
            string issuerKeyFilePassword = null
            )
        {
            X509CRL updatedCRL   = null;
            string  subjectName  = certificate.IssuerName.Name;
            string  keyId        = null;
            string  serialNumber = null;

            // caller may want to create empty CRL using the CA cert itself
            bool isCACert = X509Utils.IsCertificateAuthority(certificate);

            // find the authority key identifier.
            X509AuthorityKeyIdentifierExtension authority = X509Extensions.FindExtension <X509AuthorityKeyIdentifierExtension>(certificate);

            if (authority != null)
            {
                keyId        = authority.KeyIdentifier;
                serialNumber = authority.SerialNumber;
            }
            else
            {
                throw new ArgumentException("Certificate does not contain an Authority Key");
            }

            if (!isCACert)
            {
                if (serialNumber == certificate.SerialNumber ||
                    X509Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer))
                {
                    throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Cannot revoke self signed certificates");
                }
            }

            X509Certificate2 certCA = null;

            using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(storePath))
            {
                if (store == null)
                {
                    throw new ArgumentException("Invalid store path/type");
                }
                certCA = await X509Utils.FindIssuerCABySerialNumberAsync(store, certificate.Issuer, serialNumber).ConfigureAwait(false);

                if (certCA == null)
                {
                    throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Cannot find issuer certificate in store.");
                }

                if (!certCA.HasPrivateKey)
                {
                    throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Issuer certificate has no private key, cannot revoke certificate.");
                }

                CertificateIdentifier certCAIdentifier = new CertificateIdentifier(certCA)
                {
                    StorePath = storePath,
                    StoreType = CertificateStoreIdentifier.DetermineStoreType(storePath)
                };
                X509Certificate2 certCAWithPrivateKey = await certCAIdentifier.LoadPrivateKey(issuerKeyFilePassword).ConfigureAwait(false);

                if (certCAWithPrivateKey == null)
                {
                    throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Failed to load issuer private key. Is the password correct?");
                }

                List <X509CRL> certCACrl = store.EnumerateCRLs(certCA, false);

                var certificateCollection = new X509Certificate2Collection()
                {
                };
                if (!isCACert)
                {
                    certificateCollection.Add(certificate);
                }
                updatedCRL = CertificateFactory.RevokeCertificate(certCAWithPrivateKey, certCACrl, certificateCollection);

                store.AddCRL(updatedCRL);

                // delete outdated CRLs from store
                foreach (X509CRL caCrl in certCACrl)
                {
                    store.DeleteCRL(caCrl);
                }
                store.Close();
            }
            return(updatedCRL);
        }
コード例 #26
0
        public async Task <IConnection> CreateAndConnectAsync(HostEndpointWithPort hostEndpoint,
                                                              CancellationToken cancellationToken = default)
        {
            if (_clusterOptions.IsCapella && !_clusterOptions.EffectiveEnableTls)
            {
                _multiplexLogger.LogWarning("TLS is required when connecting to Couchbase Capella. Please enable TLS by prefixing the connection string with \"couchbases://\" (note the final 's').");
            }

            var endPoint = await _ipEndPointService.GetIpEndPointAsync(hostEndpoint.Host, hostEndpoint.Port, cancellationToken)
                           .ConfigureAwait(false);

            if (endPoint is null)
            {
                throw new ConnectException($"Unable to resolve host '{hostEndpoint}'.");
            }

            var socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                var connectTask = socket.ConnectAsync(endPoint);

                var whichTask = await Task
                                .WhenAny(connectTask, Task.Delay(_clusterOptions.KvConnectTimeout, cancellationToken))
                                .ConfigureAwait(false);

                if (whichTask != connectTask)
                {
                    // Was a timeout
                    const int connectionTimedOut = 10060;
                    throw new SocketException(connectionTimedOut);
                }
            }
            catch
            {
                socket.Dispose();
                throw;
            }

#if NETCOREAPP3_0_OR_GREATER
            _multiplexLogger.LogDebug("Setting TCP Keep-Alives using SocketOptions - enable keep-alives {EnableTcpKeepAlives}, time {TcpKeepAliveTime}, interval {TcpKeepAliveInterval}.",
                                      _clusterOptions.EnableTcpKeepAlives, _clusterOptions.TcpKeepAliveTime, _clusterOptions.TcpKeepAliveInterval);

            if (!socket.TryEnableKeepAlives(_clusterOptions.EnableTcpKeepAlives,
                                            (int)_clusterOptions.TcpKeepAliveTime.TotalSeconds,
                                            (int)_clusterOptions.TcpKeepAliveInterval.TotalSeconds, out string setKeepAliveMessage)
                )
            {
                _multiplexLogger.LogWarning(setKeepAliveMessage);
            }
#else
            _multiplexLogger.LogDebug(
                "Setting TCP Keep-Alives using Socket.IOControl on {endpoint} - enable tcp keep-alives {EnableTcpKeepAlives}, time {TcpKeepAliveTime}, interval {TcpKeepAliveInterval}",
                endPoint, _clusterOptions.EnableTcpKeepAlives, _clusterOptions.TcpKeepAliveTime,
                _clusterOptions.TcpKeepAliveInterval);

            if (!socket.TrySetKeepAlives(_clusterOptions.EnableTcpKeepAlives,
                                         (uint)_clusterOptions.TcpKeepAliveTime.TotalMilliseconds,
                                         (uint)_clusterOptions.TcpKeepAliveInterval.TotalMilliseconds, out var setKeepAliveMessage)
                )
            {
                _multiplexLogger.LogWarning(setKeepAliveMessage);
            }
#endif

            if (_clusterOptions.EffectiveEnableTls)
            {
                //Check if were using x509 auth, if so fetch the certificates
                X509Certificate2Collection?certs = null;
                if (_clusterOptions.X509CertificateFactory != null)
                {
                    certs = _clusterOptions.X509CertificateFactory.GetCertificates();
                    if (certs == null || certs.Count == 0)
                    {
                        throw new AuthenticationException(
                                  "No certificates matching the X509FindType and specified FindValue were found in the Certificate Store.");
                    }

                    if (_sslLogger.IsEnabled(LogLevel.Debug))
                    {
                        foreach (var cert in certs)
                        {
                            _sslLogger.LogDebug("Cert sent {cert.FriendlyName} - Thumbprint {cert.Thumbprint}",
                                                cert.FriendlyName, cert.Thumbprint);
                        }

                        _sslLogger.LogDebug("Sending {certs.Count} certificates to the server.", certs.Count);
                    }
                }

                //The endpoint we are connecting to
                var targetHost = _clusterOptions.ForceIpAsTargetHost
                    ? endPoint.Address.ToString()
                    : hostEndpoint.Host;

                //create the sslstream with appropriate authentication
                RemoteCertificateValidationCallback?certValidationCallback = _clusterOptions.KvCertificateCallbackValidation;
                if (certValidationCallback == null)
                {
                    certValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
                    {
                        if (_clusterOptions.KvIgnoreRemoteCertificateNameMismatch &&
                            CertificateFactory.ValidatorWithIgnoreNameMismatch(sender, certificate, chain, sslPolicyErrors))
                        {
                            return(true);
                        }

                        return(CertificateFactory.ValidateWithDefaultCertificates(sender, certificate, chain, sslPolicyErrors));
                    };
                }

                var sslStream = new SslStream(new NetworkStream(socket, true), false,
                                              certValidationCallback);

#if !NETCOREAPP3_1_OR_GREATER
                await sslStream.AuthenticateAsClientAsync(targetHost, certs,
                                                          _clusterOptions.EnabledSslProtocols,
                                                          _clusterOptions.EnableCertificateRevocation)
                .ConfigureAwait(false);
#else
                SslClientAuthenticationOptions sslOptions = new SslClientAuthenticationOptions()
                {
                    TargetHost                     = targetHost,
                    ClientCertificates             = certs,
                    EnabledSslProtocols            = _clusterOptions.EnabledSslProtocols,
                    CertificateRevocationCheckMode = _clusterOptions.EnableCertificateRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck
                };
                if (_clusterOptions.EnabledTlsCipherSuites != null && _clusterOptions.EnabledTlsCipherSuites.Count > 0)
                {
                    sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(_clusterOptions.EnabledTlsCipherSuites);
                }

                await sslStream.AuthenticateAsClientAsync(sslOptions)
                .ConfigureAwait(false);
#endif

                var isSecure = sslStream.IsAuthenticated && sslStream.IsSigned && sslStream.IsEncrypted;
                _sslLogger.LogDebug("IsAuthenticated {0} on {1}", sslStream.IsAuthenticated, targetHost);
                _sslLogger.LogDebug("IsSigned {0} on {1}", sslStream.IsSigned, targetHost);
                _sslLogger.LogDebug("IsEncrypted {0} on {1}", sslStream.IsEncrypted, targetHost);

                //punt if we cannot successfully authenticate
                if (!isSecure)
                {
                    throw new AuthenticationException($"The SSL/TLS connection could not be authenticated on [{targetHost}].");
                }

                return(new SslConnection(sslStream, socket.LocalEndPoint !, socket.RemoteEndPoint !,
                                         _sslLogger, _multiplexLogger));
            }

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

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

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

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

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

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

            if (_appConfig.SecurityConfiguration.AutoAcceptUntrustedCertificates)
            {
                _logger.Warning(
                    "WARNING: Automatically accepting certificates. This is a security risk.");
            }
        }
コード例 #28
0
        private async void RequestNewButton_Click(object sender, EventArgs e)
        {
            try
            {
                // check if we already have a private key
                NodeId requestId = null;
                if (!string.IsNullOrEmpty(m_application.CertificateStorePath))
                {
                    CertificateIdentifier id = new CertificateIdentifier();
                    id.StoreType   = CertificateStoreIdentifier.DetermineStoreType(m_application.CertificateStorePath);
                    id.StorePath   = m_application.CertificateStorePath;
                    id.SubjectName = m_application.CertificateSubjectName.Replace("localhost", Utils.GetHostName());
                    m_certificate  = await id.Find(true);

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

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

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

                m_application.CertificateRequestId = requestId.ToString();
                CertificateRequestTimer.Enabled    = true;
                RequestProgressLabel.Visible       = true;
                WarningLabel.Visible = false;
            }
            catch (Exception ex)
            {
                Opc.Ua.Client.Controls.ExceptionDlg.Show(Text, ex);
            }
        }
コード例 #29
0
        protected void ReadAsymmetricMessageHeader(
            BinaryDecoder decoder,
            X509Certificate2 receiverCertificate,
            out uint secureChannelId,
            out X509Certificate2 senderCertificate,
            out string securityPolicyUri)
        {
            senderCertificate = null;

            uint messageType = decoder.ReadUInt32(null);
            uint messageSize = decoder.ReadUInt32(null);

            // decode security header.
            byte[] certificateData = null;
            byte[] thumbprintData  = null;

            try
            {
                secureChannelId   = decoder.ReadUInt32(null);
                securityPolicyUri = decoder.ReadString(null, TcpMessageLimits.MaxSecurityPolicyUriSize);
                certificateData   = decoder.ReadByteString(null, TcpMessageLimits.MaxCertificateSize);
                thumbprintData    = decoder.ReadByteString(null, TcpMessageLimits.CertificateThumbprintSize);
            }
            catch (Exception e)
            {
                throw ServiceResultException.Create(
                          StatusCodes.BadSecurityChecksFailed,
                          e,
                          "The asymmetric security header could not be parsed.");
            }

            // verify sender certificate.
            if (certificateData != null && certificateData.Length > 0)
            {
                senderCertificate = CertificateFactory.Create(certificateData, true);

                try
                {
                    string thumbprint = senderCertificate.Thumbprint;

                    if (thumbprint == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "Invalid certificate thumbprint.");
                    }
                }
                catch (Exception e)
                {
                    throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, e, "The sender's certificate could not be parsed.");
                }
            }
            else
            {
                if (securityPolicyUri != SecurityPolicies.None)
                {
                    throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "The sender's certificate was not specified.");
                }
            }

            // verify receiver thumbprint.
            if (thumbprintData != null && thumbprintData.Length > 0)
            {
                if (receiverCertificate.Thumbprint.ToUpperInvariant() != GetThumbprintString(thumbprintData))
                {
                    throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "The receiver's certificate thumbprint is not valid.");
                }
            }
            else
            {
                if (securityPolicyUri != SecurityPolicies.None)
                {
                    throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "The receiver's certificate thumbprint was not specified.");
                }
            }
        }
コード例 #30
0
        /// <summary>
        /// Creates a minimal application configuration for a client.
        /// </summary>
        /// <remarks>
        /// In most cases the application configuration will be loaded from an XML file.
        /// This example populates the configuration in code.
        /// </remarks>
        public static ApplicationConfiguration CreateClientConfiguration()
        {
            // 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 = "UA Test Client";
            configuration.ApplicationType = ApplicationType.Client;
            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 clientCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find(true);

            // create a new certificate if one not found.
            if (clientCertificate == 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.
                clientCertificate = CertificateFactory.CreateCertificate(
                    configuration.SecurityConfiguration.ApplicationCertificate.StoreType,
                    configuration.SecurityConfiguration.ApplicationCertificate.StorePath,
                    configuration.ApplicationUri,
                    configuration.ApplicationName,
                    null,
                    null,
                    1024,
                    120);
            }

            // Step 3 - Specify the supported transport configurations.

            // The SDK requires Binding objects which are sub-types of Opc.Ua.Bindings.BaseBinding
            // These two lines add support for SOAP/HTTP w/ WS-* and UA-TCP. Support for other protocols
            // such as .NET TCP can be added but they would not be considered interoperable across different vendors.
            // Only one binding per URL scheme is allowed.
            configuration.TransportConfigurations.Add(new TransportConfiguration(Utils.UriSchemeOpcTcp, typeof(Opc.Ua.Bindings.UaTcpBinding)));
            configuration.TransportConfigurations.Add(new TransportConfiguration(Utils.UriSchemeHttp, typeof(Opc.Ua.Bindings.UaSoapXmlBinding)));

            // 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 = 360000;
            configuration.TransportQuotas.MaxStringLength  = 67108864;
            configuration.ServerConfiguration = new ServerConfiguration();

            // Step 5 - Specify the client specific configuration.
            configuration.ClientConfiguration = new ClientConfiguration();
            configuration.ClientConfiguration.DefaultSessionTimeout = 360000;

            // 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.Client);

            return(configuration);
        }