check single revocation URL...
I can't seem to figure out how to check the revocation status of a certificate for only one specific URL. For instance, in the certificate I want to check I have the following in CDP:
ldap:///CN=RootCA1,CN=CA1,CN=CDP,CN=Public%20Key%20Services,CN=Services,CN=Configuration,DC=mylab,DC=local?certificateRevocationList?base?objectClass=cRLDistributionPoint
http://ca1.mylab.local/CertEnroll/RootCA1.crl
and I have the following in the OCSP extension of AIA:
http://ca1.mylab.local/ocsp
What I would like to do is only check a specific certificate against "http://ca1.mylab.local/CertEnroll/RootCA1.crl". Is there a way to do this with certutil (or another tool)?
April 9th, 2011 7:06pm
try this: certutil -url <certificatefilename>.cer
this will display UI where you can select URL types (AIA, CDP or OCSP). Note that this tool don't perform certificate revocation check, but only CRL availability and whether it is valid.My weblog: http://en-us.sysadmins.lv
PowerShell PKI Module: http://pspki.codeplex.com
Free Windows Admin Tool Kit Click here and download it now
April 10th, 2011 4:53am
I'm familiar with the -url parameter. I'd still like to know a way to check the revocation status of a particular URL rather than the availability of the URL.
April 10th, 2011 9:47am
I'm not sure if such tool exist. However you may write your own. Here is a function for this:
http://msdn.microsoft.com/en-us/library/aa376063(VS.85).aspx
My weblog: http://en-us.sysadmins.lv
PowerShell PKI Module: http://pspki.codeplex.com
Free Windows Admin Tool Kit Click here and download it now
April 10th, 2011 10:05am
It's surprising such a tool doesn't already exist. Oh well...
April 11th, 2011 6:10am
If you wish, I can provide simple example in Windows PowerShell.My weblog: http://en-us.sysadmins.lv
PowerShell PKI Module: http://pspki.codeplex.com
Free Windows Admin Tool Kit Click here and download it now
April 11th, 2011 6:16am
Sure man... let's see it.
April 11th, 2011 6:18am
Here is an example:
function Find-CertInCRL {
param(
[string]$Certificate,
[string]$CRL
)
$signature = @"
[DllImport("CRYPT32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int CertCreateCRLContext(
int dwCertEncodingType,
byte[] pbCrlEncoded,
int cbCrlEncoded
);
[DllImport("CRYPT32.DLL", SetLastError = true)]
public static extern Boolean CertFreeCRLContext(
IntPtr pCrlContext
);
[DllImport("CRYPT32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool CertFindCertificateInCRL(
IntPtr pCert,
IntPtr pCrlContext,
int dwFlags,
IntPtr pvReserved,
ref IntPtr ppCrlEntry
);
[DllImport("CRYPT32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CertFindExtension(
[MarshalAs(UnmanagedType.LPStr)]String pszObjId,
int cExtensions,
IntPtr rgExtensions
);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CRL_ENTRY
{
public CRYPTOAPI_BLOB SerialNumber;
public Int64 RevocationDate;
public int cExtension;
public IntPtr rgExtension;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CRYPTOAPI_BLOB
{
public int cbData;
public IntPtr pbData;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CERT_EXTENSION
{
[MarshalAs(UnmanagedType.LPStr)]public String pszObjId;
public Boolean fCritical;
public CRYPTOAPI_BLOB Value;
}
"@
try {Add-Type -MemberDefinition $signature -Namespace PKI -Name Crypt32}
catch {Write-Warning "failed to load required assemblies!"; return}
try {$Cert = New-Object Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList $Certificate}
catch {Write-Warning "Specified file is not valid certificate!"; return}
if ($(Get-Item $CRL -ErrorAction Stop).PSProvider.Name -ne "FileSystem") {
throw {"File either does not exist or not a file object"}
}
if ($(Get-Item $CRL -ErrorAction Stop).Extension -ne ".crl") {
throw {"File is not valid CRL file"}
}
$Content = Get-Content $CRL
if ($Content[0] -eq "-----BEGIN X509 CRL-----") {
[Byte[]]$cBytes = [Convert]::FromBase64String($(-join $Content[1..($Content.Count - 2)]))
} elseif ($Content[0][0] -eq "M") {
[Byte[]]$cBytes = [Convert]::FromBase64String($(-join $Content))
} else {
[Byte[]]$cBytes = [IO.File]::ReadAllBytes($CRL)
}
$Reasons = @{1="Key compromise";2="CA Compromise";3="Change of Affiliation";4="Superseded";5="Cease Of Operation";
6="Hold Certificiate";7="Privilege Withdrawn";10="aA Compromise"}
$cepvContext = $Cert.Handle
$crpvContext = [PKI.Crypt32]::CertCreateCRLContext(65537,$cBytes,$cBytes.Count)
$ppCrlEntry = [IntPtr]::Zero
$pvReserved = [IntPtr]::Zero
$Status = [PKI.Crypt32]::CertFindCertificateInCRL($cepvContext,$crpvContext,0,$pvReserved,[ref]$ppCrlEntry)
if (!$Status) {Write-Warning "No checking was performed!"; return}
if (!$ppCrlEntry.Equals([IntPtr]::Zero)) {
$Entry = "" | Select SerialNumber, RevocationDate, ReasonCode, ReasonMessage
$CRLEntry = [Runtime.InteropServices.Marshal]::PtrToStructure($ppCrlEntry,[PKI.Crypt32+CRL_ENTRY])
$pByte = $CRLEntry.SerialNumber.pbData
$SerialNumber = ""
for ($m = 0; $m -lt $CRLEntry.SerialNumber.cbData; $m++) {
$bByte = [Runtime.InteropServices.Marshal]::ReadByte($pByte)
$SerialNumber = "{0:x2}" -f $bByte + $SerialNumber
$pByte = [int]$pByte + [Runtime.InteropServices.Marshal]::SizeOf([byte])
}
$Entry.SerialNumber = $SerialNumber
$Entry.RevocationDate = [datetime]::FromFileTime($CRLEntry.RevocationDate)
$CRLReasonCode = ""
[IntPtr]$rcExtension = [PKI.Crypt32]::CertFindExtension("2.5.29.21",$CRLEntry.cExtension,$CRLEntry.rgExtension)
if (!$rcExtension.Equals([IntPtr]::Zero)) {
$CRLExtension = [Runtime.InteropServices.Marshal]::PtrToStructure($rcExtension,[PKI.Crypt32+CERT_EXTENSION])
$pByte = $CRLExtension.Value.pbData
$bBytes = $null
for ($m = 0; $m -lt $CRLExtension.Value.cbData; $m++) {
$bByte = [Runtime.InteropServices.Marshal]::ReadByte($pByte)
[Byte[]]$bBytes += $bByte
$pByte = [int]$pByte + [Runtime.InteropServices.Marshal]::SizeOf([byte])
}
$Entry.ReasonCode = $bBytes[2]
$Entry.ReasonMessage = $Reasons[[int]$Entry.ReasonCode]
}
$Entry
} else {Write-Host "Certificate $($Cert.Serialnumber) is not found in the specified CRL." -ForegroundColor Green}
[void][PKI.Crypt32]::CertFreeCRLContext($crpvContext)
}
copy and paste this code to PowerShell console (PowerShell V2) and run the command:
Find-CertInCRL c:\certfile.cer c:\crlfile.crl
here is example output
[vPodans] Find-CertInCRL .\Desktop\tsgw.cer .\Desktop\pica-1.crl
Certificate 25A00F7E00000000009A is not found in the specified CRL.
[vPodans] Find-CertInCRL .\Desktop\rtsgw.cer .\Desktop\pica-1.crl
SerialNumber RevocationDate ReasonCode ReasonMessage
------------ -------------- ---------- -------------
14d70748000000000071 27.11.2010. 23:27:00 5 Cease Of Operation
[vPodans]
In the first example I have checked non-revoked certificate. In the second — revoked. If certificate is revoked, CRL entry information is displayed.
HTHMy weblog: http://en-us.sysadmins.lv
PowerShell PKI Module: http://pspki.codeplex.com
Free Windows Admin Tool Kit Click here and download it now
April 11th, 2011 7:18am
Excellent... Thanks!
April 11th, 2011 7:25am