/// <summary>
        /// Returns the certificate information for a trusted issuer certificate.
        /// </summary>
        private async Task <CertificateIdentifier> GetIssuer(
            X509Certificate2 certificate,
            CertificateIdentifierCollection explicitList,
            CertificateStoreIdentifier certificateStore,
            bool checkRecovationStatus)
        {
            // check if self-signed.
            if (X509Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer))
            {
                return(null);
            }

            string subjectName  = certificate.IssuerName.Name;
            string keyId        = null;
            string serialNumber = null;

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

            if (authority != null)
            {
                keyId        = authority.KeyIdentifier;
                serialNumber = authority.SerialNumber;
            }

            // check in explicit list.
            if (explicitList != null)
            {
                for (int ii = 0; ii < explicitList.Count; ii++)
                {
                    X509Certificate2 issuer = await explicitList[ii].Find(false);

                    if (issuer != null)
                    {
                        if (!X509Utils.IsIssuerAllowed(issuer))
                        {
                            continue;
                        }

                        if (Match(issuer, subjectName, serialNumber, keyId))
                        {
                            // can't check revocation.
                            return(new CertificateIdentifier(issuer, CertificateValidationOptions.SuppressRevocationStatusUnknown));
                        }
                    }
                }
            }

            // check in certificate store.
            if (certificateStore != null)
            {
                ICertificateStore store = certificateStore.OpenStore();

                try
                {
                    X509Certificate2Collection certificates = await store.Enumerate();

                    for (int ii = 0; ii < certificates.Count; ii++)
                    {
                        X509Certificate2 issuer = certificates[ii];

                        if (issuer != null)
                        {
                            if (!X509Utils.IsIssuerAllowed(issuer))
                            {
                                continue;
                            }

                            if (Match(issuer, subjectName, serialNumber, keyId))
                            {
                                CertificateValidationOptions options = certificateStore.ValidationOptions;

                                // already checked revocation for file based stores. windows based stores always suppress.
                                options |= CertificateValidationOptions.SuppressRevocationStatusUnknown;

                                if (checkRecovationStatus)
                                {
                                    StatusCode status = store.IsRevoked(issuer, certificate);

                                    if (StatusCode.IsBad(status) && status != StatusCodes.BadNotSupported)
                                    {
                                        if (status == StatusCodes.BadCertificateRevocationUnknown)
                                        {
                                            if (X509Utils.IsCertificateAuthority(certificate))
                                            {
                                                status.Code = StatusCodes.BadCertificateIssuerRevocationUnknown;
                                            }

                                            if (m_rejectUnknownRevocationStatus)
                                            {
                                                throw new ServiceResultException(status);
                                            }
                                        }
                                        else
                                        {
                                            throw new ServiceResultException(status);
                                        }
                                    }
                                }

                                return(new CertificateIdentifier(certificates[ii], options));
                            }
                        }
                    }
                }
                finally
                {
                    store.Close();
                }
            }

            // not a trusted issuer.
            return(null);
        }
Ejemplo n.º 2
0
        private ServiceResult Open(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            OpenFileMode mode,
            TrustListMasks masks,
            ref uint fileHandle)
        {
            HasSecureReadAccess(context);

            if (mode == OpenFileMode.Read)
            {
                HasSecureReadAccess(context);
            }
            else if (mode == (OpenFileMode.Write | OpenFileMode.EraseExisting))
            {
                HasSecureWriteAccess(context);
            }
            else
            {
                return(StatusCodes.BadNotWritable);
            }

            lock (m_lock)
            {
                if (m_sessionId != null)
                {
                    // to avoid deadlocks, last open always wins
                    m_sessionId            = null;
                    m_strm                 = null;
                    m_node.OpenCount.Value = 0;
                }

                m_readMode  = mode == OpenFileMode.Read;
                m_sessionId = context.SessionId;
                fileHandle  = ++m_fileHandle;

                TrustListDataType trustList = new TrustListDataType()
                {
                    SpecifiedLists = (uint)masks
                };

                using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_trustedStorePath))
                {
                    if ((masks & TrustListMasks.TrustedCertificates) != 0)
                    {
                        X509Certificate2Collection certificates = store.Enumerate().Result;
                        foreach (var certificate in certificates)
                        {
                            trustList.TrustedCertificates.Add(certificate.RawData);
                        }
                    }

                    if ((masks & TrustListMasks.TrustedCrls) != 0)
                    {
                        foreach (var crl in store.EnumerateCRLs())
                        {
                            trustList.TrustedCrls.Add(crl.RawData);
                        }
                    }
                }

                using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_issuerStorePath))
                {
                    if ((masks & TrustListMasks.IssuerCertificates) != 0)
                    {
                        X509Certificate2Collection certificates = store.Enumerate().Result;
                        foreach (var certificate in certificates)
                        {
                            trustList.IssuerCertificates.Add(certificate.RawData);
                        }
                    }

                    if ((masks & TrustListMasks.IssuerCrls) != 0)
                    {
                        foreach (var crl in store.EnumerateCRLs())
                        {
                            trustList.IssuerCrls.Add(crl.RawData);
                        }
                    }
                }

                if (m_readMode)
                {
                    m_strm = EncodeTrustListData(context, trustList);
                }
                else
                {
                    m_strm = new MemoryStream(DefaultTrustListCapacity);
                }

                m_node.OpenCount.Value = 1;
            }

            return(ServiceResult.Good);
        }
        private ServiceResult ApplyChanges(
            ISystemContext context,
            MethodState method,
            IList <object> inputArguments,
            IList <object> outputArguments)
        {
            HasApplicationSecureAdminAccess(context);

            bool disconnectSessions = false;

            foreach (var certificateGroup in m_certificateGroups)
            {
                try
                {
                    var updateCertificate = certificateGroup.UpdateCertificate;
                    if (updateCertificate != null)
                    {
                        if (certificateGroup.UpdateCertificate.SessionId == context.SessionId)
                        {
                            using (ICertificateStore appStore = CertificateStoreIdentifier.OpenStore(certificateGroup.ApplicationCertificate.StorePath))
                            {
                                appStore.Delete(certificateGroup.ApplicationCertificate.Thumbprint).Wait();
                                appStore.Add(updateCertificate.CertificateWithPrivateKey).Wait();
                                updateCertificate.CertificateWithPrivateKey = null;
                            }
                            using (ICertificateStore issuerStore = CertificateStoreIdentifier.OpenStore(certificateGroup.IssuerStorePath))
                            {
                                foreach (var issuer in updateCertificate.IssuerCollection)
                                {
                                    try
                                    {
                                        issuerStore.Add(issuer).Wait();
                                    }
                                    catch (ArgumentException)
                                    {
                                        // ignore error if issuer cert already exists
                                    }
                                }
                            }

                            disconnectSessions = true;
                        }
                    }
                }
                finally
                {
                    certificateGroup.UpdateCertificate = null;
                }
            }

            if (disconnectSessions)
            {
                Task.Run(async() =>
                {
                    // give the client some time to receive the response
                    // before the certificate update may disconnect all sessions
                    await Task.Delay(1000);
                    await m_configuration.CertificateValidator.UpdateCertificate(m_configuration.SecurityConfiguration);
                }
                         );
            }

            return(StatusCodes.Good);
        }
        /// <summary>
        /// Creates a self signed application instance certificate.
        /// </summary>
        /// <param name="storeType">Type of certificate store (Directory) <see cref="CertificateStoreType"/>.</param>
        /// <param name="storePath">The store path (syntax depends on storeType).</param>
        /// <param name="password">The password to use to protect the certificate.</param>
        /// <param name="applicationUri">The application uri (created if not specified).</param>
        /// <param name="applicationName">Name of the application (optional if subjectName is specified).</param>
        /// <param name="subjectName">The subject used to create the certificate (optional if applicationName is specified).</param>
        /// <param name="domainNames">The domain names that can be used to access the server machine (defaults to local computer name if not specified).</param>
        /// <param name="keySize">Size of the key (1024, 2048 or 4096).</param>
        /// <param name="startTime">The start time.</param>
        /// <param name="lifetimeInMonths">The lifetime of the key in months.</param>
        /// <param name="hashSizeInBits">The hash size in bits.</param>
        /// <param name="isCA">if set to <c>true</c> then a CA certificate is created.</param>
        /// <param name="issuerCAKeyCert">The CA cert with the CA private key.</param>
        /// <returns>The certificate with a private key.</returns>
        public static X509Certificate2 CreateCertificate(
            string storeType,
            string storePath,
            string password,
            string applicationUri,
            string applicationName,
            string subjectName,
            IList <String> domainNames,
            ushort keySize,
            DateTime startTime,
            ushort lifetimeInMonths,
            ushort hashSizeInBits,
            bool isCA,
            X509Certificate2 issuerCAKeyCert)
        {
            if (issuerCAKeyCert != null)
            {
                if (!issuerCAKeyCert.HasPrivateKey)
                {
                    throw new NotSupportedException("Cannot sign with a CA certificate without a private key.");
                }

                throw new NotSupportedException("Signing with an issuer CA certificate is currently unsupported.");
            }

            // set default values.
            SetSuitableDefaults(
                ref applicationUri,
                ref applicationName,
                ref subjectName,
                ref domainNames,
                ref keySize,
                ref lifetimeInMonths,
                isCA);

            // cert generators
            SecureRandom random           = new SecureRandom();
            X509V3CertificateGenerator cg = new X509V3CertificateGenerator();

            // Serial Number
            BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);

            cg.SetSerialNumber(serialNumber);

            // build name attributes
            var nameOids = new ArrayList();

            nameOids.Add(X509Name.DC);
            nameOids.Add(X509Name.CN);

            var nameValues = new ArrayList();

            nameValues.Add(domainNames[0]);
            nameValues.Add(subjectName);

            // self signed
            X509Name subjectDN = new X509Name(nameOids, nameValues);
            X509Name issuerDN  = subjectDN;

            cg.SetIssuerDN(issuerDN);
            cg.SetSubjectDN(subjectDN);

            // valid for
            cg.SetNotBefore(startTime);
            cg.SetNotAfter(startTime.AddMonths(lifetimeInMonths));

            // Private/Public Key
            AsymmetricCipherKeyPair subjectKeyPair;
            var keyGenerationParameters = new KeyGenerationParameters(random, keySize);
            var keyPairGenerator        = new RsaKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);
            subjectKeyPair = keyPairGenerator.GenerateKeyPair();
            cg.SetPublicKey(subjectKeyPair.Public);

            // add extensions
            // Subject key identifier
            cg.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false,
                            new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public)));

            // Basic constraints
            cg.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(isCA));

            // Authority Key identifier
            var issuerKeyPair      = subjectKeyPair;
            var issuerSerialNumber = serialNumber;

            cg.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false,
                            new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public),
                                                       new GeneralNames(new GeneralName(issuerDN)), issuerSerialNumber));

            if (!isCA)
            {
                // Key usage
                cg.AddExtension(X509Extensions.KeyUsage, true,
                                new KeyUsage(KeyUsage.DataEncipherment | KeyUsage.DigitalSignature |
                                             KeyUsage.NonRepudiation | KeyUsage.KeyCertSign | KeyUsage.KeyEncipherment));

                // Extended Key usage
                cg.AddExtension(X509Extensions.ExtendedKeyUsage, true,
                                new ExtendedKeyUsage(new List <DerObjectIdentifier>()
                {
                    new DerObjectIdentifier("1.3.6.1.5.5.7.3.1"), // server auth
                    new DerObjectIdentifier("1.3.6.1.5.5.7.3.2"), // client auth
                }));

                // subject alternate name
                cg.AddExtension(X509Extensions.SubjectAlternativeName, false,
                                new GeneralNames(new GeneralName[] {
                    new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri),
                    new GeneralName(GeneralName.DnsName, domainNames[0])
                }));
            }
            else
            {
                // Key usage CA
                cg.AddExtension(X509Extensions.KeyUsage, true,
                                new KeyUsage(KeyUsage.CrlSign | KeyUsage.DigitalSignature | KeyUsage.KeyCertSign));
            }

            // sign certificate
            ISignatureFactory signatureFactory =
                new Asn1SignatureFactory((hashSizeInBits < 256) ? "SHA1WITHRSA" : "SHA256WITHRSA", subjectKeyPair.Private, random);

            Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory);

            // create pkcs12 store for cert and private key
            X509Certificate2 certificate = null;

            using (MemoryStream pfxData = new MemoryStream())
            {
                Pkcs12Store            pkcsStore = new Pkcs12StoreBuilder().Build();
                X509CertificateEntry[] chain     = new X509CertificateEntry[1];
                string passcode = "passcode";
                chain[0] = new X509CertificateEntry(x509);
                pkcsStore.SetKeyEntry(applicationName, new AsymmetricKeyEntry(subjectKeyPair.Private), chain);
                pkcsStore.Save(pfxData, passcode.ToCharArray(), random);

                // merge into X509Certificate2
                certificate = CreateCertificateFromPKCS12(pfxData.ToArray(), passcode);
            }

            Utils.Trace(Utils.TraceMasks.Security, "Created new certificate: {0}", certificate.Thumbprint);

            // add cert to the store.
            if (!String.IsNullOrEmpty(storePath))
            {
                ICertificateStore store = null;
                if (storeType == CertificateStoreType.X509Store)
                {
                    store = new X509CertificateStore();
                }
                else if (storeType == CertificateStoreType.Directory)
                {
                    store = new DirectoryCertificateStore();
                }
                else
                {
                    throw new ArgumentException("Invalid store type");
                }

                store.Open(storePath);
                store.Add(certificate, password);
                store.Close();
                store.Dispose();
            }

            // note: this cert has a private key!
            return(certificate);
        }
Ejemplo n.º 5
0
 public AcmeClient(IDnsProvider dnsProvider, DnsLookupService dnsLookupService, ICertificateStore certifcateStore, ILogger <AcmeClient> logger = null)
 {
     this.dnsProvider      = dnsProvider;
     this.dnsLookupService = dnsLookupService;
     this.certificateStore = certifcateStore;
     this.logger           = logger ?? NullLogger <AcmeClient> .Instance;
 }
Ejemplo n.º 6
0
        private void OkBTN_Click(object sender, EventArgs e)
        {
            try
            {
                string storeType             = null;
                string storePath             = null;
                string domainName            = null;
                string organization          = null;
                string subjectName           = SubjectNameTB.Text.Trim();
                string issuerKeyFilePath     = IssuerKeyFilePathTB.Text.Trim();
                string issuerKeyFilePassword = IssuerPasswordTB.Text.Trim();

                if (String.IsNullOrEmpty(issuerKeyFilePath))
                {
                    throw new ApplicationException("Must provide an issuer certificate.");
                }

                // verify certificate.
                X509Certificate2 issuer = new X509Certificate2(
                    issuerKeyFilePath,
                    issuerKeyFilePassword,
                    X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

                if (!issuer.HasPrivateKey)
                {
                    throw new ApplicationException("Issuer certificate does not have a private key.");
                }

                // determine certificate type.
                foreach (X509Extension extension in issuer.Extensions)
                {
                    X509BasicConstraintsExtension basicContraints = extension as X509BasicConstraintsExtension;

                    if (basicContraints != null)
                    {
                        if (!basicContraints.CertificateAuthority)
                        {
                            throw new ApplicationException("Certificate cannot be used to issue new certificates.");
                        }
                    }
                }

                // check traget store.
                if (!String.IsNullOrEmpty(CertificateStoreCTRL.StorePath))
                {
                    storeType = CertificateStoreCTRL.StoreType;
                    storePath = CertificateStoreCTRL.StorePath;
                }

                if (String.IsNullOrEmpty(storePath))
                {
                    throw new ApplicationException("Please specify a store path.");
                }

                domainName   = DomainNameTB.Text;
                organization = OrganizationTB.Text;

                // extract key fields from the subject name.
                if (SubjectNameCK.Checked)
                {
                    List <string> parts = Utils.ParseDistinguishedName(SubjectNameTB.Text);

                    for (int ii = 0; ii < parts.Count; ii++)
                    {
                        if (parts[ii].StartsWith("CN="))
                        {
                            domainName = parts[ii].Substring(3).Trim();
                        }

                        if (parts[ii].StartsWith("O="))
                        {
                            organization = parts[ii].Substring(2).Trim();
                        }
                    }
                }

                if (String.IsNullOrEmpty(domainName))
                {
                    throw new ApplicationException("Please specify a domain name.");
                }

                if (!String.IsNullOrEmpty(DomainNameTB.Text) && domainName != DomainNameTB.Text)
                {
                    throw new ApplicationException("The domain name must be the common name for the certificate.");
                }

                if (!String.IsNullOrEmpty(OrganizationTB.Text) && organization != OrganizationTB.Text)
                {
                    throw new ApplicationException("The organization must be the organization for the certificate.");
                }

                X509Certificate2 certificate = Opc.Ua.CertificateFactory.CreateCertificate(
                    storeType,
                    storePath,
                    null,
                    null,
                    domainName,
                    subjectName,
                    null,
                    Convert.ToUInt16(KeySizeCB.SelectedItem.ToString()),
                    DateTime.MinValue,
                    (ushort)LifeTimeInMonthsUD.Value,
                    0,
                    false,
                    false,
                    issuerKeyFilePath,
                    issuerKeyFilePassword);

                m_certificate             = new CertificateIdentifier();
                m_certificate.StoreType   = storeType;
                m_certificate.StorePath   = storePath;
                m_certificate.Certificate = certificate;

                try
                {
                    CertificateStoreIdentifier rootStore = new CertificateStoreIdentifier();
                    rootStore.StoreType = CertificateStoreType.Windows;
                    rootStore.StorePath = "LocalMachine\\Root";

                    using (ICertificateStore store = rootStore.OpenStore())
                    {
                        X509Certificate2 rootCertificate = new X509Certificate2(issuerKeyFilePath, issuerKeyFilePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

                        if (store.FindByThumbprint(rootCertificate.Thumbprint) == null)
                        {
                            if (Ask("Would you like to install the signing certificate as a trusted root authority on this machine?"))
                            {
                                store.Add(new X509Certificate2(rootCertificate.RawData));
                            }
                        }
                    }
                }
                catch (Exception exception)
                {
                    GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
                }

                // close the dialog.
                DialogResult = DialogResult.OK;
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
            }
        }
Ejemplo n.º 7
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 = PEMWriter.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 (m_application.GetPrivateKeyFormat(m_server?.GetSupportedKeyFormats()) == "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 = X509PfxUtils.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 (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,
                        m_server.ApplicationCertificateType,
                        certificate,
                        (privateKeyPFX != null) ? "PFX" : null,
                        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;
                    }
                }

                CertificateControl.ShowValue(null, "Application Certificate", new CertificateWrapper()
                {
                    Certificate = m_certificate
                }, true);
            }
            catch (Exception exception)
            {
                if (exception is ServiceResultException sre && sre.StatusCode == StatusCodes.BadNothingToDo)
                {
                    return;
                }

                RequestProgressLabel.Visible    = false;
                CertificateRequestTimer.Enabled = false;
                Opc.Ua.Client.Controls.ExceptionDlg.Show(Text, exception);
            }
        }
 public SubscriptionCloudCredentialsFactory(ICertificateStore certificateStore)
 {
     this.certificateStore = certificateStore;
 }
Ejemplo n.º 9
0
    /// <summary>
    /// Creates a self signed application instance certificate.
    /// </summary>
    /// <param name="storeType">Type of certificate store (Directory) <see cref="CertificateStoreType"/>.</param>
    /// <param name="storePath">The store path (syntax depends on storeType).</param>
    /// <param name="password">The password to use to protect the certificate.</param>
    /// <param name="applicationUri">The application uri (created if not specified).</param>
    /// <param name="applicationName">Name of the application (optional if subjectName is specified).</param>
    /// <param name="subjectName">The subject used to create the certificate (optional if applicationName is specified).</param>
    /// <param name="domainNames">The domain names that can be used to access the server machine (defaults to local computer name if not specified).</param>
    /// <param name="keySize">Size of the key (1024, 2048 or 4096).</param>
    /// <param name="startTime">The start time.</param>
    /// <param name="lifetimeInMonths">The lifetime of the key in months.</param>
    /// <param name="hashSizeInBits">The hash size in bits.</param>
    /// <param name="isCA">if set to <c>true</c> then a CA certificate is created.</param>
    /// <param name="issuerCAKeyCert">The CA cert with the CA private key.</param>
    /// <returns>The certificate with a private key.</returns>
    public static X509Certificate2 CreateCertificate(
        string storeType,
        string storePath,
        string password,
        string applicationUri,
        string applicationName,
        string subjectName,
        IList <String> domainNames,
        ushort keySize,
        DateTime startTime,
        ushort lifetimeInMonths,
        ushort hashSizeInBits,
        bool isCA = false,
        X509Certificate2 issuerCAKeyCert = null,
        byte[] publicKey = null)
    {
        if (issuerCAKeyCert != null)
        {
            if (!issuerCAKeyCert.HasPrivateKey)
            {
                throw new NotSupportedException("Cannot sign with a CA certificate without a private key.");
            }
        }

        if (publicKey != null && issuerCAKeyCert == null)
        {
            throw new NotSupportedException("Cannot use a public key without a CA certificate with a private key.");
        }

        // set default values.
        X509Name subjectDN = SetSuitableDefaults(
            ref applicationUri,
            ref applicationName,
            ref subjectName,
            ref domainNames,
            ref keySize,
            ref lifetimeInMonths);

        using (var cfrg = new CertificateFactoryRandomGenerator())
        {
            // cert generators
            SecureRandom random           = new SecureRandom(cfrg);
            X509V3CertificateGenerator cg = new X509V3CertificateGenerator();

            // Serial Number
            BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
            cg.SetSerialNumber(serialNumber);

            // subject and issuer DN
            X509Name issuerDN = null;
            if (issuerCAKeyCert != null)
            {
                issuerDN = new CertificateFactoryX509Name(issuerCAKeyCert.Subject);
            }
            else
            {
                // self signed
                issuerDN = subjectDN;
            }
            cg.SetIssuerDN(issuerDN);
            cg.SetSubjectDN(subjectDN);

            // valid for
            cg.SetNotBefore(startTime);
            cg.SetNotAfter(startTime.AddMonths(lifetimeInMonths));

            // set Private/Public Key
            AsymmetricKeyParameter subjectPublicKey;
            AsymmetricKeyParameter subjectPrivateKey;
            if (publicKey == null)
            {
                var keyGenerationParameters = new KeyGenerationParameters(random, keySize);
                var keyPairGenerator        = new RsaKeyPairGenerator();
                keyPairGenerator.Init(keyGenerationParameters);
                AsymmetricCipherKeyPair subjectKeyPair = keyPairGenerator.GenerateKeyPair();
                subjectPublicKey  = subjectKeyPair.Public;
                subjectPrivateKey = subjectKeyPair.Private;
            }
            else
            {
                // special case, if a cert is signed by CA, the private key of the cert is not needed
                subjectPublicKey  = PublicKeyFactory.CreateKey(publicKey);
                subjectPrivateKey = null;
            }
            cg.SetPublicKey(subjectPublicKey);

            // add extensions
            // Subject key identifier
            cg.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false,
                            new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectPublicKey)));

            // Basic constraints
            cg.AddExtension(X509Extensions.BasicConstraints.Id, true, isCA ? new BasicConstraints(0) : new BasicConstraints(false));

            // Authority Key identifier references the issuer cert or itself when self signed
            AsymmetricKeyParameter issuerPublicKey;
            BigInteger             issuerSerialNumber;
            if (issuerCAKeyCert != null)
            {
                issuerPublicKey    = GetPublicKeyParameter(issuerCAKeyCert);
                issuerSerialNumber = GetSerialNumber(issuerCAKeyCert);
                if (startTime.AddMonths(lifetimeInMonths) > issuerCAKeyCert.NotAfter)
                {
                    cg.SetNotAfter(issuerCAKeyCert.NotAfter);
                }
            }
            else
            {
                issuerPublicKey    = subjectPublicKey;
                issuerSerialNumber = serialNumber;
            }

            cg.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false,
                            new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(issuerPublicKey),
                                                       new GeneralNames(new GeneralName(issuerDN)), issuerSerialNumber));

            if (!isCA)
            {
                // Key usage
                var keyUsage = KeyUsage.DataEncipherment | KeyUsage.DigitalSignature |
                               KeyUsage.NonRepudiation | KeyUsage.KeyEncipherment;
                if (issuerCAKeyCert == null)
                {   // only self signed certs need KeyCertSign flag.
                    keyUsage |= KeyUsage.KeyCertSign;
                }
                cg.AddExtension(X509Extensions.KeyUsage, true,
                                new KeyUsage(keyUsage));

                // Extended Key usage
                cg.AddExtension(X509Extensions.ExtendedKeyUsage, true,
                                new ExtendedKeyUsage(new List <DerObjectIdentifier>()
                {
                    new DerObjectIdentifier("1.3.6.1.5.5.7.3.1"), // server auth
                    new DerObjectIdentifier("1.3.6.1.5.5.7.3.2"), // client auth
                }));

                // subject alternate name
                List <GeneralName> generalNames = new List <GeneralName>();
                generalNames.Add(new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri));
                generalNames.AddRange(CreateSubjectAlternateNameDomains(domainNames));
                cg.AddExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(generalNames.ToArray()));
            }
            else
            {
                // Key usage CA
                cg.AddExtension(X509Extensions.KeyUsage, true,
                                new KeyUsage(KeyUsage.CrlSign | KeyUsage.DigitalSignature | KeyUsage.KeyCertSign));
            }

            // sign certificate
            AsymmetricKeyParameter signingKey;
            if (issuerCAKeyCert != null)
            {
                // signed by issuer
                signingKey = GetPrivateKeyParameter(issuerCAKeyCert);
            }
            else
            {
                // self signed
                signingKey = subjectPrivateKey;
            }
            ISignatureFactory signatureFactory =
                new Asn1SignatureFactory(GetRSAHashAlgorithm(hashSizeInBits), signingKey, random);
            Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory);

            // convert to X509Certificate2
            X509Certificate2 certificate = null;
            if (subjectPrivateKey == null)
            {
                // create the cert without the private key
                certificate = new X509Certificate2(x509.GetEncoded());
            }
            else
            {
                // note: this cert has a private key!
                certificate = CreateCertificateWithPrivateKey(x509, null, subjectPrivateKey, random);
            }

            Utils.Trace(Utils.TraceMasks.Security, "Created new certificate: {0}", certificate.Thumbprint);

            // add cert to the store.
            if (!String.IsNullOrEmpty(storePath) && !String.IsNullOrEmpty(storeType))
            {
                using (ICertificateStore store = CertificateStoreIdentifier.CreateStore(storeType))
                {
                    if (store == null)
                    {
                        throw new ArgumentException("Invalid store type");
                    }

                    store.Open(storePath);
                    store.Add(certificate, password).Wait();
                    store.Close();
                }
            }

            return(certificate);
        }
    }
Ejemplo n.º 10
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;

        try
        {
            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 = IsCertificateAuthority(certificate);

            // find the authority key identifier.
            X509AuthorityKeyIdentifierExtension authority = FindAuthorityKeyIdentifier(certificate);

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

            if (!isCACert)
            {
                if (serialNumber == certificate.SerialNumber ||
                    Utils.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 FindIssuerCABySerialNumberAsync(store, certificate.Issuer, serialNumber);

                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);
                certCAIdentifier.StorePath = storePath;
                certCAIdentifier.StoreType = CertificateStoreIdentifier.DetermineStoreType(storePath);
                X509Certificate2 certCAWithPrivateKey = await certCAIdentifier.LoadPrivateKey(issuerKeyFilePassword);

                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()
                {
                    certificate
                };
                updatedCRL = RevokeCertificate(certCAWithPrivateKey, certCACrl, certificateCollection);

                store.AddCRL(updatedCRL);

                // delete outdated CRLs from store
                foreach (X509CRL caCrl in certCACrl)
                {
                    store.DeleteCRL(caCrl);
                }
                store.Close();
            }
        }
        catch (Exception e)
        {
            throw e;
        }
        return(updatedCRL);
    }
Ejemplo n.º 11
0
        private void PullFromGds(bool deleteBeforeAdd)
        {
            try
            {
                NodeId trustListId = m_gds.GetTrustList(m_application.ApplicationId, null);

                if (trustListId == null)
                {
                    CertificateStoreControl.Initialize(null, null, null);
                    return;
                }

                var trustList = m_gds.ReadTrustList(trustListId);

                if (m_application.RegistrationType == RegistrationType.ServerPush)
                {
                    CertificateStoreControl.Initialize(trustList);

                    MessageBox.Show(
                        Parent,
                        "The trust list (include CRLs) was downloaded from the GDS. It now has to be pushed to the Server.",
                        Parent.Text,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information);

                    return;
                }

                if (!String.IsNullOrEmpty(m_trustListStorePath))
                {
                    if (deleteBeforeAdd)
                    {
                        DeleteExistingFromStore(m_trustListStorePath);
                        DeleteExistingFromStore(m_issuerListStorePath);
                    }
                }

                if (!String.IsNullOrEmpty(m_trustListStorePath))
                {
                    using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_trustListStorePath))
                    {
                        if ((trustList.SpecifiedLists & (uint)Opc.Ua.TrustListMasks.TrustedCertificates) != 0)
                        {
                            foreach (var certificate in trustList.TrustedCertificates)
                            {
                                var x509 = new X509Certificate2(certificate);

                                if (store.FindByThumbprint(x509.Thumbprint) == null)
                                {
                                    store.Add(x509);
                                }
                            }
                        }

                        if ((trustList.SpecifiedLists & (uint)Opc.Ua.TrustListMasks.TrustedCrls) != 0)
                        {
                            foreach (var crl in trustList.TrustedCrls)
                            {
                                store.AddCRL(new X509CRL(crl));
                            }
                        }
                    }
                }

                if (!String.IsNullOrEmpty(m_application.IssuerListStorePath))
                {
                    using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_application.IssuerListStorePath))
                    {
                        if ((trustList.SpecifiedLists & (uint)Opc.Ua.TrustListMasks.IssuerCertificates) != 0)
                        {
                            foreach (var certificate in trustList.IssuerCertificates)
                            {
                                var x509 = new X509Certificate2(certificate);

                                if (store.FindByThumbprint(x509.Thumbprint) == null)
                                {
                                    store.Add(x509);
                                }
                            }
                        }

                        if ((trustList.SpecifiedLists & (uint)Opc.Ua.TrustListMasks.IssuerCrls) != 0)
                        {
                            foreach (var crl in trustList.IssuerCrls)
                            {
                                store.AddCRL(new X509CRL(crl));
                            }
                        }
                    }
                }

                CertificateStoreControl.Initialize(m_trustListStorePath, m_issuerListStorePath, null);

                MessageBox.Show(
                    Parent,
                    "The trust list (include CRLs) was downloaded from the GDS and saved locally.",
                    Parent.Text,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
            catch (Exception exception)
            {
                MessageBox.Show(Parent.Text + ": " + exception.Message);
            }
        }
Ejemplo n.º 12
0
 public CertificateRepository(ICertificateStore client)
 {
     m_client = client;
 }
Ejemplo n.º 13
0
        private static X509Certificate2 GetHttpsCertificate(string certificateFilePath, ICertificateStore store)
        {
            if (store.TryGet(certificateFilePath, out var certificate))
            {
                return(certificate);
            }

            throw new FileLoadException($"Failed to load certificate from path {certificateFilePath}");
        }
Ejemplo n.º 14
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
            //
            OpcApplicationConfiguration = new ApplicationConfiguration();

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


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

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

            // Use existing certificate, if it is there.
            X509Certificate2 certificate = await OpcApplicationConfiguration.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(
                    OpcApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.StoreType,
                    OpcApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null,
                    OpcApplicationConfiguration.ApplicationUri,
                    OpcApplicationConfiguration.ApplicationName,
                    OpcApplicationConfiguration.ApplicationName,
                    null,
                    CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize,
                    false,
                    null,
                    null
                    );
                OpcApplicationConfiguration.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");
            }
            OpcApplicationConfiguration.ApplicationUri = Utils.GetApplicationUriFromCertificate(certificate);
            Logger.Information($"Application certificate is for Application URI '{OpcApplicationConfiguration.ApplicationUri}', Application '{OpcApplicationConfiguration.ApplicationName} and has Subject '{OpcApplicationConfiguration.ApplicationName}'");

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

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

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

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

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

            // MinimunCertificatesKeySize
            // We allow a minimum key size of 1024 bit, as many OPC UA servers still use them
            OpcApplicationConfiguration.SecurityConfiguration.MinimumCertificateKeySize = 1024;
            Logger.Information($"Minimum certificate key size set to {OpcApplicationConfiguration.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 = OpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();
                    if (store == null)
                    {
                        Logger.Information($"Can not open trusted peer store. StorePath={OpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");
                    }
                    else
                    {
                        try
                        {
                            Logger.Information($"Adding own certificate to trusted peer store. StorePath={OpcApplicationConfiguration.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 own certificate to trusted peer store. StorePath={OpcApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.StorePath}");
                }
            }
            else
            {
                Logger.Information($"{ProgramName} certificate is not added to trusted peer store.");
            }


            //
            // TransportConfigurations
            //

            OpcApplicationConfiguration.TransportQuotas = new TransportQuotas();
            OpcApplicationConfiguration.TransportQuotas.MaxByteStringLength = 4 * 1024 * 1024;
            OpcApplicationConfiguration.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
            OpcApplicationConfiguration.TransportQuotas.MaxStringLength = OpcMaxStringLength;

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

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

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

            // validate the configuration now
            await OpcApplicationConfiguration.Validate(OpcApplicationConfiguration.ApplicationType);
        }
        /// <summary>
        /// Installs a UA application.
        /// </summary>
        public static async Task InstallApplication(
            InstalledApplication application,
            bool autostart,
            bool configureFirewall)
        {
            // validate the executable file.
            string executableFile = Utils.GetAbsoluteFilePath(application.ExecutableFile, true, true, false);

            // get the default application name from the executable file.
            FileInfo executableFileInfo = new FileInfo(executableFile);

            string applicationName = executableFileInfo.Name.Substring(0, executableFileInfo.Name.Length - 4);

            // choose a default configuration file.
            if (String.IsNullOrEmpty(application.ConfigurationFile))
            {
                application.ConfigurationFile = Utils.Format(
                    "{0}\\{1}.Config.xml",
                    executableFileInfo.DirectoryName,
                    applicationName);
            }

            // validate the configuration file.
            string configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, false, false);

            // create a new file if one does not exist.
            bool useExisting = true;

            if (configurationFile == null)
            {
                configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, true, true);
                useExisting       = false;
            }

            // create the default configuration file.

            if (useExisting)
            {
                try
                {
                    Opc.Ua.Security.SecuredApplication existingSettings = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configurationFile);

                    // copy current settings
                    application.ApplicationType             = existingSettings.ApplicationType;
                    application.BaseAddresses               = existingSettings.BaseAddresses;
                    application.ApplicationCertificate      = existingSettings.ApplicationCertificate;
                    application.ApplicationName             = existingSettings.ApplicationName;
                    application.ProductName                 = existingSettings.ProductName;
                    application.RejectedCertificatesStore   = existingSettings.RejectedCertificatesStore;
                    application.TrustedCertificateStore     = existingSettings.TrustedCertificateStore;
                    application.TrustedCertificates         = existingSettings.TrustedCertificates;
                    application.IssuerCertificateStore      = existingSettings.IssuerCertificateStore;
                    application.IssuerCertificates          = application.IssuerCertificates;
                    application.UseDefaultCertificateStores = false;
                }
                catch (Exception e)
                {
                    useExisting = false;
                    Utils.Trace("WARNING. Existing configuration file could not be loaded: {0}.\r\nReplacing with default: {1}", e.Message, configurationFile);
                    File.Copy(configurationFile, configurationFile + ".bak", true);
                }
            }

            // create the configuration file from the default.
            if (!useExisting)
            {
                try
                {
                    string installationFile = Utils.Format(
                        "{0}\\Install\\{1}.Config.xml",
                        executableFileInfo.Directory.Parent.FullName,
                        applicationName);

                    if (!File.Exists(installationFile))
                    {
                        Utils.Trace("Could not find default configuation at: {0}", installationFile);
                    }

                    File.Copy(installationFile, configurationFile, true);
                    Utils.Trace("File.Copy({0}, {1})", installationFile, configurationFile);
                }
                catch (Exception e)
                {
                    Utils.Trace("Could not copy default configuation to: {0}. Error={1}.", configurationFile, e.Message);
                }
            }

            // create a default application name.
            if (String.IsNullOrEmpty(application.ApplicationName))
            {
                application.ApplicationName = applicationName;
            }

            // create a default product name.
            if (String.IsNullOrEmpty(application.ProductName))
            {
                application.ProductName = application.ApplicationName;
            }

            // create a default uri.
            if (String.IsNullOrEmpty(application.ApplicationUri))
            {
                application.ApplicationUri = Utils.Format("http://localhost/{0}/{1}", applicationName, Guid.NewGuid());
            }

            // make the uri specify the local machine.
            application.ApplicationUri = Utils.ReplaceLocalhost(application.ApplicationUri);

            // set a default application store.
            if (application.ApplicationCertificate == null)
            {
                application.ApplicationCertificate           = new Opc.Ua.Security.CertificateIdentifier();
                application.ApplicationCertificate.StoreType = Utils.DefaultStoreType;
                application.ApplicationCertificate.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault";
            }

            if (application.UseDefaultCertificateStores)
            {
                if (application.IssuerCertificateStore == null)
                {
                    application.IssuerCertificateStore           = new Opc.Ua.Security.CertificateStoreIdentifier();
                    application.IssuerCertificateStore.StoreType = Utils.DefaultStoreType;
                    application.IssuerCertificateStore.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault";
                }

                if (application.TrustedCertificateStore == null)
                {
                    application.TrustedCertificateStore           = new Opc.Ua.Security.CertificateStoreIdentifier();
                    application.TrustedCertificateStore.StoreType = Utils.DefaultStoreType;
                    application.TrustedCertificateStore.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault";
                }

                try
                {
                    Utils.GetAbsoluteDirectoryPath(application.TrustedCertificateStore.StorePath, true, true, true);
                }
                catch (Exception e)
                {
                    Utils.Trace("Could not access the machine directory: {0} '{1}'", application.RejectedCertificatesStore.StorePath, e);
                }

                if (application.RejectedCertificatesStore == null)
                {
                    application.RejectedCertificatesStore           = new Opc.Ua.Security.CertificateStoreIdentifier();
                    application.RejectedCertificatesStore.StoreType = CertificateStoreType.Directory;
                    application.RejectedCertificatesStore.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\RejectedCertificates";

                    StringBuilder buffer = new StringBuilder();

                    buffer.Append(ApplicationData.Current.LocalFolder.Path);
                    buffer.Append("\\OPC Foundation");
                    buffer.Append("\\RejectedCertificates");

                    string folderPath = buffer.ToString();

                    if (!Directory.Exists(folderPath))
                    {
                        Directory.CreateDirectory(folderPath);
                    }
                }
            }

            // check for valid certificate (discard invalid certificates).
            CertificateIdentifier applicationCertificate = Opc.Ua.Security.SecuredApplication.FromCertificateIdentifier(application.ApplicationCertificate);
            X509Certificate2      certificate            = await applicationCertificate.Find(true);

            if (certificate == null)
            {
                certificate = await applicationCertificate.Find(false);

                if (certificate != null)
                {
                    Utils.Trace(
                        "Found existing certificate but it does not have a private key: Store={0}, Certificate={1}",
                        application.ApplicationCertificate.StorePath,
                        application.ApplicationCertificate);
                }
                else
                {
                    Utils.Trace(
                        "Existing certificate could not be found: Store={0}, Certificate={1}",
                        application.ApplicationCertificate.StorePath,
                        application.ApplicationCertificate);
                }
            }

            // check if no certificate exists.
            if (certificate == null)
            {
                certificate = await CreateCertificateForApplication(application);
            }

            // ensure the application certificate is in the trusted peers store.
            try
            {
                CertificateStoreIdentifier certificateStore = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(application.TrustedCertificateStore);

                using (ICertificateStore store = certificateStore.OpenStore())
                {
                    X509Certificate2Collection peerCertificates = await store.FindByThumbprint(certificate.Thumbprint);

                    if (peerCertificates.Count == 0)
                    {
                        await store.Add(new X509Certificate2(certificate.RawData));
                    }
                }
            }
            catch (Exception e)
            {
                Utils.Trace(
                    "Could not add certificate '{0}' to trusted peer store '{1}'. Error={2}",
                    certificate.Subject,
                    application.TrustedCertificateStore,
                    e.Message);
            }

            // update configuration file location.
            UpdateConfigurationLocation(executableFile, configurationFile);

            // update configuration file.
            new Opc.Ua.Security.SecurityConfigurationManager().WriteConfiguration(configurationFile, application);

            ApplicationAccessRuleCollection accessRules = application.AccessRules;
            bool noRulesDefined = application.AccessRules == null || application.AccessRules.Count == 0;

            // add the default access rules.
            if (noRulesDefined)
            {
                ApplicationAccessRule rule = new ApplicationAccessRule();

                rule.IdentityName = WellKnownSids.Administrators;
                rule.RuleType     = AccessControlType.Allow;
                rule.Right        = ApplicationAccessRight.Configure;

                accessRules.Add(rule);

                rule = new ApplicationAccessRule();

                rule.IdentityName = WellKnownSids.Users;
                rule.RuleType     = AccessControlType.Allow;
                rule.Right        = ApplicationAccessRight.Update;

                accessRules.Add(rule);
            }

            // ensure the service account has priviledges.
            if (application.InstallAsService)
            {
                // check if a specific account is assigned.
                AccountInfo accountInfo = null;

                if (!String.IsNullOrEmpty(application.ServiceUserName))
                {
                    accountInfo = AccountInfo.Create(application.ServiceUserName);
                }

                // choose a built-in service account.
                if (accountInfo == null)
                {
                    accountInfo = AccountInfo.Create(WellKnownSids.NetworkService);

                    if (accountInfo == null)
                    {
                        accountInfo = AccountInfo.Create(WellKnownSids.LocalSystem);
                    }
                }

                ApplicationAccessRule rule = new ApplicationAccessRule();

                rule.IdentityName = accountInfo.ToString();
                rule.RuleType     = AccessControlType.Allow;
                rule.Right        = ApplicationAccessRight.Run;

                accessRules.Add(rule);
            }

            // set the permissions for the HTTP endpoints used by the application.
            if (configureFirewall && application.BaseAddresses != null && application.BaseAddresses.Count > 0)
            {
                for (int ii = 0; ii < application.BaseAddresses.Count; ii++)
                {
                    Uri url = Utils.ParseUri(application.BaseAddresses[ii]);

                    if (url != null)
                    {
                        try
                        {
                            HttpAccessRule.SetAccessRules(url, accessRules, true);
                            Utils.Trace("Added HTTP access rules for URL: {0}", url);
                        }
                        catch (Exception e)
                        {
                            Utils.Trace("Could not set HTTP access rules for URL: {0}. Error={1}", url, e.Message);

                            for (int jj = 0; jj < accessRules.Count; jj++)
                            {
                                ApplicationAccessRule rule = accessRules[jj];

                                Utils.Trace(
                                    (int)Utils.TraceMasks.Error,
                                    "IdentityName={0}, Right={1}, RuleType={2}",
                                    rule.IdentityName,
                                    rule.Right,
                                    rule.RuleType);
                            }
                        }
                    }
                }
            }

            // set permissions on the local certificate store.
            SetCertificatePermissions(
                application,
                applicationCertificate,
                accessRules,
                false);

            // set permissions on the local certificate store.
            if (application.RejectedCertificatesStore != null)
            {
                // need to grant full control to certificates in the RejectedCertificatesStore.
                foreach (ApplicationAccessRule rule in accessRules)
                {
                    if (rule.RuleType == AccessControlType.Allow)
                    {
                        rule.Right = ApplicationAccessRight.Configure;
                    }
                }

                CertificateStoreIdentifier rejectedCertificates = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(application.RejectedCertificatesStore);

                using (ICertificateStore store = rejectedCertificates.OpenStore())
                {
                    if (store.SupportsAccessControl)
                    {
                        store.SetAccessRules(accessRules, false);
                    }
                }
            }
        }
Ejemplo n.º 16
0
 public CertificateStore(ICertificateStore personalStore, ICertificateStore rootStore)
 {
     _personalStore = personalStore;
     _rootStore = rootStore;
 }
        /// <summary>
        /// Uninstalls a UA application.
        /// </summary>
        public static async Task UninstallApplication(InstalledApplication application)
        {
            // validate the executable file.
            string executableFile = Utils.GetAbsoluteFilePath(application.ExecutableFile, true, true, false);

            // get the default application name from the executable file.
            FileInfo executableFileInfo = new FileInfo(executableFile);
            string   applicationName    = executableFileInfo.Name.Substring(0, executableFileInfo.Name.Length - 4);

            // choose a default configuration file.
            if (String.IsNullOrEmpty(application.ConfigurationFile))
            {
                application.ConfigurationFile = Utils.Format(
                    "{0}\\{1}.Config.xml",
                    executableFileInfo.DirectoryName,
                    applicationName);
            }

            // validate the configuration file.
            string configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, false, false);

            if (configurationFile != null)
            {
                // load the current configuration.
                Opc.Ua.Security.SecuredApplication security = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configurationFile);

                // delete the application certificates.
                if (application.DeleteCertificatesOnUninstall)
                {
                    CertificateIdentifier id = Opc.Ua.Security.SecuredApplication.FromCertificateIdentifier(security.ApplicationCertificate);

                    // delete public key from trusted peers certificate store.
                    try
                    {
                        CertificateStoreIdentifier certificateStore = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(security.TrustedCertificateStore);

                        using (ICertificateStore store = certificateStore.OpenStore())
                        {
                            X509Certificate2Collection peerCertificates = await store.FindByThumbprint(id.Thumbprint);

                            if (peerCertificates.Count > 0)
                            {
                                await store.Delete(peerCertificates[0].Thumbprint);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message);
                    }

                    // delete private key from application certificate store.
                    try
                    {
                        using (ICertificateStore store = id.OpenStore())
                        {
                            await store.Delete(id.Thumbprint);
                        }
                    }
                    catch (Exception e)
                    {
                        Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message);
                    }

                    // permentently delete any UA defined stores if they are now empty.
                    try
                    {
                        WindowsCertificateStore store = new WindowsCertificateStore();
                        await store.Open("LocalMachine\\UA Applications");

                        X509Certificate2Collection collection = await store.Enumerate();

                        if (collection.Count == 0)
                        {
                            store.PermanentlyDeleteStore();
                        }
                    }
                    catch (Exception e)
                    {
                        Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message);
                    }
                }

                // remove the permissions for the HTTP endpoints used by the application.
                if (application.BaseAddresses != null && application.BaseAddresses.Count > 0)
                {
                    List <ApplicationAccessRule> noRules = new List <ApplicationAccessRule>();

                    for (int ii = 0; ii < application.BaseAddresses.Count; ii++)
                    {
                        Uri url = Utils.ParseUri(application.BaseAddresses[ii]);

                        if (url != null)
                        {
                            try
                            {
                                HttpAccessRule.SetAccessRules(url, noRules, true);
                                Utils.Trace("Removed HTTP access rules for URL: {0}", url);
                            }
                            catch (Exception e)
                            {
                                Utils.Trace("Could not remove HTTP access rules for URL: {0}. Error={1}", url, e.Message);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 18
0
        public async void Initialize(string trustedStorePath, string issuerStorePath, string rejectedStorePath)
        {
            CertificatesTable.Rows.Clear();

            m_trustedStorePath  = trustedStorePath;
            m_issuerStorePath   = issuerStorePath;
            m_rejectedStorePath = rejectedStorePath;

            if (!String.IsNullOrEmpty(trustedStorePath))
            {
                using (ICertificateStore store = CreateStore(trustedStorePath))
                {
                    X509CertificateCollection certificates = await store.Enumerate();

                    foreach (X509Certificate2 certificate in certificates)
                    {
                        List <X509CRL> crls = new List <X509CRL>();

                        if (store.SupportsCRLs)
                        {
                            foreach (X509CRL crl in store.EnumerateCRLs(certificate))
                            {
                                crls.Add(crl);
                            }
                        }

                        AddCertificate(certificate, Status.Trusted, crls);
                    }
                }
            }

            string path1 = Utils.GetAbsoluteDirectoryPath(trustedStorePath, true, false, false);
            string path2 = Utils.GetAbsoluteDirectoryPath(issuerStorePath, true, false, false);

            if (String.Compare(path1, path2, StringComparison.OrdinalIgnoreCase) != 0)
            {
                if (!String.IsNullOrEmpty(issuerStorePath))
                {
                    using (ICertificateStore store = CreateStore(issuerStorePath))
                    {
                        X509Certificate2Collection certificates = await store.Enumerate();

                        foreach (X509Certificate2 certificate in certificates)
                        {
                            List <X509CRL> crls = new List <X509CRL>();

                            if (store.SupportsCRLs)
                            {
                                foreach (X509CRL crl in store.EnumerateCRLs(certificate))
                                {
                                    crls.Add(crl);
                                }
                            }

                            AddCertificate(certificate, Status.Issuer, crls);
                        }
                    }
                }
            }

            if (!String.IsNullOrEmpty(rejectedStorePath))
            {
                using (ICertificateStore store = CreateStore(rejectedStorePath))
                {
                    X509Certificate2Collection certificates = await store.Enumerate();

                    foreach (X509Certificate2 certificate in certificates)
                    {
                        AddCertificate(certificate, Status.Rejected, null);
                    }
                }
            }

            m_dataset.AcceptChanges();
            NoDataWarningLabel.Visible = CertificatesTable.Rows.Count == 0;
        }
Ejemplo n.º 19
0
        private static void SetBinding(Binding binding, dynamic obj)
        {
            string protocol           = DynamicHelper.Value(obj.protocol);
            string bindingInformation = DynamicHelper.Value(obj.binding_information);
            bool?  requireSni         = DynamicHelper.To <bool>(obj.require_sni);

            if (protocol == null)
            {
                throw new ApiArgumentException("binding.protocol");
            }

            binding.Protocol = protocol;

            bool isHttp = protocol.Equals("http") || protocol.Equals("https");

            if (isHttp)
            {
                //
                // HTTP Binding information provides port, ip address, and hostname
                UInt16    port;
                string    hostname;
                IPAddress ipAddress = null;

                if (bindingInformation == null)
                {
                    var ip = DynamicHelper.Value(obj.ip_address);
                    if (ip == "*")
                    {
                        ipAddress = IPAddress.Any;
                    }
                    else if (!IPAddress.TryParse(ip, out ipAddress))
                    {
                        throw new ApiArgumentException("binding.ip_address");
                    }

                    UInt16?p = (UInt16?)DynamicHelper.To(obj.port, 1, UInt16.MaxValue);
                    if (p == null)
                    {
                        throw new ApiArgumentException("binding.port");
                    }
                    port = p.Value;

                    hostname = DynamicHelper.Value(obj.hostname) ?? string.Empty;
                }
                else
                {
                    var parts = bindingInformation.Split(':');
                    if (parts.Length != 3)
                    {
                        throw new ApiArgumentException("binding.binding_information");
                    }

                    if (parts[0] == "*")
                    {
                        ipAddress = IPAddress.Any;
                    }
                    else if (!IPAddress.TryParse(parts[0], out ipAddress))
                    {
                        throw new ApiArgumentException("binding.binding_information");
                    }

                    if (!UInt16.TryParse(parts[1], out port))
                    {
                        throw new ApiArgumentException("binding.binding_information");
                    }

                    hostname = parts[2];
                }

                binding.Protocol = protocol;

                // HTTPS
                if (protocol.Equals("https"))
                {
                    if (string.IsNullOrEmpty(hostname) && requireSni.HasValue && requireSni.Value)
                    {
                        throw new ApiArgumentException("binding.require_sni");
                    }

                    if (obj.certificate == null || !(obj.certificate is JObject))
                    {
                        throw new ApiArgumentException("binding.certificate");
                    }

                    dynamic certificate = obj.certificate;
                    string  uuid        = DynamicHelper.Value(certificate.id);

                    if (string.IsNullOrEmpty(uuid))
                    {
                        throw new ApiArgumentException("binding.certificate.id");
                    }

                    CertificateId     id    = new CertificateId(uuid);
                    ICertificateStore store = CertificateStoreProviderAccessor.Instance?.Stores
                                              .FirstOrDefault(s => s.Name.Equals(id.StoreName, StringComparison.OrdinalIgnoreCase));
                    ICertificate cert = null;

                    if (store != null)
                    {
                        cert = store.GetCertificate(id.Id).Result;
                    }

                    if (cert == null)
                    {
                        throw new NotFoundException("binding.certificate");
                    }

                    if (!cert.PurposesOID.Contains(OIDServerAuth))
                    {
                        throw new ApiArgumentException("binding.certificate", "Certificate does not support server authentication");
                    }

                    //
                    // Windows builtin store
                    if (store is IWindowsCertificateStore)
                    {
                        // The specified certificate must be in the store with a private key or else there will be an exception when we commit
                        if (cert == null)
                        {
                            throw new NotFoundException("binding.certificate");
                        }
                        if (!cert.HasPrivateKey)
                        {
                            throw new ApiArgumentException("binding.certificate", "Certificate must have a private key");
                        }

                        List <byte> bytes = new List <byte>();
                        // Decode the hex string of the certificate hash into bytes
                        for (int i = 0; i < id.Id.Length; i += 2)
                        {
                            bytes.Add(Convert.ToByte(id.Id.Substring(i, 2), 16));
                        }

                        binding.CertificateStoreName = id.StoreName;
                        binding.CertificateHash      = bytes.ToArray();
                    }

                    //
                    // IIS Central Certificate store
                    else if (store is ICentralCertificateStore)
                    {
                        string name = Path.GetFileNameWithoutExtension(cert.Alias);

                        if (string.IsNullOrEmpty(hostname) || !hostname.Replace('*', '_').Equals(name))
                        {
                            throw new ApiArgumentException("binding.hostname", "Hostname must match certificate file name for central certificate store");
                        }

                        binding.SslFlags |= SslFlags.CentralCertStore;
                    }

                    if (requireSni.HasValue)
                    {
                        if (!binding.Schema.HasAttribute(sslFlagsAttribute))
                        {
                            // throw on IIS 7.5 which does not have SNI support
                            throw new ApiArgumentException("binding.require_sni", "SNI not supported on this machine");
                        }

                        if (requireSni.Value)
                        {
                            binding.SslFlags |= SslFlags.Sni;
                        }
                        else
                        {
                            binding.SslFlags &= ~SslFlags.Sni;
                        }
                    }
                }

                var ipModel = ipAddress.Equals(IPAddress.Any) ? "*" : ipAddress.ToString();
                binding.BindingInformation = $"{ipModel}:{port}:{hostname}";
            }
            else
            {
                //
                // Custom protocol
                if (string.IsNullOrEmpty(bindingInformation))
                {
                    throw new ApiArgumentException("binding.binding_information");
                }

                binding.BindingInformation = bindingInformation;
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Creates an application instance certificate if one does not already exist.
        /// </summary>
        public static void CheckApplicationInstanceCertificate(ApplicationConfiguration configuration)
        {
            // create a default certificate id none specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                id = new CertificateIdentifier
                {
                    StoreType   = CertificateStoreType.X509Store,
                    StorePath   = "LocalMachine\\My",
                    SubjectName = configuration.ApplicationName
                };
            }

            // check for certificate with a private key.
            X509Certificate2 certificate = id.Find(true).Result;

            if (certificate != null)
            {
                //This UA application already has an instance certificate
                SaveCertificate(certificate);
                return;
            }

            //This UA application does not have an instance certificate. Create one automatically

            // construct the subject name from the
            List <string> hostNames = new List <string>
            {
                System.Net.Dns.GetHostName()
            };

            string commonName  = Utils.Format("CN={0}", configuration.ApplicationName);
            string domainName  = Utils.Format("DC={0}", hostNames[0]);
            string subjectName = Utils.Format("{0}, {1}", commonName, domainName);

            // check if a distinguished name was specified.
            if (id.SubjectName.IndexOf("=", StringComparison.Ordinal) != -1)
            {
                List <string> fields = Utils.ParseDistinguishedName(id.SubjectName);

                bool commonNameFound = false;
                bool domainNameFound = false;

                for (int ii = 0; ii < fields.Count; ii++)
                {
                    string field = fields[ii];

                    if (field.StartsWith("CN="))
                    {
                        fields[ii]      = commonName;
                        commonNameFound = true;
                        continue;
                    }

                    if (field.StartsWith("DC="))
                    {
                        fields[ii]      = domainName;
                        domainNameFound = true;
                        continue;
                    }
                }

                if (!commonNameFound)
                {
                    fields.Insert(0, commonName);
                }

                if (!domainNameFound)
                {
                    fields.Insert(0, domainName);
                }

                StringBuilder buffer = new StringBuilder();

                for (int ii = 0; ii < fields.Count; ii++)
                {
                    if (buffer.Length > 0)
                    {
                        buffer.Append(", ");
                    }

                    buffer.Append(fields[ii]);
                }

                subjectName = buffer.ToString();
            }

            // create a new certificate with a new public key pair.
            //certificate = CertificateFactory.CreateCertificate(
            //    id.StoreType,
            //    id.StorePath,
            //    configuration.ApplicationUri,
            //    configuration.ApplicationName,
            //    subjectName,
            //    hostNames,
            //    1024,
            //    120);

            ushort minimumKeySize   = CertificateFactory.defaultKeySize;
            ushort lifeTimeInMonths = CertificateFactory.defaultLifeTime;

            certificate = CertificateFactory.CreateCertificate(
                id.StoreType,
                id.StorePath,
                null,
                configuration.ApplicationUri,
                configuration.ApplicationName,
                id.SubjectName,
                hostNames,
                minimumKeySize,
                DateTime.UtcNow - TimeSpan.FromDays(1),
                lifeTimeInMonths,
                CertificateFactory.defaultHashSize,
                false,
                null,
                null);

            // update and save the configuration file.
            id.Certificate = certificate;
            configuration.SaveToFile(configuration.SourceFilePath);

            // add certificate to the trusted peer store so other applications will trust it.
            ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();

            try
            {
                X509Certificate2 certificate2 = store.FindByThumbprint(certificate.Thumbprint).Result[0];

                if (certificate2 == null)
                {
                    store.Add(certificate);
                }
            }
            finally
            {
                store.Close();
            }

            // tell the certificate validator about the new certificate.
            configuration.CertificateValidator.Update(configuration.SecurityConfiguration);
            SaveCertificate(certificate);
        }
Ejemplo n.º 21
0
        private static object ToJsonModel(Binding binding)
        {
            dynamic obj = new ExpandoObject();

            obj.protocol            = binding.Protocol;
            obj.binding_information = binding.BindingInformation;

            bool isHttp = binding.Protocol.Equals("http") || binding.Protocol.Equals("https");

            if (isHttp)
            {
                string ipAddress = null;
                int?   port      = null;

                if (binding.EndPoint != null && binding.EndPoint.Address != null)
                {
                    port = binding.EndPoint.Port;
                    if (binding.EndPoint.Address != null)
                    {
                        ipAddress = binding.EndPoint.Address.Equals(IPAddress.Any) ? "*" : binding.EndPoint.Address.ToString();
                    }
                }

                obj.ip_address = ipAddress;
                obj.port       = port;
                obj.hostname   = binding.Host;

                //
                // HTTPS
                if (binding.Protocol.Equals("https"))
                {
                    ICertificateStore store = null;

                    // Windows store
                    if (binding.CertificateStoreName != null)
                    {
                        string thumbprint = binding.CertificateHash == null ? null : BitConverter.ToString(binding.CertificateHash)?.Replace("-", string.Empty);
                        store = CertificateStoreProviderAccessor.Instance?.Stores
                                .FirstOrDefault(s => s.Name.Equals(binding.CertificateStoreName, StringComparison.OrdinalIgnoreCase));

                        // Certificate
                        if (store != null)
                        {
                            obj.certificate = CertificateHelper.ToJsonModelRef(GetCertificate(() => store.GetCertificate(thumbprint).Result));
                        }
                    }

                    // IIS Central Certificate Store
                    else if (binding.Schema.HasAttribute(sslFlagsAttribute) && binding.SslFlags.HasFlag(SslFlags.CentralCertStore) && !string.IsNullOrEmpty(binding.Host))
                    {
                        ICentralCertificateStore centralStore = null;

                        if (PathUtil.IsValidFileName(binding.Host))
                        {
                            centralStore = CertificateStoreProviderAccessor.Instance?.Stores.FirstOrDefault(s => s is ICentralCertificateStore) as ICentralCertificateStore;
                        }

                        // Certificate
                        if (centralStore != null)
                        {
                            obj.certificate = CertificateHelper.ToJsonModelRef(GetCertificate(() => centralStore.GetCertificateByHostName(binding.Host.Replace('*', '_')).Result));
                        }
                    }

                    //
                    // Ssl Flags
                    if (binding.Schema.HasAttribute(sslFlagsAttribute))
                    {
                        obj.require_sni = binding.SslFlags.HasFlag(SslFlags.Sni);
                    }
                }
            }

            return(obj);
        }
Ejemplo n.º 22
0
 public ServiceFabricHealthChecker(ILog log, ICertificateStore certificateStore, IVariables variables)
 {
     this.log = log;
     this.certificateStore = certificateStore;
     this.variables        = variables;
 }
 public SubscriptionCloudCredentialsFactory(ICertificateStore certificateStore)
 {
     this.certificateStore = certificateStore;
 }
Ejemplo n.º 24
0
 public PublicKeySymmetricEncryption(ICertificateStore store, ILogger logger, PasswordEncryption passwordEncryption) : base(store, logger)
 {
     this.passwordEncryption = passwordEncryption;
 }
Ejemplo n.º 25
0
        internal void OnDeserializedMethod(StreamingContext context)
        {
            // Validate configuration and set reasonable defaults

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            // validate the configuration now
            Configuration.Validate(Configuration.ApplicationType).Wait();
        }
        /// <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);
                            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);
        }
Ejemplo n.º 27
0
 public AzurePowerShellContext()
 {
     this.fileSystem        = new WindowsPhysicalFileSystem();
     this.certificateStore  = new CalamariCertificateStore();
     this.embeddedResources = new CallingAssemblyEmbeddedResources();
 }
Ejemplo n.º 28
0
        private ServiceResult RemoveCertificate(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            string thumbprint,
            bool isTrustedCertificate)
        {
            HasSecureWriteAccess(context);

            lock (m_lock)
            {
                if (m_sessionId != null)
                {
                    return(StatusCodes.BadInvalidState);
                }

                if (String.IsNullOrEmpty(thumbprint))
                {
                    return(StatusCodes.BadInvalidArgument);
                }

                using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(isTrustedCertificate ? m_trustedStorePath : m_issuerStorePath))
                {
                    var certCollection = store.FindByThumbprint(thumbprint).Result;

                    if (certCollection.Count == 0)
                    {
                        return(StatusCodes.BadInvalidArgument);
                    }

                    // delete all CRLs signed by cert
                    var crlsToDelete = new List <X509CRL>();
                    foreach (var crl in store.EnumerateCRLs())
                    {
                        foreach (var cert in certCollection)
                        {
                            if (Utils.CompareDistinguishedName(cert.Subject, crl.Issuer) &&
                                crl.VerifySignature(cert, false))
                            {
                                crlsToDelete.Add(crl);
                                break;
                            }
                        }
                    }

                    if (!store.Delete(thumbprint).Result)
                    {
                        return(StatusCodes.BadInvalidArgument);
                    }

                    foreach (var crl in crlsToDelete)
                    {
                        if (!store.DeleteCRL(crl))
                        {
                            // intentionally ignore errors, try best effort
                            Utils.Trace("RemoveCertificate: Failed to delete CRL {0}.", crl.ToString());
                        }
                    }
                }

                m_node.LastUpdateTime.Value = DateTime.UtcNow;
            }

            return(ServiceResult.Good);
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Synchronous helper implementation of CheckApplicationInstanceCertificate for C++ Proxy
        /// </summary>
        public static void CheckApplicationInstanceCertificate(ApplicationConfiguration configuration)
        {
            // create a default certificate id none specified.
            CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate;

            if (id == null)
            {
                id             = new CertificateIdentifier();
                id.StoreType   = Utils.DefaultStoreType;
                id.StorePath   = Utils.DefaultStorePath;
                id.SubjectName = configuration.ApplicationName;
            }

            // check for certificate with a private key.
            X509Certificate2 certificate = id.Find(true).Result;

            if (certificate != null)
            {
                return;
            }

            // construct the subject name from the
            List <string> hostNames = new List <string>();

            hostNames.Add(Utils.GetHostName());

            string commonName  = Utils.Format("CN={0}", configuration.ApplicationName);
            string domainName  = Utils.Format("DC={0}", hostNames[0]);
            string subjectName = Utils.Format("{0}, {1}", commonName, domainName);

            // create a new certificate with a new public key pair.
            //certificate = CertificateFactory.CreateCertificate(
            //    id.StoreType,
            //    id.StorePath,
            //    null,
            //    configuration.ApplicationUri,
            //    configuration.ApplicationName,
            //    subjectName,
            //    hostNames,
            //    2048,
            //    DateTime.UtcNow - TimeSpan.FromHours(1),
            //    120,
            //    256,
            //    false,
            //    null,
            //    null);

            certificate = CertificateFactory.CreateCertificate(configuration.ApplicationUri, configuration.ApplicationName, subjectName, hostNames)
                          .CreateForRSA();
            // update and save the configuration file.
            id.Certificate = certificate;
            configuration.SaveToFile(configuration.SourceFilePath);

            // add certificate to the trusted peer store so other applications will trust it.
            ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();

            try
            {
                X509Certificate2Collection certificateCollection = store.FindByThumbprint(certificate.Thumbprint).Result;
                if (certificateCollection != null)
                {
                    store.Add(certificateCollection[0]).Wait();
                }
            }
            finally
            {
                store.Close();
            }

            // tell the certificate validator about the new certificate.
            configuration.CertificateValidator.Update(configuration.SecurityConfiguration).Wait();
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Adds the certificate to the Trusted Certificate Store
        /// </summary>
        /// <param name="configuration">The application's configuration which specifies the location of the TrustedStore.</param>
        /// <param name="certificate">The certificate to register.</param>
        private static async Task AddToTrustedStore(ApplicationConfiguration configuration, X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            string storePath = null;

            if (configuration != null && configuration.SecurityConfiguration != null && configuration.SecurityConfiguration.TrustedPeerCertificates != null)
            {
                storePath = configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath;
            }

            if (String.IsNullOrEmpty(storePath))
            {
                Utils.Trace(Utils.TraceMasks.Information, "WARNING: Trusted peer store not specified.");
                return;
            }

            try
            {
                ICertificateStore store = configuration.SecurityConfiguration.TrustedPeerCertificates.OpenStore();

                if (store == null)
                {
                    Utils.Trace("Could not open trusted peer store. StorePath={0}", storePath);
                    return;
                }

                try
                {
                    // check if it already exists.
                    X509Certificate2Collection existingCertificates = await store.FindByThumbprint(certificate.Thumbprint);

                    if (existingCertificates.Count > 0)
                    {
                        return;
                    }

                    Utils.Trace(Utils.TraceMasks.Information, "Adding certificate to trusted peer store. StorePath={0}", storePath);

                    List <string> subjectName = Utils.ParseDistinguishedName(certificate.Subject);

                    // check for old certificate.
                    X509Certificate2Collection certificates = await store.Enumerate();

                    for (int ii = 0; ii < certificates.Count; ii++)
                    {
                        if (Utils.CompareDistinguishedName(certificates[ii], subjectName))
                        {
                            if (certificates[ii].Thumbprint == certificate.Thumbprint)
                            {
                                return;
                            }

                            await store.Delete(certificates[ii].Thumbprint);

                            break;
                        }
                    }

                    // add new certificate.
                    X509Certificate2 publicKey = new X509Certificate2(certificate.RawData);
                    await store.Add(publicKey);
                }
                finally
                {
                    store.Close();
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Could not add certificate to trusted peer store. StorePath={0}", storePath);
            }
        }
Ejemplo n.º 31
0
 public CertificatesProvider(ICertificateStore certificatesStore, ISecretsStore secretsStore)
 {
     this.certificatesStore = certificatesStore;
     this.secretsStore      = secretsStore;
 }
Ejemplo n.º 32
0
 public CertificateRepository(ICertificateStore client)
 {
     m_client = client;
 }
Ejemplo n.º 33
0
 private async Task <IEnumerable <ICertificate> > SafeGetCertificates(ICertificateStore store)
 {
     return((await SafeAccessStore(async() => await store.GetCertificates())) ?? Enumerable.Empty <ICertificate>());
 }
Ejemplo n.º 34
0
 public AzurePowershellContext()
 {
     this.fileSystem = new WindowsPhysicalFileSystem();
     this.certificateStore = new CalamariCertificateStore();
     this.embeddedResources = new ExecutingAssemblyEmbeddedResources();
 }
Ejemplo n.º 35
0
 public CertificateInstallation(ICertificateStore personalStore, ICertificateStore authorityStore)
 {
     _personalStore = personalStore;
     _authorityStore = authorityStore;
 }