internal void Finish(OidCollection applicationPolicy, OidCollection certificatePolicy) { WorkingChain workingChain = null; // If the chain had any errors during the previous build we need to walk it again with // the error collector running. if (Interop.Crypto.X509StoreCtxGetError(_storeCtx) != Interop.Crypto.X509VerifyStatusCode.X509_V_OK) { Interop.Crypto.X509StoreCtxReset(_storeCtx); workingChain = new WorkingChain(); Interop.Crypto.X509StoreVerifyCallback workingCallback = workingChain.VerifyCallback; Interop.Crypto.X509StoreCtxSetVerifyCallback(_storeCtx, workingCallback); bool verify = Interop.Crypto.X509VerifyCert(_storeCtx); GC.KeepAlive(workingCallback); // Because our callback tells OpenSSL that every problem is ignorable, it should tell us that the // chain is just fine (unless it returned a negative code for an exception) Debug.Assert(verify, "verify should have returned true"); const Interop.Crypto.X509VerifyStatusCode NoCrl = Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_CRL; ErrorCollection?errors = workingChain.LastError > 0 ? (ErrorCollection?)workingChain[0] : null; if (_revocationMode == X509RevocationMode.Online && _remainingDownloadTime > TimeSpan.Zero && errors?.HasError(NoCrl) == true) { Interop.Crypto.X509VerifyStatusCode ocspStatus = CheckOcsp(); ref ErrorCollection refErrors = ref workingChain[0]; if (ocspStatus == Interop.Crypto.X509VerifyStatusCode.X509_V_OK) { refErrors.ClearError(NoCrl); } else if (ocspStatus != NoCrl) { refErrors.ClearError(NoCrl); refErrors.Add(ocspStatus); } } }