private async Task GetAllApplications()
        {
            await Assert.ThrowsAsync <ArgumentNullException>(async() =>
            {
                await _applicationsDatabase.GetApplicationAsync(null);
            });

            await Assert.ThrowsAsync <ArgumentException>(async() =>
            {
                await _applicationsDatabase.GetApplicationAsync(Guid.Empty.ToString());
            });

            await Assert.ThrowsAsync <ArgumentException>(async() =>
            {
                await _applicationsDatabase.GetApplicationAsync("abc");
            });

            await Assert.ThrowsAsync <ResourceNotFoundException>(async() =>
            {
                await _applicationsDatabase.GetApplicationAsync(Guid.NewGuid().ToString());
            });

            Skip.If(!_fixture.RegistrationOk);
            foreach (var application in _applicationTestSet)
            {
                var applicationModel = await _applicationsDatabase.GetApplicationAsync(application.Model.ApplicationId.ToString());

                Assert.NotNull(applicationModel);
                Assert.NotEqual(applicationModel.ApplicationId, Guid.Empty);
                Assert.Equal(applicationModel.ApplicationId, applicationModel.ApplicationId);
                ApplicationTestData.AssertEqualApplicationModelData(applicationModel, application.Model);
            }
        }
        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);
        }
Example #3
0
        private async Task RegisterAllApplications()
        {
            foreach (var application in _applicationTestSet)
            {
                var applicationModel = await _applicationsDatabase.RegisterApplicationAsync(application.Model);

                Assert.NotNull(applicationModel);
                Assert.NotEqual(applicationModel.ApplicationId, Guid.Empty);
                ApplicationTestData.AssertEqualApplicationModelData(applicationModel, application.Model);
                application.Model = applicationModel;
                Assert.NotNull(applicationModel);
            }
            _fixture.RegistrationOk = true;
        }
        private async Task RegisterAllApplicationsThrow()
        {
            await Assert.ThrowsAsync <ArgumentNullException>(async() =>
            {
                await _applicationsDatabase.RegisterApplicationAsync(null);
            });

            await Assert.ThrowsAsync <ResourceNotFoundException>(async() =>
            {
                var testModelCopy           = ApplicationTestData.ApplicationDeepCopy(_applicationTestSet[0].Model);
                testModelCopy.ApplicationId = Guid.NewGuid();
                await _applicationsDatabase.RegisterApplicationAsync(testModelCopy);
            });
        }
        private async Task UnregisteredGetAllApplicationsNot()
        {
            Skip.If(!_fixture.RegistrationOk);
            foreach (var application in _applicationTestSet)
            {
                var applicationModel = await _applicationsDatabase.GetApplicationAsync(application.Model.ApplicationId.ToString());

                Assert.NotNull(applicationModel);
                Assert.NotEqual(applicationModel.ApplicationId, Guid.Empty);
                Assert.Equal(applicationModel.ApplicationId, applicationModel.ApplicationId);
                Assert.Equal(ApplicationState.Unregistered, applicationModel.ApplicationState);
                Assert.NotNull(applicationModel.DeleteTime);
                ApplicationTestData.AssertEqualApplicationModelData(applicationModel, application.Model);
            }
        }
        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 KeyVaultNewKeyPairAndRevokeCertificateAsync()
        {
            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 newCert = await _keyVault.NewKeyPairRequestAsync(
                    group,
                    requestId.ToString(),
                    randomApp.ApplicationRecord.ApplicationUri,
                    randomApp.Subject,
                    randomApp.DomainNames.ToArray(),
                    randomApp.PrivateKeyFormat,
                    randomApp.PrivateKeyPassword
                    );

                Assert.NotNull(newCert);
                Assert.False(newCert.Certificate.HasPrivateKey);
                Assert.True(Opc.Ua.Utils.CompareDistinguishedName(randomApp.Subject, newCert.Certificate.Subject));
                Assert.False(Opc.Ua.Utils.CompareDistinguishedName(newCert.Certificate.Issuer, newCert.Certificate.Subject));
                X509Certificate2 cert = new X509Certificate2(newCert.Certificate.RawData);
                X509CRL          crl  = await _keyVault.RevokeCertificateAsync(group, cert);

                Assert.NotNull(crl);
                X509Certificate2Collection caChain = await _keyVault.GetIssuerCACertificateChainAsync(group);

                Assert.NotNull(caChain);
                X509Certificate2 caCert = caChain[0];
                Assert.False(caCert.HasPrivateKey);
                crl.VerifySignature(caCert, true);
                Assert.True(Opc.Ua.Utils.CompareDistinguishedName(crl.Issuer, caCert.Issuer));
                // disable and delete private key from KeyVault (requires set/delete rights)
                await _keyVault.AcceptPrivateKeyAsync(group, requestId.ToString());

                await _keyVault.DeletePrivateKeyAsync(group, requestId.ToString());
            }
        }
        public ApplicationTestData RandomApplicationTestData()
        {
            Opc.Ua.ApplicationType appType = (Opc.Ua.ApplicationType)_randomSource.NextInt32((int)Opc.Ua.ApplicationType.ClientAndServer);
            string pureAppName             = _dataGenerator.GetRandomString("en");

            pureAppName = Regex.Replace(pureAppName, @"[^\w\d\s]", "");
            string           pureAppUri         = Regex.Replace(pureAppName, @"[^\w\d]", "");
            string           appName            = "UA " + pureAppName;
            StringCollection domainNames        = RandomDomainNames();
            string           localhost          = domainNames[0];
            string           privateKeyFormat   = _randomSource.NextInt32(1) == 0 ? "PEM" : "PFX";
            string           appUri             = ("urn:localhost:opcfoundation.org:" + pureAppUri.ToLower()).Replace("localhost", localhost);
            string           prodUri            = "http://opcfoundation.org/UA/" + pureAppUri;
            StringCollection discoveryUrls      = new StringCollection();
            StringCollection serverCapabilities = new StringCollection();

            switch (appType)
            {
            case Opc.Ua.ApplicationType.Client:
                appName += " Client";
                break;

            case Opc.Ua.ApplicationType.ClientAndServer:
                appName += " Client and";
                goto case Opc.Ua.ApplicationType.Server;

            case Opc.Ua.ApplicationType.Server:
                appName += " Server";
                int port = (_dataGenerator.GetRandomInt16() & 0x1fff) + 50000;
                discoveryUrls      = RandomDiscoveryUrl(domainNames, port, pureAppUri);
                serverCapabilities = RandomServerCapabilities();
                break;
            }
            ApplicationTestData testData = new ApplicationTestData
            {
                Model = new Application
                {
                    ApplicationUri     = appUri,
                    ApplicationName    = appName,
                    ApplicationType    = (Types.ApplicationType)appType,
                    ProductUri         = prodUri,
                    ServerCapabilities = ApplicationTestData.ServerCapabilities(serverCapabilities.ToArray()),
                    ApplicationNames   = new ApplicationName[] { new ApplicationName {
                                                                     Locale = "en-us", Text = appName
                                                                 } },
                    DiscoveryUrls = discoveryUrls.ToArray()
                },
                ApplicationRecord = new ApplicationRecordDataType
                {
                    ApplicationNames = new LocalizedTextCollection {
                        new LocalizedText("en-us", appName)
                    },
                    ApplicationUri     = appUri,
                    ApplicationType    = appType,
                    ProductUri         = prodUri,
                    DiscoveryUrls      = discoveryUrls,
                    ServerCapabilities = serverCapabilities
                },
                DomainNames      = domainNames,
                Subject          = string.Format("CN={0},DC={1},O=OPC Foundation", appName, localhost),
                PrivateKeyFormat = privateKeyFormat,
                RequestIds       = new List <string>()
            };

            return(testData);
        }
        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);
                });
            }
        }
        private async Task ApproveAllApplications()
        {
            await Assert.ThrowsAsync <ArgumentNullException>(async() =>
            {
                await _applicationsDatabase.ApproveApplicationAsync(null, false, false);
            });

            await Assert.ThrowsAsync <ArgumentException>(async() =>
            {
                await _applicationsDatabase.ApproveApplicationAsync(Guid.Empty.ToString(), false, false);
            });

            Skip.If(!_fixture.RegistrationOk);
            int fullPasses = 0;

            foreach (var application in _applicationTestSet)
            {
                // read model to get state
                var applicationModel = await _applicationsDatabase.GetApplicationAsync(application.Model.ApplicationId.ToString());

                if (applicationModel.ApplicationState == ApplicationState.New)
                {
                    // approve app
                    applicationModel = await _applicationsDatabase.ApproveApplicationAsync(application.Model.ApplicationId.ToString(), true, false);

                    Assert.NotNull(applicationModel);
                    Assert.Equal(ApplicationState.Approved, applicationModel.ApplicationState);
                }

                // verify start condition
                if (applicationModel.ApplicationState != ApplicationState.Approved)
                {
                    continue;
                }

                // reject approved app should fail
                await Assert.ThrowsAsync <ResourceInvalidStateException>(async() =>
                {
                    await _applicationsDatabase.ApproveApplicationAsync(application.Model.ApplicationId.ToString(), false, false);
                });

                // force approved app to rejected state
                applicationModel = await _applicationsDatabase.ApproveApplicationAsync(application.Model.ApplicationId.ToString(), false, true);

                Assert.NotNull(applicationModel);
                Assert.NotEqual(applicationModel.ApplicationId, Guid.Empty);
                Assert.Equal(ApplicationState.Rejected, applicationModel.ApplicationState);
                ApplicationTestData.AssertEqualApplicationModelData(applicationModel, application.Model);

                // approve rejected app should fail
                await Assert.ThrowsAsync <ResourceInvalidStateException>(async() =>
                {
                    await _applicationsDatabase.ApproveApplicationAsync(application.Model.ApplicationId.ToString(), true, false);
                });

                // force approve of rejected app
                applicationModel = await _applicationsDatabase.ApproveApplicationAsync(application.Model.ApplicationId.ToString(), true, true);

                Assert.NotNull(applicationModel);
                Assert.NotEqual(applicationModel.ApplicationId, Guid.Empty);
                Assert.Equal(ApplicationState.Approved, applicationModel.ApplicationState);
                ApplicationTestData.AssertEqualApplicationModelData(applicationModel, application.Model);
                fullPasses++;
            }
            // not enough test passes to verify
            Skip.If(fullPasses < _applicationTestSet.Count / 2);
        }
        public static void VerifySignedApplicationCert(ApplicationTestData testApp, X509Certificate2 signedCert, X509Certificate2Collection issuerCerts)
        {
            X509Certificate2 issuerCert = issuerCerts[0];

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

            // test basic constraints
            var constraints = FindBasicConstraintsExtension(signedCert);

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

            // key usage
            var keyUsage = FindKeyUsageExtension(signedCert);

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

            // enhanced key usage
            var enhancedKeyUsage = FindEnhancedKeyUsageExtension(signedCert);

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

            // test for authority key
            X509AuthorityKeyIdentifierExtension authority = FindAuthorityKeyIdentifier(signedCert);

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

            // verify authority key in signed cert
            X509SubjectKeyIdentifierExtension subjectKeyId = FindSubjectKeyIdentifierExtension(issuerCert);

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

            X509SubjectAltNameExtension subjectAlternateName = FindSubjectAltName(signedCert);

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

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

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

            CertificateIdentifierCollection issuerCertIdCollection = new CertificateIdentifierCollection();

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

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

            trustedStore.TrustedCertificates = issuerCertIdCollection;
            certValidator.Update(trustedStore, issuerStore, null);
            Assert.Throws <Opc.Ua.ServiceResultException>(() =>
            {
                certValidator.Validate(signedCert);
            });
            issuerStore.TrustedCertificates = issuerCertIdCollection;
            certValidator.Update(issuerStore, trustedStore, null);
            certValidator.Validate(signedCert);
        }