Example #1
0
        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);
                    }
                }
            }