public static CertificateSecurityInformation Verify(this Org.BouncyCastle.X509.X509Certificate cert, DateTime date, int[] keyUsageIndexes, int minimumKeySize, IX509Store certs, ref IList <CertificateList> crls, ref IList <BasicOcspResponse> ocsps) { CertificateSecurityInformation result = new CertificateSecurityInformation(); result.Certificate = new X509Certificate2(cert.GetEncoded()); //check key size AsymmetricKeyParameter key = cert.GetPublicKey(); if (!VerifyKeySize(key, minimumKeySize)) { result.securityViolations.Add(CertSecurityViolation.NotValidKeySize); trace.TraceEvent(TraceEventType.Warning, 0, "The key was smaller then {0}", minimumKeySize); } //check key usages foreach (int i in keyUsageIndexes) { if (!cert.GetKeyUsage()[i]) { result.securityViolations.Add(CertSecurityViolation.NotValidForUsage); trace.TraceEvent(TraceEventType.Warning, 0, "The key usage did not have the correct usage flag {0} set", i); } } //build extra store X509Certificate2Collection extraStore = new X509Certificate2Collection(); foreach (Org.BouncyCastle.X509.X509Certificate obj in certs.GetMatches(null)) { extraStore.Add(new X509Certificate2(obj.GetEncoded())); } CertificateSecurityInformation dest = result; CertificateSecurityInformation previous = null; Org.BouncyCastle.X509.X509Certificate issuer = cert.ValidateAndGetDerivedIssuer(certs); if (issuer != null) { trace.TraceEvent(TraceEventType.Verbose, 0, "Detected eHealth variant of proxy certificate"); //check proxy certificate, is it still valid? if (!cert.IsValid(date)) { dest.securityViolations.Add(CertSecurityViolation.NotTimeValid); trace.TraceEvent(TraceEventType.Warning, 0, "The proxy certificate is expired or not yet valid, {0} not between {1}-{2}", date, cert.NotBefore, cert.NotAfter); } //The issuer signature of the proxy certificate is already checked... //check issuer previous = dest; dest = new CertificateSecurityInformation(); dest.Certificate = new X509Certificate2(issuer.GetEncoded()); //check key size of the issuer key = issuer.GetPublicKey(); if (!VerifyKeySize(key, minimumKeySize)) { dest.securityViolations.Add(CertSecurityViolation.NotValidKeySize); trace.TraceEvent(TraceEventType.Warning, 0, "The key of the issuer was smaller then {0}", minimumKeySize); } //check key usage of the issuer foreach (int i in new int[] { 0, 1 }) { if (!issuer.GetKeyUsage()[i]) { dest.securityViolations.Add(CertSecurityViolation.NotValidForUsage); trace.TraceEvent(TraceEventType.Warning, 0, "The key usage of the issuer did not have the correct usage flag set"); } } } //check the chain Chain chain; if (crls != null || ocsps != null) { chain = dest.Certificate.BuildChain(date, extraStore, crls, ocsps); } else { chain = dest.Certificate.BuildChain(date, extraStore); } //process the chain foreach (ChainElement ce in chain.ChainElements) { //connect the prepared link if (previous != null) { previous.IssuerInfo = dest; } //update the link dest.Certificate = ce.Certificate; foreach (X509ChainStatus status in ce.ChainElementStatus.Where(x => x.Status != X509ChainStatusFlags.NoError)) { dest.securityViolations.Add((CertSecurityViolation)Enum.Parse(typeof(CertSecurityViolation), Enum.GetName(typeof(X509ChainStatusFlags), status.Status))); } //prepare the next link previous = dest; dest = new CertificateSecurityInformation(); } if (chain.ChainStatus.Count(x => x.Status == X509ChainStatusFlags.PartialChain) > 0) { result.securityViolations.Add(CertSecurityViolation.IssuerTrustUnknown); } trace.TraceEvent(TraceEventType.Verbose, 0, "Verified certificate {0} for date {1}", cert.SubjectDN.ToString(), date); return(result); }