简体   繁体   中英

Invalidate CRL cache

Is there a way to immediately invalidate the CRL (Certificate Revocation List) cache causing clients to download the CRL again?

I would like to achieve it in C# without resorting to the command line 'certutil.exe'.

Even better would be to be able to set the invalidation time (like UtcNow + 12hours)

I already implement such solution, it update CRL cache on clients machine every x hours, depending of scheduler settings. You can read about CRL here: http://social.technet.microsoft.com/wiki/contents/articles/4954.certificate-status-and-revocation-checking.aspx

CRL cache is stored on client machine in special folders and consist of two files stored in Metadata and Content folders. These folders are placed in “C:\\Documents and Settings{user name}\\Application Data\\Microsoft\\CryptnetUrlCache” and the per-machine cache location is “%WINDIR%\\System32\\config\\SystemProfile\\Application Data\\Microsoft\\CryptnetUrlCache”. Cahce files are named in MD5 hash sum of CRL url. File in folder "Metadata" contains some constant data, date of last update, CRL url, CRL file size and other. And file in "Content" folder is CRL file itself and has the same name as file from "Metadata". I parse meta file, check if it invalid and load new CRL file by CRL url, place it to "Content" folder and rebuild metadata file. I use BouncyCastle library for these purposes. As scheduling library I use Quartz.Net.

I know you don't want to use certutil.exe but this way you can run it in your application without cmd window showing up, if that was what you didn't want.

public bool ClearCRLCache()
{
    var pw = new ProcessWrapper();
    var result = pw.Start("certutil.exe", "-urlcache * delete");
    // -2147024637 is the exitcode when the urlcache is empty
    return (result == 0 || result == -2147024637);
}

The class ProcessWrapper:

public class ProcessWrapper
{
    /// <summary>
    /// Output from stderr
    /// </summary>
    public string StdErr { get; private set; }

    /// <summary>
    /// Output from stdout
    /// </summary>
    public string StdOut { get; private set; }

    /// <summary>
    /// Starts a process
    /// </summary>
    /// <param name="command">Executable filename</param>
    /// <returns>Process exitcode</returns>
    public int Start(string command)
    {
        return Start(command, "");
    }

    /// <summary>
    /// Starts a process with commandline arguments
    /// </summary>
    /// <param name="command">Executable filename</param>
    /// <param name="arguments">Commanline arguments for the process</param>
    /// <returns>Process exitcode</returns>
    public int Start(string command, string arguments)
    {
        return Start(command, arguments, "");
    }

    /// <summary>
    /// Starts a process with commandline arguments and working directory
    /// </summary>
    /// <param name="command">Executable filename</param>
    /// <param name="arguments">Commanline arguments for the process</param>
    /// <param name="workingDirectory">Working directory for the process</param>
    /// <returns>Process exitcode</returns>
    public int Start(string command, string arguments, string workingDirectory)
    {
        StdErr = "";
        StdOut = "";
        var proc = new Process();
        proc.StartInfo.FileName = command;
        proc.StartInfo.Arguments = arguments;
        proc.StartInfo.WorkingDirectory = workingDirectory;
        proc.StartInfo.UseShellExecute = false;
        proc.StartInfo.RedirectStandardOutput = true;
        proc.StartInfo.RedirectStandardError = true;
        proc.EnableRaisingEvents = true;
        proc.StartInfo.CreateNoWindow = true;

        // Write messages from stderr to StdErr property
        proc.ErrorDataReceived += (sender, e) =>
        {
            StdErr += e.Data + Environment.NewLine;
        };

        // Write messages from stdout to StdOut property
        proc.OutputDataReceived += (sender, e) =>
        {
            StdOut += e.Data + Environment.NewLine;
        };

        proc.Start();

        proc.BeginErrorReadLine();
        proc.BeginOutputReadLine();

        proc.WaitForExit();
        return proc.ExitCode;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM