private CertificateVerificationResult VerifyCertificate(X509Certificate2 certificate, IReadOnlyList <X509Certificate2> extraCertificates, Oid applicationPolicy) { X509Chain chain = null; try { chain = new X509Chain(); // Allow the chain to use whatever additional extra certificates were provided. chain.ChainPolicy.ExtraStore.AddRange(extraCertificates.ToArray()); if (applicationPolicy != null) { chain.ChainPolicy.ApplicationPolicy.Add(applicationPolicy); } chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; var resultBuilder = new CertificateVerificationResult.Builder(); if (chain.Build(certificate)) { resultBuilder.WithStatus(EndCertificateStatus.Good); resultBuilder.WithStatusFlags(X509ChainStatusFlags.NoError); } else { resultBuilder.WithStatus(GetEndCertificateStatusFromInvalidChain(chain)); resultBuilder.WithStatusFlags(FlattenChainStatusFlags(chain)); } InspectChain(chain, certificate, resultBuilder); return(resultBuilder.Build()); } finally { if (chain != null) { foreach (var chainElement in chain.ChainElements) { chainElement.Certificate.Dispose(); } chain.Dispose(); } } }
private unsafe void InspectChain(X509Chain chain, X509Certificate2 certificate, CertificateVerificationResult.Builder resultBuilder) { var addedRef = false; var chainHandle = chain.SafeHandle; try { chainHandle.DangerousAddRef(ref addedRef); CERT_REVOCATION_INFO *pRevocationInfo = GetEndCertificateRevocationInfoPointer(chainHandle, certificate); if (CertificateWasVerifiedOnline(pRevocationInfo)) { resultBuilder.WithRevocationTime(GetRevocationTime(pRevocationInfo)); resultBuilder.WithStatusUpdateTime(GetStatusUpdateTime(pRevocationInfo)); } } finally { if (addedRef) { chainHandle.DangerousRelease(); } } }