Re-Revoking Certificates with Different Reason Code

 

One of my customers is using 3rd party Card Management System (CMS) to manage their smart cards. One of many common management tasks that such systems perform is revocation of the smart card and in particular the certificates issued to the given smart card. Well, of course CMS only originates the revocation request - the actual revocation is performed on CA that issued certificates. Certificates can be revoked for different reasons and when you revoke it is good idea to specify the reason code for revocation. Some implementations require that the reason code is specified, and some implementations require that this reason code must be set to "key compromise". If you do not specify the reason code during revocation then it will be set to the default reason code which is  "unspecified". 

 

So this particular  CMS does not specify the reason code when it sends revocation requests to CA. At the same time customer Security Policy dictates that all subscriber certificates will be revoked with "key compromise" reason code.

 

As I mention before the default revocation reason code for Windows 2003 CA is "unspecified". It is not possible to change the default setting to any other reason code.

 

Since CMS doesn't specify the reason code for revocation all revoked certificates by this CMS are revoked with the reason code "unspecified". This is a problem for them and we had to find some quick and easy solution to change the reason code on already revoked certificates from "unspecified" to "key compromise".

 

Fortunately it is possible to do in couple different ways. One of them is to use certutil.exe command to re-revoke already issued certificates and specify new required reason code.

 

Here is the command you need to run to revoke a certificate with Serial Number 18e877ea00000000000a and reason code "key compromise":

 

certutil -revoke "18e877ea00000000000a" 1

 

So far so good, but how do we know what Serial Number to put into this command? We need to know what certificates already have been revoked. Well, the same utility comes to our rescue. If you run the following command it will provide you with Serial Numbers of all revoked certificates after the specified date:

 

certutil –view –restrict "RevokedWhen>=08/15/2007" –out SerialNumber

 

OK, so we run this command, get all serial numbers of revoked certificates, populate this numbers to the first command and re-revoke all of them with new reason code. Cool, but what kind of output does this command provide to us? Can we easily grab serial numbers out from it?

 

The output from this command looks similar to this:

 

1/1/2006 12:00 AM

Schema:

  Column Name                   Localized Name                Type    MaxLength

  ----------------------------  ----------------------------  ------  ---------

  SerialNumber                  Serial Number                 String  128 -- Indexed

 

Row 1:

  Serial Number: "61153ff1000000000006"

 

Row 2:

  Serial Number: "18daada4000000000007"

 

Row 3:

  Serial Number: "18e2c82a000000000008"

 

Row 4:

  Serial Number: "18e3c5d4000000000009"

 

Row 5:

  Serial Number: "18e877ea00000000000a"

 

Can we get actual numbers out of this output? To the rescue comes Visual Basic script that parse through this information and as it finds anything between "" it takes it, and then creates the revocation command and executes that command.

 

First we run this command and create the output file with serial numbers:

 

certutil –view –restrict "RevokedWhen>=08/15/2007" –out SerialNumber > sn-input.txt

 

 

Then we can run the following VBScript to re-revoke all certificates that have been revoked since 8/15/07. Here is the sample script to do it:

 

sInFile = "sn-input.txt"

sDelimiter = """"

 

const ForReading = 1, ForWriting = 2, ForAppending = 8

 

set oShell = wscript.createobject("wscript.shell")

set oFSO = wscript.createobject("scripting.filesystemobject")

 

if oFSO.FileExists(sInFile) then

                set oInFile = oFSO.OpenTextFile(sInFile,ForReading)

else

                wscript.echo "Input file " & sInFile & " does not exist."

                wscript.quit(1)

end if

 

do while not oInFile.AtEndOfStream

 

                sLine = oInFile.ReadLine

                aValues = split(sLine,sDelimiter)

                if ubound(aValues)>0 then

                                if ucase(trim(aValues(0))) = ucase("Serial Number:") then

                                               iRetVal = oShell.Run("certutil -revoke " & """"& aValues(1) &"""" & " 1",TRUE)

                                end if

                end if

 

loop ' oFile

 

oInFile.Close

 

 

Now it should be easy to create a batch file that will first create an input file with  serial numbers of all revoked certificates and then run vbscript that will parse through this file and re-revoke them with new reason code.

 

To truly really automate this solution we'll need to automatically inject the date into the command that creates the input file, otherwise it will re-revoke bunch more certificates that we really need. But I didn’t do any investigation yet on how easy it would be inject a certain date into that command. Maybe some other time.

 

By the way it would take me much longer to come up with this solution if not for some quick pointers from PG and help with writing vbscript from  another MS Consultant. Mark you are da man!