CRL freshness checking scripts

Because CRL validity is so important to the functionality of your PKI, it's important to have proactive monitoring of the validity of your CRLs. Particularly in situations where you're using smart cards for logon, having a CRL go stale can be a very disruptive experience to end users.

In my session at IT Forum in Barcelona this week, I'm showing some of the new manageability features of Certificate Services in WS08. One of the major investments for CertSrv in this release is manageability, including integration with MOM/SCOM. One of the features I'm demonstrating is the extensibility of SCOM to help with monitoring the freshness of CRLs. The following scripts can be used to alert you to the status of CRLs before they go stale, allowing you to avoid outages before they happen. They can be integrated with MOM/SCOM for centralized alerting and reporting or just run by themselves.

Here's how the scripts work:

  1. checkCrlFreshness.cmd calls wget.exe (you'll need to download this separately) and downloads the CRL from whatever location you specify
  2. checkCrlFreshness.cmd then calls compareNextUpdateToNow.vbs
  3. compareNextUpdateToNow.vbs calls certutil "nameOfCrl" and scrapes the NextUpdate: line from its output
  4. compareNextUpdateToNow.vbs then compares the hourly NextUpdate value to whatever value is passed by checkCRLFreshness.cmd when it calls compareNextUpdateToNow.vbs
  5. if the NextUpdate value is < the threshold value (i.e. the CRL's expiration is below your minimum value), an alert is written to the application log on the machine where the script is run

SCOM can then be leveraged to watch the event logs for this particular event and then alert or take whatever other action you've specified. Note that if you're running the scripts on Vista or WS08, you can also take advantage of the new Windows eventing infrastructure to run a task or send an email when the event occurs, without having to have MOM/SCOM involved at all.

The nice thing about this script is that it can easily work against any HTTP CDP. So, you can use it to monitor CRLs inside or outside of your organization, including those of partners or service providers that you might depend on.

Scripts are provided as is, us at your own risk, no support, etc, etc…

 

checkCrlFreshness.cmd

:: CRL freshness monitoring master script

:: downloads all relevant CRLs with wget, calls VBScript to compare NextUpdate time with current system time to determine freshness

:: John Morello, Windows Server Division

 

:: uses wget to download CRL; -r says to overwrite existing copy, -nH --cut-dirs=1 says to save in current directory (removes --cut-dirs value from end of URI)

:: wget must be in same directory as this script or in %Path%

wget.exe -r -nH --cut-dirs=1 "https://ws08rc0.pki.test/certenroll/pki-ws08rc0-ca.crl"

 

:: calls compareNextUpdateToNow.vbs to compare time difference between Now() and NextUpdate value in CRL

:: if difference is < the second parameter (in hours), compareNextUpdateToNow.vbs writes warning to AppEvent

cscript compareNextUpdateToNow.vbs "pki-ws08rc0-ca.crl" 336

 

 

compareNextUpdateToNow.vbs

' CRL date comparison script

' takes 2 command line parameters, the name of the CRL and the acceptable age threshold

' if NextUpdate time from CRL is not > acceptable threshold (or other error condition exists), writes event to AppEvent

' Robert Deluca, Windows Server Division

' John Morello, Windows Server Division

 

Option Explicit

 

' check if command line parameters were passed

If WScript.Arguments.Count < 2 Then

wscript.echo "Usage: cscript crldatecheck.vbs <CRL filename> <age threshold in hours>"

wscript.quit

End If

 

' assign params to variables

Dim CRLFilename

CRLFilename = WScript.Arguments.Item(0)

 

Dim ThresholdHours

ThresholdHours = CInt(WScript.Arguments.Item(1))

 

' Create wscript.shell object for exec

Dim WshShell

Set WshShell = CreateObject("WScript.Shell")

 

' Execute certutil

Dim oExec

Set oExec = WshShell.Exec("certutil """ & CRLFilename & """")

 

' Wait for certutil to finish running

Do While oExec.Status = 0

wscript.sleep 100

Loop

 

' Read certutil output until end of stream or found the NextUpdate: line

Dim DateString

Dim Found

Found = false

Do While (Not Found) And (Not oExec.StdOut.AtEndOfStream)

DateString = oExec.StdOut.ReadLine

Found = instr(DateString,"NextUpdate: ") = 1

Loop

 

' exit if the proper line wasn't found

Dim NoNextUpdateFoundMessage

NoNextUpdateFoundMessage = "Failure to read Next Update time from CRL."

If Not Found Then

     wscript.echo "Failure to read Next Update time from CRL."

     WshShell.LogEvent 2, NoNextUpdateFoundMessage

wscript.quit

End If

 

' remove the header from the line

DateString = Replace(DateString,"NextUpdate: ","")

 

' exit if the rest of the string isn't recognized as a date

If Not IsDate(DateString) Then

wscript.echo "Date not recognized as valid."

wscript.quit

End If

 

' convert the string to a date variable

Dim d

d = CDate(DateString)

 

' calculate hours until NextUpdate

Dim HoursUntilUpdate

HoursUntilUpdate = DateDiff("h",Now,d)

 

' display update and threshold information

Dim Message

Message = "Next CRL update is in " & HoursUntilUpdate & " hours. Threshold is " & ThresholdHours & " hours."

wscript.echo Message

 

' update time is below acceptable threshold, write message to screen and event log

If HoursUntilUpdate < ThresholdHours Then

wscript.echo "Time is below acceptable threshold! Writing warning to event log."

WshShell.LogEvent 2, Message

Else

     wscript.echo "Unknown failure! Manually verify CRL and diagnose run time failure."

     WshShell.LogEvent 2, Message

End If

 

wscript.quit