Пример #1
0
        private static PkixCertPathBuilderResult VerifyCertificate(X509Certificate target, Org.BouncyCastle.Utilities.Collections.HashSet trustedRootCerts, Org.BouncyCastle.Utilities.Collections.HashSet intermediateCerts)
        {
            intermediateCerts.Add(target);

            // Create the selector that specifies the starting certificate
            var selector = new X509CertStoreSelector()
            {
                Certificate = target
            };

            // Create the trust anchors (set of root CA certificates)
            var trustAnchors = new Org.BouncyCastle.Utilities.Collections.HashSet();

            foreach (X509Certificate trustedRootCert in trustedRootCerts)
            {
                trustAnchors.Add(new TrustAnchor(trustedRootCert, null));
            }

            PkixBuilderParameters pkixParams = new PkixBuilderParameters(trustAnchors, selector)
            {
                // Disable CRL checks (this is done manually as additional step)
                IsRevocationEnabled = false
            };

            // Specify a list of intermediate certificates
            IX509Store intermediateCertStore = X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(intermediateCerts));

            pkixParams.AddStore(intermediateCertStore);

            // Build and verify the certification chain
            PkixCertPathBuilder       builder = new PkixCertPathBuilder();
            PkixCertPathBuilderResult result  = builder.Build(pkixParams);

            return(result);
        }
Пример #2
0
        /// <summary>
        /// Gets the trusted anchors.
        /// </summary>
        /// <remarks>
        /// A trusted anchor is a trusted root-level X.509 certificate,
        /// generally issued by a certificate authority (CA).
        /// </remarks>
        /// <returns>The trusted anchors.</returns>
        protected override Org.BouncyCastle.Utilities.Collections.HashSet GetTrustedAnchors()
        {
            var anchors = new Org.BouncyCastle.Utilities.Collections.HashSet();

            foreach (var certificate in certificates)
            {
                anchors.Add(new TrustAnchor(certificate, null));
            }

            return(anchors);
        }
Пример #3
0
        BuildCertificateChainBC(
            byte[] primary,
            System.Collections.Generic.IEnumerable <byte[]> additional)
        {
            X509CertificateParser parser  = new X509CertificateParser();
            PkixCertPathBuilder   builder = new PkixCertPathBuilder();

            // Separate root from itermediate
            System.Collections.Generic.List <Org.BouncyCastle.X509.X509Certificate> intermediateCerts =
                new System.Collections.Generic.List <Org.BouncyCastle.X509.X509Certificate>();

            Org.BouncyCastle.Utilities.Collections.HashSet rootCerts =
                new Org.BouncyCastle.Utilities.Collections.HashSet();

            foreach (byte[] cert in additional)
            {
                Org.BouncyCastle.X509.X509Certificate x509Cert = parser.ReadCertificate(cert);

                // Separate root and subordinate certificates
                if (x509Cert.IssuerDN.Equivalent(x509Cert.SubjectDN))
                {
                    rootCerts.Add(new TrustAnchor(x509Cert, null));
                }
                else
                {
                    intermediateCerts.Add(x509Cert);
                }
            }

            // Create chain for this certificate
            X509CertStoreSelector holder = new X509CertStoreSelector();

            holder.Certificate = parser.ReadCertificate(primary);

            // WITHOUT THIS LINE BUILDER CANNOT BEGIN BUILDING THE CHAIN
            intermediateCerts.Add(holder.Certificate);

            PkixBuilderParameters builderParams = new PkixBuilderParameters(rootCerts, holder);

            builderParams.IsRevocationEnabled = false;

            X509CollectionStoreParameters intermediateStoreParameters =
                new X509CollectionStoreParameters(intermediateCerts);

            builderParams.AddStore(X509StoreFactory.Create(
                                       "Certificate/Collection", intermediateStoreParameters));

            PkixCertPathBuilderResult result = builder.Build(builderParams);

            return(System.Linq.Enumerable.Cast <Org.BouncyCastle.X509.X509Certificate>(result.CertPath.Certificates));
        }
Пример #4
0
        /// <summary>
        /// Gets the trusted anchors.
        /// </summary>
        /// <remarks>
        /// A trusted anchor is a trusted root-level X.509 certificate,
        /// generally issued by a Certificate Authority (CA).
        /// </remarks>
        /// <returns>The trusted anchors.</returns>
        protected override Org.BouncyCastle.Utilities.Collections.HashSet GetTrustedAnchors()
        {
            var anchors  = new Org.BouncyCastle.Utilities.Collections.HashSet();
            var selector = new X509CertStoreSelector();
            var keyUsage = new bool[9];

            keyUsage[(int)X509KeyUsageBits.KeyCertSign] = true;
            selector.KeyUsage = keyUsage;

            foreach (var record in dbase.Find(selector, true, X509CertificateRecordFields.Certificate))
            {
                anchors.Add(new TrustAnchor(record.Certificate, null));
            }

            return(anchors);
        }
Пример #5
0
        /// <summary>
        /// Gets the trusted anchors.
        /// </summary>
        /// <remarks>
        /// A trusted anchor is a trusted root-level X.509 certificate,
        /// generally issued by a certificate authority (CA).
        /// </remarks>
        /// <returns>The trusted anchors.</returns>
        protected override Org.BouncyCastle.Utilities.Collections.HashSet GetTrustedAnchors()
        {
            var anchors = new Org.BouncyCastle.Utilities.Collections.HashSet();

            foreach (var certificate in certificates)
            {
                var keyUsage = certificate.GetKeyUsage();

                if (keyUsage != null && keyUsage[(int)X509KeyUsageBits.KeyCertSign] && certificate.IsSelfSigned())
                {
                    anchors.Add(new TrustAnchor(certificate, null));
                }
            }

            return(anchors);
        }
Пример #6
0
        /// <summary>
        /// Gets the trusted anchors.
        /// </summary>
        /// <remarks>
        /// A trusted anchor is a trusted root-level X.509 certificate,
        /// generally issued by a certificate authority (CA).
        /// </remarks>
        /// <returns>The trusted anchors.</returns>
        protected override Org.BouncyCastle.Utilities.Collections.HashSet GetTrustedAnchors()
        {
            var anchors  = new Org.BouncyCastle.Utilities.Collections.HashSet();
            var selector = new X509CertStoreSelector();
            var keyUsage = new bool[9];

            keyUsage[(int)X509KeyUsageBits.KeyCertSign] = true;
            selector.KeyUsage = keyUsage;

            foreach (var certificate in certificates)
            {
                if (selector.Match(certificate))
                {
                    anchors.Add(new TrustAnchor(certificate, null));
                }
            }

            return(anchors);
        }
Пример #7
0
		/// <summary>
		/// Gets the trusted anchors.
		/// </summary>
		/// <remarks>
		/// Gets the trusted anchors.
		/// </remarks>
		/// <returns>The trusted anchors.</returns>
		protected override Org.BouncyCastle.Utilities.Collections.HashSet GetTrustedAnchors ()
		{
			var storeNames = new StoreName[] { StoreName.TrustedPeople, StoreName.Root };
			var anchors = new Org.BouncyCastle.Utilities.Collections.HashSet ();

			foreach (var storeName in storeNames) {
				var store = new X509Store (storeName, StoreLocation);

				store.Open (OpenFlags.ReadOnly);

				foreach (var certificate in store.Certificates) {
					var cert = DotNetUtilities.FromX509Certificate (certificate);
					anchors.Add (new TrustAnchor (cert, null));
				}

				store.Close ();
			}

			return anchors;
		}
Пример #8
0
        /// <inheritdoc/>
        public async Task <(X509Certificate Certificate, RsaKeyParameters Key)> GetLocalCertificateAsync(ApplicationDescription applicationDescription, ILogger logger = null)
        {
            string applicationUri = applicationDescription.ApplicationUri;

            if (string.IsNullOrEmpty(applicationUri))
            {
                throw new ArgumentOutOfRangeException(nameof(applicationDescription), "Expecting ApplicationUri in the form of 'http://{hostname}/{appname}' -or- 'urn:{hostname}:{appname}'.");
            }

            string subjectName = null;
            string hostName    = null;
            string appName     = null;

            UriBuilder appUri = new UriBuilder(applicationUri);

            if (appUri.Scheme == "http" && !string.IsNullOrEmpty(appUri.Host))
            {
                var path = appUri.Path.Trim('/');
                if (!string.IsNullOrEmpty(path))
                {
                    hostName    = appUri.Host;
                    appName     = path;
                    subjectName = $"CN={appName},DC={hostName}";
                }
            }

            if (appUri.Scheme == "urn")
            {
                var parts = appUri.Path.Split(new[] { ':' }, 2);
                if (parts.Length == 2)
                {
                    hostName    = parts[0];
                    appName     = parts[1];
                    subjectName = $"CN={appName},DC={hostName}";
                }
            }

            if (subjectName == null)
            {
                throw new ArgumentOutOfRangeException(nameof(applicationDescription), "Expecting ApplicationUri in the form of 'http://{hostname}/{appname}' -or- 'urn:{hostname}:{appname}'.");
            }

            var crt = default(X509Certificate);
            var key = default(RsaKeyParameters);

            // Build 'own/certs' certificate store.
            var ownCerts     = new Org.BouncyCastle.Utilities.Collections.HashSet();
            var ownCertsInfo = new DirectoryInfo(Path.Combine(this.pkiPath, "own", "certs"));

            if (ownCertsInfo.Exists)
            {
                foreach (var info in ownCertsInfo.EnumerateFiles())
                {
                    using (var crtStream = info.OpenRead())
                    {
                        var c = this.certParser.ReadCertificate(crtStream);
                        if (c != null)
                        {
                            ownCerts.Add(c);
                        }
                    }
                }
            }

            IX509Store ownCertStore = X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(ownCerts));

            // Select the newest certificate that matches by subject name.
            var selector = new X509CertStoreSelector()
            {
                Subject = new X509Name(subjectName)
            };

            crt = ownCertStore.GetMatches(selector).OfType <X509Certificate>().OrderBy(c => c.NotBefore).LastOrDefault();
            if (crt != null)
            {
                // If certificate found, verify alt-name, and retrieve private key.
                var asn1OctetString = crt.GetExtensionValue(X509Extensions.SubjectAlternativeName);
                if (asn1OctetString != null)
                {
                    var          asn1Object = X509ExtensionUtilities.FromExtensionValue(asn1OctetString);
                    GeneralNames gns        = GeneralNames.GetInstance(asn1Object);
                    if (gns.GetNames().Any(n => n.TagNo == GeneralName.UniformResourceIdentifier && n.Name.ToString() == applicationUri))
                    {
                        var ki = new FileInfo(Path.Combine(this.pkiPath, "own", "private", $"{crt.SerialNumber}.key"));
                        if (ki.Exists)
                        {
                            using (var keyStream = new StreamReader(ki.OpenRead()))
                            {
                                var keyReader = new PemReader(keyStream);
                                var keyPair   = keyReader.ReadObject() as AsymmetricCipherKeyPair;
                                if (keyPair != null)
                                {
                                    key = keyPair.Private as RsaKeyParameters;
                                }
                            }
                        }
                    }
                }
            }

            // If certificate and key are found, return to caller.
            if (crt != null && key != null)
            {
                logger?.LogTrace($"Found certificate with subject alt name '{applicationUri}'.");
                return(crt, key);
            }

            if (!this.CreateLocalCertificateIfNotExist)
            {
                return(null, null);
            }

            // Create new certificate
            var subjectDN = new X509Name(subjectName);

            // Create a keypair.
            var kp = await Task.Run <AsymmetricCipherKeyPair>(() =>
            {
                RsaKeyPairGenerator kg = new RsaKeyPairGenerator();
                kg.Init(new KeyGenerationParameters(this.rng, 2048));
                return(kg.GenerateKeyPair());
            });

            key = kp.Private as RsaPrivateCrtKeyParameters;

            // Create a certificate.
            X509V3CertificateGenerator cg = new X509V3CertificateGenerator();
            var subjectSN = BigInteger.ProbablePrime(120, this.rng);

            cg.SetSerialNumber(subjectSN);
            cg.SetSubjectDN(subjectDN);
            cg.SetIssuerDN(subjectDN);
            cg.SetNotBefore(DateTime.Now.Date.ToUniversalTime());
            cg.SetNotAfter(DateTime.Now.Date.ToUniversalTime().AddYears(25));
            cg.SetPublicKey(kp.Public);

            cg.AddExtension(
                X509Extensions.BasicConstraints.Id,
                true,
                new BasicConstraints(false));

            cg.AddExtension(
                X509Extensions.SubjectKeyIdentifier.Id,
                false,
                new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(kp.Public)));

            cg.AddExtension(
                X509Extensions.AuthorityKeyIdentifier.Id,
                false,
                new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(kp.Public), new GeneralNames(new GeneralName(subjectDN)), subjectSN));

            cg.AddExtension(
                X509Extensions.SubjectAlternativeName,
                false,
                new GeneralNames(new[] { new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri), new GeneralName(GeneralName.DnsName, hostName) }));

            cg.AddExtension(
                X509Extensions.KeyUsage,
                true,
                new KeyUsage(KeyUsage.DataEncipherment | KeyUsage.DigitalSignature | KeyUsage.NonRepudiation | KeyUsage.KeyCertSign | KeyUsage.KeyEncipherment));

            cg.AddExtension(
                X509Extensions.ExtendedKeyUsage,
                true,
                new ExtendedKeyUsage(KeyPurposeID.IdKPClientAuth, KeyPurposeID.IdKPServerAuth));

            crt = cg.Generate(new Asn1SignatureFactory("SHA256WITHRSA", key, this.rng));

            logger?.LogTrace($"Created certificate with subject alt name '{applicationUri}'.");

            var keyInfo = new FileInfo(Path.Combine(this.pkiPath, "own", "private", $"{crt.SerialNumber}.key"));

            if (!keyInfo.Directory.Exists)
            {
                Directory.CreateDirectory(keyInfo.DirectoryName);
            }
            else if (keyInfo.Exists)
            {
                keyInfo.Delete();
            }

            using (var keystream = new StreamWriter(keyInfo.OpenWrite()))
            {
                var pemwriter = new PemWriter(keystream);
                pemwriter.WriteObject(key);
            }

            var crtInfo = new FileInfo(Path.Combine(this.pkiPath, "own", "certs", $"{crt.SerialNumber}.crt"));

            if (!crtInfo.Directory.Exists)
            {
                Directory.CreateDirectory(crtInfo.DirectoryName);
            }
            else if (crtInfo.Exists)
            {
                crtInfo.Delete();
            }

            using (var crtstream = new StreamWriter(crtInfo.OpenWrite()))
            {
                var pemwriter = new PemWriter(crtstream);
                pemwriter.WriteObject(crt);
            }

            return(crt, key);
        }
Пример #9
0
        /// <inheritdoc/>
        public Task <bool> ValidateRemoteCertificateAsync(X509Certificate target, ILogger logger = null)
        {
            if (this.AcceptAllRemoteCertificates)
            {
                return(Task.FromResult(true));
            }

            var trustedCerts     = new Org.BouncyCastle.Utilities.Collections.HashSet();
            var trustedCertsInfo = new DirectoryInfo(Path.Combine(this.pkiPath, "trusted"));

            if (!trustedCertsInfo.Exists)
            {
                trustedCertsInfo.Create();
            }

            foreach (var info in trustedCertsInfo.EnumerateFiles())
            {
                using (var crtStream = info.OpenRead())
                {
                    var crt = this.certParser.ReadCertificate(crtStream);
                    if (crt != null)
                    {
                        trustedCerts.Add(crt);
                    }
                }
            }

            var intermediateCerts     = new Org.BouncyCastle.Utilities.Collections.HashSet();
            var intermediateCertsInfo = new DirectoryInfo(Path.Combine(this.pkiPath, "issuer"));

            if (!intermediateCertsInfo.Exists)
            {
                intermediateCertsInfo.Create();
            }

            foreach (var info in intermediateCertsInfo.EnumerateFiles())
            {
                using (var crtStream = info.OpenRead())
                {
                    var crt = this.certParser.ReadCertificate(crtStream);
                    if (crt != null)
                    {
                        intermediateCerts.Add(crt);
                    }
                }
            }

            if (IsSelfSigned(target))
            {
                // Create the selector that specifies the starting certificate
                var selector = new X509CertStoreSelector()
                {
                    Certificate = target
                };
                IX509Store trustedCertStore = X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(trustedCerts));
                if (trustedCertStore.GetMatches(selector).Count > 0)
                {
                    return(Task.FromResult(true));
                }

                logger?.LogError($"Error validatingRemoteCertificate.");
                this.StoreInRejectedFolder(target);
                return(Task.FromResult(false));
            }

            try
            {
                var res = VerifyCertificate(target, trustedCerts, intermediateCerts);
            }
            catch (Exception ex)
            {
                logger?.LogError($"Error validatingRemoteCertificate. {ex.Message}");
                this.StoreInRejectedFolder(target);
                return(Task.FromResult(false));
            }

            return(Task.FromResult(true));
        }
Пример #10
0
		/// <summary>
		/// Gets the trusted anchors.
		/// </summary>
		/// <returns>The trusted anchors.</returns>
		protected override Org.BouncyCastle.Utilities.Collections.HashSet GetTrustedAnchors ()
		{
			var anchors = new Org.BouncyCastle.Utilities.Collections.HashSet ();

			foreach (var certificate in certificates) {
				anchors.Add (new TrustAnchor (certificate, null));
			}

			return anchors;
		}
Пример #11
0
        /// <summary>
        /// Builds certification path for provided signing certificate
        /// </summary>
        /// <param name="signingCertificate">Signing certificate</param>
        /// <param name="otherCertificates">Other certificates that should be used in path building process. Self-signed certificates from this list are used as trust anchors.</param>
        /// <returns>Certification path for provided signing certificate</returns>
        public ICollection <Org.BouncyCastle.X509.X509Certificate> BuildCertPath(byte[] signingCertificate, List <byte[]> otherCertificates)
        {
            if (signingCertificate == null)
            {
                throw new ArgumentNullException("signingCertificate");
            }

            List <Org.BouncyCastle.X509.X509Certificate> result = new List <Org.BouncyCastle.X509.X509Certificate>();

            Org.BouncyCastle.X509.X509Certificate signingCert = ToBouncyCastleObject(signingCertificate);



            Org.BouncyCastle.Utilities.Collections.ISet  trustAnchors = new Org.BouncyCastle.Utilities.Collections.HashSet();
            List <Org.BouncyCastle.X509.X509Certificate> otherCerts   = new List <Org.BouncyCastle.X509.X509Certificate>();

            if (IsSelfSigned(signingCert))
            {
                result.Add(signingCert);
            }
            else
            {
                otherCerts.Add(signingCert);

                if (otherCertificates != null)
                {
                    foreach (byte[] otherCertificate in otherCertificates)
                    {
                        Org.BouncyCastle.X509.X509Certificate otherCert = ToBouncyCastleObject(otherCertificate);
                        otherCerts.Add(ToBouncyCastleObject(otherCertificate));
                        if (IsSelfSigned(otherCert))
                        {
                            trustAnchors.Add(new TrustAnchor(otherCert, null));
                        }
                    }
                }

                if (trustAnchors.Count < 1)
                {
                    throw new PkixCertPathBuilderException("Provided certificates do not contain self-signed root certificate");
                }

                X509CertStoreSelector targetConstraints = new X509CertStoreSelector();
                targetConstraints.Certificate = signingCert;

                PkixBuilderParameters certPathBuilderParameters = new PkixBuilderParameters(trustAnchors, targetConstraints);
                certPathBuilderParameters.AddStore(X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(otherCerts)));
                certPathBuilderParameters.IsRevocationEnabled = false;

                PkixCertPathBuilder       certPathBuilder       = new PkixCertPathBuilder();
                PkixCertPathBuilderResult certPathBuilderResult = certPathBuilder.Build(certPathBuilderParameters);

                foreach (Org.BouncyCastle.X509.X509Certificate certPathCert in certPathBuilderResult.CertPath.Certificates)
                {
                    result.Add(certPathCert);
                }

                result.Add(certPathBuilderResult.TrustAnchor.TrustedCert);
            }

            return(result);
        }
Пример #12
0
        /// <inheritdoc/>
        public bool ValidateRemoteCertificate(X509Certificate target)
        {
            if (this.AcceptAllRemoteCertificates)
            {
                return(true);
            }

            var trustedCerts      = new Org.BouncyCastle.Utilities.Collections.HashSet();
            var intermediateCerts = new Org.BouncyCastle.Utilities.Collections.HashSet();
            var trustedCertsInfo  = new DirectoryInfo(Path.Combine(this.pkiDirectoryPath, "trusted", "certs"));

            if (trustedCertsInfo.Exists)
            {
                foreach (var info in trustedCertsInfo.EnumerateFiles())
                {
                    using (var crtStream = info.OpenRead())
                    {
                        var crt = this.certParser.ReadCertificate(crtStream);
                        if (crt != null)
                        {
                            trustedCerts.Add(crt);
                        }
                    }
                }
            }

            var intermediateCertsInfo = new DirectoryInfo(Path.Combine(this.pkiDirectoryPath, "issuer", "certs"));

            if (intermediateCertsInfo.Exists)
            {
                foreach (var info in intermediateCertsInfo.EnumerateFiles())
                {
                    using (var crtStream = info.OpenRead())
                    {
                        var crt = this.certParser.ReadCertificate(crtStream);
                        if (crt != null)
                        {
                            intermediateCerts.Add(crt);
                        }
                    }
                }
            }

            if (IsSelfSigned(target))
            {
                // Create the selector that specifies the starting certificate
                var selector = new X509CertStoreSelector()
                {
                    Certificate = target
                };
                IX509Store trustedCertStore = X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(trustedCerts));
                return(trustedCertStore.GetMatches(selector).Count > 0);
            }

            try
            {
                var res = VerifyCertificate(target, trustedCerts, intermediateCerts);
            }
            catch (Exception ex)
            {
                return(false);
            }

            return(true);
        }
Пример #13
0
		/// <summary>
		/// Gets the trusted anchors.
		/// </summary>
		/// <remarks>
		/// A trusted anchor is a trusted root-level X.509 certificate,
		/// generally issued by a Certificate Authority (CA).
		/// </remarks>
		/// <returns>The trusted anchors.</returns>
		protected override Org.BouncyCastle.Utilities.Collections.HashSet GetTrustedAnchors ()
		{
			var anchors = new Org.BouncyCastle.Utilities.Collections.HashSet ();
			var selector = new X509CertStoreSelector ();
			var keyUsage = new bool[9];

			keyUsage[(int) X509KeyUsageBits.KeyCertSign] = true;
			selector.KeyUsage = keyUsage;

			foreach (var record in dbase.Find (selector, true, X509CertificateRecordFields.Certificate)) {
				anchors.Add (new TrustAnchor (record.Certificate, null));
			}

			return anchors;
		}