public static void FlushStores() { OpenSslX509ChainProcessor.FlushStores(); }
private static IChainPal?BuildChainCore( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection?extraStore, OidCollection?applicationPolicy, OidCollection?certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, X509Certificate2Collection?customTrustStore, X509ChainTrustMode trustMode, DateTime verificationTime, TimeSpan timeout, bool disableAia) { if (timeout == TimeSpan.Zero) { // An input value of 0 on the timeout is treated as 15 seconds, to match Windows. timeout = TimeSpan.FromSeconds(15); } else if (timeout > s_maxUrlRetrievalTimeout || timeout < TimeSpan.Zero) { // Windows has a max timeout of 1 minute, so we'll match. Windows also treats // the timeout as unsigned, so a negative value gets treated as a large positive // value that is also clamped. timeout = s_maxUrlRetrievalTimeout; } // Let Unspecified mean Local, so only convert if the source was UTC. // // Converge on Local instead of UTC because OpenSSL is going to assume we gave it // local time. if (verificationTime.Kind == DateTimeKind.Utc) { verificationTime = verificationTime.ToLocalTime(); } // Until we support the Disallowed store, ensure it's empty (which is done by the ctor) using (new X509Store(StoreName.Disallowed, StoreLocation.CurrentUser, OpenFlags.ReadOnly)) { } TimeSpan downloadTimeout = timeout; OpenSslX509ChainProcessor chainPal = OpenSslX509ChainProcessor.InitiateChain( ((OpenSslX509CertificateReader)cert).SafeHandle, customTrustStore, trustMode, verificationTime, downloadTimeout); Interop.Crypto.X509VerifyStatusCode status = chainPal.FindFirstChain(extraStore); if (OpenSslX509ChainEventSource.Log.IsEnabled()) { OpenSslX509ChainEventSource.Log.FindFirstChainFinished(status); } if (!OpenSslX509ChainProcessor.IsCompleteChain(status)) { if (disableAia) { if (OpenSslX509ChainEventSource.Log.IsEnabled()) { OpenSslX509ChainEventSource.Log.AiaDisabled(); } } else { List <X509Certificate2>?tmp = null; status = chainPal.FindChainViaAia(ref tmp); if (OpenSslX509ChainEventSource.Log.IsEnabled()) { OpenSslX509ChainEventSource.Log.FindChainViaAiaFinished(status, tmp?.Count ?? 0); } if (tmp != null) { if (status == Interop.Crypto.X509VerifyStatusCode.X509_V_OK) { SaveIntermediateCertificates(tmp); } foreach (X509Certificate2 downloaded in tmp) { downloaded.Dispose(); } } } } if (revocationMode != X509RevocationMode.NoCheck) { if (OpenSslX509ChainProcessor.IsCompleteChain(status)) { // Checking the validity period for the certificates in the chain is done after the // check for a trusted root, so accept expired (or not yet valid) as acceptable for // processing revocation. if (status != Interop.Crypto.X509VerifyStatusCode.X509_V_OK && status != Interop.Crypto.X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_NOT_YET_VALID && status != Interop.Crypto.X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_HAS_EXPIRED) { if (OpenSslX509ChainEventSource.Log.IsEnabled()) { OpenSslX509ChainEventSource.Log.UntrustedChainWithRevocation(); } revocationMode = X509RevocationMode.NoCheck; } chainPal.CommitToChain(); chainPal.ProcessRevocation(revocationMode, revocationFlag); } } chainPal.Finish(applicationPolicy, certificatePolicy); #if DEBUG if (chainPal.ChainElements !.Length > 0) { X509Certificate2 reportedLeaf = chainPal.ChainElements[0].Certificate; Debug.Assert(reportedLeaf != null, "reportedLeaf != null"); Debug.Assert(!ReferenceEquals(cert, reportedLeaf.Pal), "!ReferenceEquals(cert, reportedLeaf.Pal)"); } #endif return(chainPal); }
internal static partial IChainPal?BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection?extraStore, OidCollection?applicationPolicy, OidCollection?certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, X509Certificate2Collection?customTrustStore, X509ChainTrustMode trustMode, DateTime verificationTime, TimeSpan timeout, bool disableAia) { if (timeout == TimeSpan.Zero) { // An input value of 0 on the timeout is treated as 15 seconds, to match Windows. timeout = TimeSpan.FromSeconds(15); } else if (timeout > s_maxUrlRetrievalTimeout || timeout < TimeSpan.Zero) { // Windows has a max timeout of 1 minute, so we'll match. Windows also treats // the timeout as unsigned, so a negative value gets treated as a large positive // value that is also clamped. timeout = s_maxUrlRetrievalTimeout; } // Let Unspecified mean Local, so only convert if the source was UTC. // // Converge on Local instead of UTC because OpenSSL is going to assume we gave it // local time. if (verificationTime.Kind == DateTimeKind.Utc) { verificationTime = verificationTime.ToLocalTime(); } // Until we support the Disallowed store, ensure it's empty (which is done by the ctor) using (new X509Store(StoreName.Disallowed, StoreLocation.CurrentUser, OpenFlags.ReadOnly)) { } TimeSpan downloadTimeout = timeout; OpenSslX509ChainProcessor chainPal = OpenSslX509ChainProcessor.InitiateChain( ((OpenSslX509CertificateReader)cert).SafeHandle, customTrustStore, trustMode, verificationTime, downloadTimeout); Interop.Crypto.X509VerifyStatusCode status = chainPal.FindFirstChain(extraStore); if (!OpenSslX509ChainProcessor.IsCompleteChain(status) && !disableAia) { List <X509Certificate2>?tmp = null; status = chainPal.FindChainViaAia(ref tmp); if (tmp != null) { if (status == Interop.Crypto.X509VerifyStatusCode.X509_V_OK) { SaveIntermediateCertificates(tmp); } foreach (X509Certificate2 downloaded in tmp) { downloaded.Dispose(); } } } // In NoCheck+OK then we don't need to build the chain any more, we already // know it's error-free. So skip straight to finish. if (status != Interop.Crypto.X509VerifyStatusCode.X509_V_OK || revocationMode != X509RevocationMode.NoCheck) { if (OpenSslX509ChainProcessor.IsCompleteChain(status)) { chainPal.CommitToChain(); chainPal.ProcessRevocation(revocationMode, revocationFlag); } } chainPal.Finish(applicationPolicy, certificatePolicy); #if DEBUG if (chainPal.ChainElements !.Length > 0) { X509Certificate2 reportedLeaf = chainPal.ChainElements[0].Certificate; Debug.Assert(reportedLeaf != null, "reportedLeaf != null"); Debug.Assert(!ReferenceEquals(cert, reportedLeaf.Pal), "!ReferenceEquals(cert, reportedLeaf.Pal)"); } #endif return(chainPal); }