public async Task KeyVaultCreateCACertificateAsync()
        {
            Skip.If(!_fixture.KeyVaultInitOk);
            string[] groups = await _keyVault.GetCertificateGroupIds();

            foreach (string group in groups)
            {
                X509Certificate2 result = await _keyVault.CreateIssuerCACertificateAsync(group);

                Assert.NotNull(result);
                Assert.False(result.HasPrivateKey);
                Assert.True(Opc.Ua.Utils.CompareDistinguishedName(result.Issuer, result.Subject));
                X509BasicConstraintsExtension basicConstraints = X509TestUtils.FindBasicConstraintsExtension(result);
                Assert.NotNull(basicConstraints);
                Assert.True(basicConstraints.CertificateAuthority);
                Assert.True(basicConstraints.Critical);
                var subjectKeyId = result.Extensions.OfType <X509SubjectKeyIdentifierExtension>().Single();
                Assert.False(subjectKeyId.Critical);
                var authorityKeyIdentifier = X509TestUtils.FindAuthorityKeyIdentifier(result);
                Assert.NotNull(authorityKeyIdentifier);
                Assert.False(authorityKeyIdentifier.Critical);
                Assert.Equal(authorityKeyIdentifier.SerialNumber, result.SerialNumber, ignoreCase: true);
                Assert.Equal(authorityKeyIdentifier.KeyId, subjectKeyId.SubjectKeyIdentifier, ignoreCase: true);
            }
        }
        public async Task <X509CertificateCollection> KeyVaultSigningRequestAsync()
        {
            Skip.If(!_fixture.KeyVaultInitOk);
            X509CertificateCollection certCollection = new X509CertificateCollection();

            string[] groups = await _keyVault.GetCertificateGroupIds();

            foreach (string group in groups)
            {
                var certificateGroupConfiguration = await _keyVault.GetCertificateGroupConfiguration(group);

                ApplicationTestData randomApp      = _fixture.RandomGenerator.RandomApplicationTestData();
                X509Certificate2    csrCertificate = CertificateFactory.CreateCertificate(
                    null, null, null,
                    randomApp.ApplicationRecord.ApplicationUri,
                    null,
                    randomApp.Subject,
                    randomApp.DomainNames.ToArray(),
                    certificateGroupConfiguration.DefaultCertificateKeySize,
                    DateTime.UtcNow.AddDays(-10),
                    certificateGroupConfiguration.DefaultCertificateLifetime,
                    certificateGroupConfiguration.DefaultCertificateHashSize
                    );
                byte[] certificateRequest = CertificateFactory.CreateSigningRequest(csrCertificate, randomApp.DomainNames);

                X509Certificate2 newCert = await _keyVault.SigningRequestAsync(
                    group,
                    randomApp.ApplicationRecord.ApplicationUri,
                    certificateRequest);

                // get issuer cert used for signing
                X509Certificate2Collection issuerCerts = await _keyVault.GetIssuerCACertificateChainAsync(group);

#if WRITECERT
                // save cert for debugging
                using (ICertificateStore store = CertificateStoreIdentifier.CreateStore(CertificateStoreType.Directory))
                {
                    Assert.NotNull(store);
                    store.Open("d:\\unittest");
                    await store.Add(newCert);

                    foreach (var cert in issuerCerts)
                    {
                        await store.Add(cert);
                    }
                }
#endif
                Assert.NotNull(issuerCerts);
                Assert.True(issuerCerts.Count >= 1);
                X509TestUtils.VerifySignedApplicationCert(randomApp, newCert, issuerCerts);
                certCollection.Add(newCert);
            }
            return(certCollection);
        }
        public async Task <X509CertificateCollection> KeyVaultNewKeyPairRequestAsync()
        {
            Skip.If(!_fixture.KeyVaultInitOk);
            X509CertificateCollection certCollection = new X509CertificateCollection();

            string[] groups = await _keyVault.GetCertificateGroupIds();

            foreach (string group in groups)
            {
                ApplicationTestData randomApp = _fixture.RandomGenerator.RandomApplicationTestData();
                Guid requestId = Guid.NewGuid();
                Opc.Ua.Gds.Server.X509Certificate2KeyPair newKeyPair = await _keyVault.NewKeyPairRequestAsync(
                    group,
                    requestId.ToString(),
                    randomApp.ApplicationRecord.ApplicationUri,
                    randomApp.Subject,
                    randomApp.DomainNames.ToArray(),
                    randomApp.PrivateKeyFormat,
                    randomApp.PrivateKeyPassword);

                Assert.NotNull(newKeyPair);
                Assert.False(newKeyPair.Certificate.HasPrivateKey);
                Assert.True(Opc.Ua.Utils.CompareDistinguishedName(randomApp.Subject, newKeyPair.Certificate.Subject));
                Assert.False(Opc.Ua.Utils.CompareDistinguishedName(newKeyPair.Certificate.Issuer, newKeyPair.Certificate.Subject));
                X509Certificate2Collection issuerCerts = await _keyVault.GetIssuerCACertificateChainAsync(group);

                Assert.NotNull(issuerCerts);
                Assert.True(issuerCerts.Count >= 1);

                X509TestUtils.VerifyApplicationCertIntegrity(
                    newKeyPair.Certificate,
                    newKeyPair.PrivateKey,
                    randomApp.PrivateKeyPassword,
                    randomApp.PrivateKeyFormat,
                    issuerCerts
                    );
                certCollection.Add(newKeyPair.Certificate);

                // disable and delete private key from KeyVault (requires set/delete rights)
                await _keyVault.AcceptPrivateKeyAsync(group, requestId.ToString());

                await _keyVault.DeletePrivateKeyAsync(group, requestId.ToString());
            }
            return(certCollection);
        }
        public async Task GetTrustListAsync()
        {
            Skip.If(!_fixture.KeyVaultInitOk);
            string[] groups = await _keyVault.GetCertificateGroupIds();

            foreach (string group in groups)
            {
                var trustList = await _keyVault.GetTrustListAsync(group, null, 2);

                string nextPageLink = trustList.NextPageLink;
                while (nextPageLink != null)
                {
                    var nextTrustList = await _keyVault.GetTrustListAsync(group, nextPageLink, 2);

                    trustList.AddRange(nextTrustList);
                    nextPageLink = nextTrustList.NextPageLink;
                }
                var validator = X509TestUtils.CreateValidatorAsync(trustList);
            }
        }
        public async Task CreateCAAndAppCertificatesThenRevokeAll()
        {
            Skip.If(!_fixture.KeyVaultInitOk);
            X509Certificate2Collection certCollection = new X509Certificate2Collection();

            for (int i = 0; i < 3; i++)
            {
                await KeyVaultCreateCACertificateAsync();

                for (int v = 0; v < 10; v++)
                {
                    certCollection.AddRange(await KeyVaultSigningRequestAsync());
                    certCollection.AddRange(await KeyVaultNewKeyPairRequestAsync());
                }
            }

            string[] groups = await _keyVault.GetCertificateGroupIds();

            // validate all certificates
            foreach (string group in groups)
            {
                var trustList = await _keyVault.GetTrustListAsync(group);

                string nextPageLink = trustList.NextPageLink;
                while (nextPageLink != null)
                {
                    var nextTrustList = await _keyVault.GetTrustListAsync(group, nextPageLink);

                    trustList.AddRange(nextTrustList);
                    nextPageLink = nextTrustList.NextPageLink;
                }
                var validator = await X509TestUtils.CreateValidatorAsync(trustList);

                foreach (var cert in certCollection)
                {
                    validator.Validate(cert);
                }
            }

            // now revoke all certifcates
            var revokeCertificates = new X509Certificate2Collection(certCollection);

            foreach (string group in groups)
            {
                var unrevokedCertificates = await _keyVault.RevokeCertificatesAsync(group, revokeCertificates);

                Assert.True(unrevokedCertificates.Count <= revokeCertificates.Count);
                revokeCertificates = unrevokedCertificates;
            }
            Assert.Empty(revokeCertificates);

            // reload updated trust list from KeyVault
            var trustListAllGroups = new KeyVaultTrustListModel("all");

            foreach (string group in groups)
            {
                var trustList = await _keyVault.GetTrustListAsync(group);

                string nextPageLink = trustList.NextPageLink;
                while (nextPageLink != null)
                {
                    var nextTrustList = await _keyVault.GetTrustListAsync(group, nextPageLink);

                    trustList.AddRange(nextTrustList);
                    nextPageLink = nextTrustList.NextPageLink;
                }
                trustListAllGroups.AddRange(trustList);
            }

            // verify certificates are revoked
            {
                var validator = await X509TestUtils.CreateValidatorAsync(trustListAllGroups);

                foreach (var cert in certCollection)
                {
                    Assert.Throws <Opc.Ua.ServiceResultException>(() =>
                    {
                        validator.Validate(cert);
                    });
                }
            }
        }
        public async Task KeyVaultNewKeyPairLoadThenDeletePrivateKeyAsync()
        {
            Skip.If(!_fixture.KeyVaultInitOk);
            string[] groups = await _keyVault.GetCertificateGroupIds();

            foreach (string group in groups)
            {
                ApplicationTestData randomApp = _fixture.RandomGenerator.RandomApplicationTestData();
                Guid requestId = Guid.NewGuid();
                Opc.Ua.Gds.Server.X509Certificate2KeyPair newKeyPair = await _keyVault.NewKeyPairRequestAsync(
                    group,
                    requestId.ToString(),
                    randomApp.ApplicationRecord.ApplicationUri,
                    randomApp.Subject,
                    randomApp.DomainNames.ToArray(),
                    randomApp.PrivateKeyFormat,
                    randomApp.PrivateKeyPassword
                    );

                Assert.NotNull(newKeyPair);
                Assert.False(newKeyPair.Certificate.HasPrivateKey);
                Assert.True(Opc.Ua.Utils.CompareDistinguishedName(randomApp.Subject, newKeyPair.Certificate.Subject));
                Assert.False(Opc.Ua.Utils.CompareDistinguishedName(newKeyPair.Certificate.Issuer, newKeyPair.Certificate.Subject));

                X509Certificate2Collection issuerCerts = await _keyVault.GetIssuerCACertificateChainAsync(group);

                Assert.NotNull(issuerCerts);
                Assert.True(issuerCerts.Count >= 1);

                X509TestUtils.VerifyApplicationCertIntegrity(
                    newKeyPair.Certificate,
                    newKeyPair.PrivateKey,
                    randomApp.PrivateKeyPassword,
                    randomApp.PrivateKeyFormat,
                    issuerCerts
                    );

                // test to load the key from KeyVault
                var privateKey = await _keyVault.LoadPrivateKeyAsync(group, requestId.ToString(), randomApp.PrivateKeyFormat);

                X509Certificate2 privateKeyX509;
                if (randomApp.PrivateKeyFormat == "PFX")
                {
                    privateKeyX509 = CertificateFactory.CreateCertificateFromPKCS12(privateKey, randomApp.PrivateKeyPassword);
                }
                else
                {
                    privateKeyX509 = CertificateFactory.CreateCertificateWithPEMPrivateKey(newKeyPair.Certificate, privateKey, randomApp.PrivateKeyPassword);
                }
                Assert.True(privateKeyX509.HasPrivateKey);

                X509TestUtils.VerifyApplicationCertIntegrity(
                    newKeyPair.Certificate,
                    privateKey,
                    randomApp.PrivateKeyPassword,
                    randomApp.PrivateKeyFormat,
                    issuerCerts
                    );

                await _keyVault.AcceptPrivateKeyAsync(group, requestId.ToString());

                await Assert.ThrowsAsync <KeyVaultErrorException>(async() =>
                {
                    privateKey = await _keyVault.LoadPrivateKeyAsync(group, requestId.ToString(), randomApp.PrivateKeyFormat);
                });

                await _keyVault.AcceptPrivateKeyAsync(group, requestId.ToString());

                await _keyVault.DeletePrivateKeyAsync(group, requestId.ToString());

                await Assert.ThrowsAsync <KeyVaultErrorException>(async() =>
                {
                    await _keyVault.DeletePrivateKeyAsync(group, requestId.ToString());
                });

                await Assert.ThrowsAsync <KeyVaultErrorException>(async() =>
                {
                    privateKey = await _keyVault.LoadPrivateKeyAsync(group, requestId.ToString(), randomApp.PrivateKeyFormat);
                });
            }
        }