How to Script Disabling CRL Checking With Netsh and Powershell

I ran into a situation where I needed to automate disabling the certificate revocation list (CRL) checking for a certificate. I won't go into all the details, except to say that the trust chain provider URL was not available to the server with the certificate, so this had to be done as a temporary fix to enable the certificate to validate.

Here are the steps for disabling the CRL:

There are 3 steps to the manual process of doing this:

  1. "netsh http show sslcert" to show a list of certificates associated with ports so you can find yours.
  2. "netsh http delete sslcert ipport=…" where ipport is the port associated with the cert you're interested in from the list above. This removes the association.
  3. "netsh http add sslcert ipport=… certhash=… appid=… certstorename=… verifyclientcertrevocation=disable" to re-add the certificate association with CRL checking option disabled.

Great that we have a manual process to do this, but what do you do if you need to automate deployment (to an Azure role, in our case)? The netsh command spits a bunch of useful text out for a human reader, but not for a computer to read and script.

My approach to automate this process was to write the below Powershell script. It captures the output from step #1 above, parses it into variables, then composes commands for steps #2 and #3 using those variables.  If you want to spend the time, you can optimize the script to probably about half the number of lines, but I chose to code it in a more step-by-step fashion so you could more easily see what is happening.  This is meant to be a start and teaching tool to set you off on your own way.

Save the text of the script below to a file with a .ps1 extension.  Run the script by giving it the command line argument of your certificate hash number (eg PS C:\> .\ssltest.ps1 094898a90ab97564cc79f3351561c90625001053).

# Get a list of the registered ssl certs and find the index of

# the first line in the output containing the target thumbprint

# note that $certHashMatches may be an array if the thumbprint

# is associated with several ports

$output = Invoke-Expression "netsh http show sslcert"

$certHashMatches = $output | Select-String $args[0]

$line = $certHashMatches.LineNumber

# Parse the details of that cert relative to the output line the

# target thumbprint was found on

$retVal = New-Object System.Object

$retVal | Add-Member -type NoteProperty -Name IPPort -Value ([regex]::Match($output[$line-2], "\s+:\s+(\d+.\d+.\d+.\d+:\d+)").Groups[1].Value)

$retVal | Add-Member -type NoteProperty -Name CertHash -Value ([regex]::Match($output[$line-1], "\s+:\s+(\w+)").Groups[1].Value)

$retVal | Add-Member -type NoteProperty -Name AppId -Value ([regex]::Match($output[$line], "\s+:\s+({\w+-\w+-\w+-\w+-\w+})").Groups[1].Value)

$retVal | Add-Member -type NoteProperty -Name CertStoreName -Value ([regex]::Match($output[$line+1], "\s+:\s+(\w+)").Groups[1].Value)

$retVal | Add-Member -type NoteProperty -Name VerifyClientCertRevocation -Value ([regex]::Match($output[$line+2], "\s+:\s+(\w+)").Groups[1].Value)

$retVal | Add-Member -type NoteProperty -Name VerifyRevocationWithCachedClientCertOnly -Value ([regex]::Match($output[$line+3], "\s+:\s+(\w+)").Groups[1].Value)

# Create and invoke a command line to delete the cert

$expression = "netsh http delete sslcert ipport=" + $retVal.IPPort

Invoke-Expression $expression

# Create and invoke a command line to put it back in with

# the verifyclientcertrevocation option disabled

$expression = "netsh http add sslcert ipport=" + $retVal.IPPort

$expression += " certhash=" + $retVal.CertHash

$expression += " appid='" + $retVal.AppId + "'"

$expression += " certstorename=" + $retVal.CertStoreName

$expression += " verifyclientcertrevocation=disable"

Invoke-Expression $expression