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); }
/// <summary> /// Gets the trust anchors. /// </summary> /// <returns>The trust anchors.</returns> protected override Org.BouncyCastle.Utilities.Collections.HashSet GetTrustedAnchors() { var anchors = new Org.BouncyCastle.Utilities.Collections.HashSet(); // FIXME: how do we get the trusted root certs? return(anchors); }
/// <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); }
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)); }
/// <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); }
/// <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); }
/// <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); }
/// <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; }
/// <summary> /// /// </summary> /// <param name="certificateChain"></param> /// <exception cref="PkixCertPathValidatorException"></exception> /// <exception cref="CryptographicException"></exception> public SigningCertificate(string certificateChain) { StringReader stringReader = new StringReader(certificateChain); PemReader pemReader = new PemReader(stringReader); List <X509Certificate> certificates = new List <X509Certificate>(); X509Certificate certificate; while ((certificate = (X509Certificate)pemReader.ReadObject()) != null) { certificates.Add(certificate); } path = new PkixCertPath(certificates); Org.BouncyCastle.Utilities.Collections.ISet trustAnchors = new Org.BouncyCastle.Utilities.Collections.HashSet(new TrustAnchor[] { new TrustAnchor(certificates.Last(), null) }); PkixParameters pkixParameters = new PkixParameters(trustAnchors); pkixParameters.IsRevocationEnabled = false; PkixCertPathValidator certPathValidator = new PkixCertPathValidator(); certPathValidator.Validate(path, pkixParameters); VerifyDistinguishedName(path); }
/// <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); }
/// <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)); }
/// <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; }
/// <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); }
/// <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); }
/// <summary> /// Gets the trust anchors. /// </summary> /// <returns>The trust anchors.</returns> protected override Org.BouncyCastle.Utilities.Collections.HashSet GetTrustedAnchors() { var anchors = new Org.BouncyCastle.Utilities.Collections.HashSet (); // FIXME: how do we get the trusted root certs? return anchors; }
/// <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; }