private X509Certificate2 CreateInvalidCert(InvalidCertType certType)
        {
            // reasonable defaults
            DateTime notBefore = DateTime.Today.AddDays(-30);
            DateTime notAfter  = DateTime.Today.AddDays(30);
            ushort   keySize   = CertificateFactory.DefaultKeySize;

            string[] domainNames = new string[] { Utils.GetHostName() };
            switch (certType)
            {
            case InvalidCertType.Expired:
                notBefore = DateTime.Today.AddMonths(-12);
                notAfter  = DateTime.Today.AddDays(-7);
                break;

            case InvalidCertType.NotYetValid:
                notBefore = DateTime.Today.AddDays(7);
                notAfter  = notBefore.AddMonths(12);
                break;

            case InvalidCertType.KeySize1024:
                keySize = 1024;
                break;

            case InvalidCertType.HostName:
                domainNames = new string[] { "myhost", "1.2.3.4" };
                break;

            default:
                break;
            }

            return(CertificateFactory.CreateCertificate(
                       ApplicationUri,
                       ApplicationName,
                       SubjectName,
                       domainNames)
                   .SetNotBefore(notBefore)
                   .SetNotAfter(notAfter)
                   .SetRSAKeySize(keySize)
                   .CreateForRSA());
        }
        private X509Certificate2Collection CreateInvalidCertChain(InvalidCertType certType)
        {
            // reasonable defaults
            DateTime notBefore       = DateTime.Today.AddYears(-1);
            DateTime notAfter        = DateTime.Today.AddYears(1);
            DateTime issuerNotBefore = notBefore;
            DateTime issuerNotAfter  = notAfter;
            ushort   keySize         = CertificateFactory.DefaultKeySize;

            string[] domainNames = new string[] { Utils.GetHostName() };
            switch (certType)
            {
            case InvalidCertType.Expired:
                notAfter = DateTime.Today.AddDays(-7);
                break;

            case InvalidCertType.IssuerExpired:
                issuerNotAfter = DateTime.Today.AddDays(-7);
                break;

            case InvalidCertType.NotYetValid:
                notBefore = DateTime.Today.AddDays(7);
                break;

            case InvalidCertType.IssuerNotYetValid:
                issuerNotBefore = DateTime.Today.AddDays(7);
                break;

            case InvalidCertType.KeySize1024:
                keySize = 1024;
                break;

            case InvalidCertType.HostName:
                domainNames = new string[] { "myhost", "1.2.3.4" };
                break;

            default:
                break;
            }

            string rootCASubjectName = "CN=Root CA Test";
            var    rootCA            = CertificateFactory.CreateCertificate(rootCASubjectName)
                                       .SetNotBefore(issuerNotBefore)
                                       .SetNotAfter(issuerNotAfter)
                                       .SetCAConstraint(-1)
                                       .CreateForRSA();

            var appCert = CertificateFactory.CreateCertificate(
                ApplicationUri,
                ApplicationName,
                SubjectName,
                domainNames)
                          .SetNotBefore(notBefore)
                          .SetNotAfter(notAfter)
                          .SetIssuer(rootCA)
                          .SetRSAKeySize(keySize)
                          .CreateForRSA();

            var result = new X509Certificate2Collection();

            result.Add(appCert);
            result.Add(new X509Certificate2(rootCA.RawData));
            return(result);
        }
        //TODO [TestCase(InvalidCertType.KeySize1024, true, false)]
        public async Task TestInvalidAppCertChainDoNotRecreate(InvalidCertType certType, bool server, bool suppress)
        {
            // pki directory root for test runs.
            var pkiRoot = Path.GetTempPath() + Path.GetRandomFileName() + Path.DirectorySeparatorChar;

            var applicationInstance = new ApplicationInstance()
            {
                ApplicationName = ApplicationName
            };

            Assert.NotNull(applicationInstance);
            ApplicationConfiguration config;

            if (server)
            {
                config = await applicationInstance.Build(ApplicationUri, ProductUri)
                         .AsServer(new string[] { "opc.tcp://localhost:12345/Configuration" })
                         .AddSecurityConfiguration(SubjectName, pkiRoot)
                         .Create().ConfigureAwait(false);
            }
            else
            {
                config = await applicationInstance.Build(ApplicationUri, ProductUri)
                         .AsClient()
                         .AddSecurityConfiguration(SubjectName, pkiRoot)
                         .Create().ConfigureAwait(false);
            }
            Assert.NotNull(config);

            CertificateIdentifier applicationCertificate = applicationInstance.ApplicationConfiguration.SecurityConfiguration.ApplicationCertificate;

            Assert.IsNull(applicationCertificate.Certificate);

            var testCerts = CreateInvalidCertChain(certType);

            if (certType != InvalidCertType.NoIssuer)
            {
                using (var issuerCert = testCerts[1])
                {
                    Assert.NotNull(issuerCert);
                    Assert.False(issuerCert.HasPrivateKey);
                    issuerCert.AddToStore(
                        applicationInstance.ApplicationConfiguration.SecurityConfiguration.TrustedIssuerCertificates.StoreType,
                        applicationInstance.ApplicationConfiguration.SecurityConfiguration.TrustedIssuerCertificates.StorePath
                        );
                }
            }

            X509Certificate2 publicKey = null;

            using (var testCert = testCerts[0])
            {
                Assert.NotNull(testCert);
                Assert.True(testCert.HasPrivateKey);
                testCert.AddToStore(
                    applicationCertificate.StoreType,
                    applicationCertificate.StorePath
                    );
                publicKey = new X509Certificate2(testCert.RawData);
            }

            using (publicKey)
            {
                if (suppress)
                {
                    bool certOK = await applicationInstance.CheckApplicationInstanceCertificate(true, 0)
                                  .ConfigureAwait(false);

                    Assert.True(certOK);
                    Assert.AreEqual(publicKey, applicationCertificate.Certificate);
                }
                else
                {
                    var sre = Assert.ThrowsAsync <ServiceResultException>(async() =>
                                                                          await applicationInstance.CheckApplicationInstanceCertificate(true, 0).ConfigureAwait(false));
                    Assert.AreEqual(StatusCodes.BadConfigurationError, sre.StatusCode);
                }
            }
        }