OCSP issues
I have a 2008 R2 setup as DC/Enterprise CA. It is also running IIS for OCSP.
My problem lies in non domain members outside the firewall not being able to access the OCSP. My internal clients can hit it no problem.
I have enabled port forwarding on 80/443 to one of the interfaces on the server. I fired up an EC2 instance of 2008r2 and I can hit both the HTTP site and HTTPS site through the firewall. When I do a : certutil -url webServer.cer It fails everytime. It also
fails on certutil -verify webServer.cer. saying the OCSP responder is not online.
When I attempted to connect to the OCSP from INSIDE the firewall with a non-domain member I am prompted for uname/pwd (while going to IE
http://myserver.com/ocsp)
here is some of the output from certutil -verify
------------------------------------
419.3401.0: 0x800b010a (-2146762486)
Incomplete certificate chain
Cannot find certificate:
CN=myserver.com
ERROR: Verifying leaf certificate revocation status returned The revocation func
tion was unable to check revocation because the revocation server was offline. 0
x80092013 (-2146885613)
CertUtil: The revocation function was unable to check revocation because the rev
ocation server was offline.
CertUtil: -verify command completed successfully.
I suspect the problem is I have some permissions incorrect somewhere but am lost as to where I should be looking first.
I need to allow anonymous authentication to access the OCSP to verify certs.
Thank you!
July 23rd, 2011 1:57pm
yes, you're right you need to enable anonymous authentication on OCSP virtual directory.
http://technet.microsoft.com/en-us/library/cc731244(WS.10).aspxMy weblog: http://en-us.sysadmins.lv
PowerShell PKI Module: http://pspki.codeplex.com
Windows PKI reference:
on TechNet wiki
Free Windows Admin Tool Kit Click here and download it now
July 23rd, 2011 3:05pm
I have corrected the authentication part but still seem to be having issues. here is the output from certutil -verify
I think this is telling me it cant find the Root CA Cert?
-------- CERT_CHAIN_CONTEXT --------
ChainContext.dwErrorStatus = CERT_TRUST_REVOCATION_STATUS_UNKNOWN (0x40)
ChainContext.dwErrorStatus = CERT_TRUST_IS_OFFLINE_REVOCATION (0x1000000)
ChainContext.dwErrorStatus = CERT_TRUST_IS_PARTIAL_CHAIN (0x10000)
SimpleChain.dwErrorStatus = CERT_TRUST_REVOCATION_STATUS_UNKNOWN (0x40)
SimpleChain.dwErrorStatus = CERT_TRUST_IS_OFFLINE_REVOCATION (0x1000000)
SimpleChain.dwErrorStatus = CERT_TRUST_IS_PARTIAL_CHAIN (0x10000)
CertContext[0][0]: dwInfoStatus=2 dwErrorStatus=1000040
Issuer: CN=myserver.com
NotBefore: 7/23/2011 5:54 AM
NotAfter: 7/22/2013 5:54 AM
Subject: CN=myserver.com, OU=a, O=a, L=a, S=a, C=US
Serial: 619ab07c00000000000d
Template: WebServer
f6 fd bb af 9f 36 41 bf 5d 78 af ef 77 1f cd ca 95 a1 c4 ea
Element.dwInfoStatus = CERT_TRUST_HAS_KEY_MATCH_ISSUER (0x2)
Element.dwErrorStatus = CERT_TRUST_REVOCATION_STATUS_UNKNOWN (0x40)
Element.dwErrorStatus = CERT_TRUST_IS_OFFLINE_REVOCATION (0x1000000)
Application[0] = 1.3.6.1.5.5.7.3.1 Server Authentication
Exclude leaf cert:
da 39 a3 ee 5e 6b 4b 0d 32 55 bf ef 95 60 18 90 af d8 07 09
Full chain:
f6 fd bb af 9f 36 41 bf 5d 78 af ef 77 1f cd ca 95 a1 c4 ea
Missing Issuer: CN=mysever.com
Issuer: CN=myserver.com
NotBefore: 7/23/2011 5:54 AM
NotAfter: 7/22/2013 5:54 AM
Subject: CN=myserver.com, OU=a, O=a, L=a, S=a, C=US
Serial: 619ab07c000000000m00d
Template: WebServer
f6 fd bb af 9f 36 41 bf 5d 78 af ef 77 1f cd ca 95 a1 c4 ea
A certificate chain could not be built to a trusted root authority. 0x800b010a (
-2146762486)
------------------------------------
Incomplete certificate chain
Cannot find certificate:
CN=myserver.com
Leaf certificate revocation check passed
CertUtil: -verify command completed successfully.
July 23rd, 2011 4:01pm
certutil -url shows
Status: Unsuccessful
Type: OCSP
URL: [0.0] http://myserver.com/ocsp
I'm not sure what this is telling me.
Free Windows Admin Tool Kit Click here and download it now
July 23rd, 2011 4:02pm
it seems that OCSP is still not accessible from outside.My weblog: http://en-us.sysadmins.lv
PowerShell PKI Module: http://pspki.codeplex.com
Windows PKI reference:
on TechNet wiki
July 23rd, 2011 5:05pm
HA! Yep, any ideas? NTFS permissions? private key permissions?
is the ocsp folder supposed to be empty?
in another note the W3c log file is logging the request as sc-status 200, completed with no errors?
Free Windows Admin Tool Kit Click here and download it now
July 23rd, 2011 5:12pm
if you are saying that OCSP works within internal network then it most likely you have issues with OCSP publishing to the internet.My weblog: http://en-us.sysadmins.lv
PowerShell PKI Module: http://pspki.codeplex.com
Windows PKI reference:
on TechNet wiki
July 24th, 2011 3:46am
Yes. So can anyone point me to log files or something that can help me resolve this? Thanks!
Free Windows Admin Tool Kit Click here and download it now
July 25th, 2011 9:15am
I have a draft of OCSP test script (in PowerShell):
function Test-OCSP {
<#
#>
[CmdletBinding(DefaultParameterSetName='File')]
param (
[Parameter(ParameterSetName = "File", Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
[string]$File,
[Parameter(ParameterSetName = "Certificate", Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
[Security.Cryptography.X509Certificates.X509Certificate2]$Certificate,
[ValidateSet("SHA1","MD5")]
[string]$Hash = "SHA1",
[string]$URL,
[switch]$Nonce
)
#region data type definitions
Add-Type @'
using System;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
namespace PKI
{
namespace OCSP
{
public class OCSPClient
{
public string OCSPRequest;
public string OCSPResponse;
}
}
}
'@
#endregion
#region Helper functions
function Get-ASNLength ($RawData, $offset) {
$return = "" | Select FullLength, Padding, LengthBytes, PayLoadLength
if ($RawData[$offset + 1] -lt 128) {
$return.lengthbytes = 1
$return.Padding = 0
$return.PayLoadLength = $RawData[$offset + 1]
$return.FullLength = $return.Padding + $return.lengthbytes + $return.PayLoadLength + 1
} else {
$return.lengthbytes = $RawData[$offset + 1] - 128
$return.Padding = 1
$lengthstring = -join ($RawData[($offset + 2)..($offset + 1 + $return.lengthbytes)] | %{"{0:x2}" -f $_})
$return.PayLoadLength = Invoke-Expression 0x$($lengthstring)
$return.FullLength = $return.Padding + $return.lengthbytes + $return.PayLoadLength + 1
}
$return
}
function Compute-ASNLength ([Byte[]]$RawData, [string]$StructureType = "Sequence") {
if ($RawData.Count -lt 128) {$LengthBytes = $RawData.Count; $ComputedRawData = ,$LengthBytes + $RawData}
else {
if (($RawData.Count % 2) -eq 0) {$LengthBytes = "{0:x2}" -f $RawData.Count} else {$LengthBytes = "0" + ("{0:x2}" -f $RawData.Count)}
[Byte[]]$LengthBytes = $LengthBytes -split "([a-f0-9]{2})" | ?{$_} | %{[Convert]::ToByte($_,16)}
$PaddingByte = 128 + $LengthBytes.Count
$ComputedRawData = ,$PaddingByte + $LengthBytes + $RawData
}
switch ($StructureType) {
"Sequence" {,48 + $ComputedRawData}
"Boolean" {,1 + $ComputedRawData}
"Integer" {,2 + $ComputedRawData}
"BitString" {,3 + $ComputedRawData}
"OctetString" {,4 + $ComputedRawData}
"OID" {,6 + $ComputedRawData}
"UTF8String" {,12 + $ComputedRawData}
"IA5String" {,22 + $ComputedRawData}
"UTCTime" {,23 + $ComputedRawData}
"GeneralizedTime" {,24 + $ComputedRawData}
}
}
#endregion
switch ($PsCmdlet.ParameterSetName) {
"File" {
try {$cert = New-Object security.Cryptography.X509Certificates.X509Certificate2 $File}
catch {Write-Warning "No cert, halt!"; break}
}
"Certificate" {
$cert = $Certificate
}
}
#region OCSP Request
#region object definitions
if ($Hash -eq "SHA1") {$hasher = [System.Security.Cryptography.SHA1]::Create()}
elseif ($Hash -eq "MD5") {$hasher = [System.Security.Cryptography.MD5]::Create()}
#endregion
#region signature sequence computation
$OIDs = New-Object Security.Cryptography.OidCollection
$OID = New-Object Security.Cryptography.Oid $Hash
[void]$OIDs.Add($OID)
$OIDRawData = (New-Object Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension $OIDs, $false).RawData
$OIDRawData = $OIDRawData[2..($OIDRawData.Count - 1)]
$AlgParams = 5,0
$hashAlgorithm = Compute-ASNLength ($OIDRawData + $AlgParams) "Sequence"
#endregion
#region issuerKeyHash property computation
$chain = New-Object Security.Cryptography.X509Certificates.X509Chain
$chain.ChainPolicy.RevocationMode = "NoCheck"
[void]$chain.Build($cert)
if (!$chain.ChainElements[1].Certificate) {Write-Warning "Certificate chain is unavailable, halt!"; break}
$IssuerKey = $chain.ChainElements[1].Certificate.PublicKey.EncodedKeyValue.RawData
$IssuerKeyASNLength = Get-ASNLength $IssuerKey 0
# need to check it in more RFC2560 conformant applications
#$IssuerKeyRawData = $IssuerKey[($IssuerKeyASNLength.Padding + $IssuerKeyASNLength.LengthBytes + 1)..($IssuerKeyASNLength.FullLength - 1)]
#$issuerKeyHash = $hasher.ComputeHash($IssuerKeyRawData)
$issuerKeyHash = $hasher.ComputeHash($IssuerKey)
$issuerKeyHash = Compute-ASNLength $issuerKeyHash "OctetString"
#endregion
#region issuerNameHash computation
$IssuerNameRawData = $cert.IssuerName.RawData
$issuerNameHash = $hasher.ComputeHash($IssuerNameRawData)
$issuerNameHash = Compute-ASNLength $issuerNameHash "OctetString"
#endregion
#region certificate serial number computation
$SN = $cert.SerialNumber -split "([a-f0-9]{2})" | ?{$_} | %{[Convert]::ToByte($_,16)}
$serialNumber = Compute-ASNLength $SN "Integer"
#endregion
#region request message computation
$CertIDRaw = $HashAlgorithm + $issuerNameHash + $issuerKeyHash + $serialNumber
$CertID = Compute-ASNLength $CertIDRaw "Sequence"
$Request = Compute-ASNLength $CertID "Sequence"
$sequenceOfRequests = Compute-ASNLength $Request "Sequence"
$TBSRequest = Compute-ASNLength $sequenceOfRequests "Sequence"
[Byte[]]$OCSPRequest = Compute-ASNLength $TBSRequest "Sequence"
#endregion
#region OCSP URL extraction
if (!$URL) {
$AIA = ($cert.Extensions | ?{$_.Oid.Value -eq "1.3.6.1.5.5.7.1.1"}).RawData
if (!$AIA) {Write-Warning "no AIA, halt!"; break}
$AIALength = Get-ASNLength $AIA 0
$offset = $AIALength.Padding + $AIALength.LengthBytes + 1
$remaining = $AIALength.PayloadLength
[Byte[]]$PatternOID = @(6,8,43,6,1,5,5,7,48,1)
$OCSPURls = @()
do {
$CASNLength = Get-ASNLength $AIA $offset
$OidLength = Get-ASNLength $AIA ($offset + $CASNLength.Padding + $CASNLength.LengthBytes + 1)
[Byte[]]$OCSPOID = $AIA[($offset + $OidLength.Padding + $OidLength.LengthBytes + 1)..($offset + $OidLength.FullLength + 1)]
if ((Compare-Object $OCSPOID $PatternOID) -eq $null) {
$eoffset = $offset + $CASNLength.Padding + $CASNLength.LengthBytes + $OidLength.FullLength + 1
$OCSPURLLength = Get-ASNLength $AIA $eoffset
$OCSPURL = -join ($AIA[($eoffset + $OCSPURLLength.Padding + $OCSPURLLength.LengthBytes + 1)..($eoffset + $OCSPURLLength.FullLength - 1)] | %{[char]$_})
$OCSPURls += $OCSPURL
}
$remaining -= $CASNLength.FullLength
$offset = $offset + $CASNLength.FullLength
} while ($remaining -gt 0)
} else {$OCSPURls = $URL}
#endregion
#region OCSP request send/recieve routine
if ($OCSPURls) {
$binResponces = @()
foreach ($URi in $OCSPURls) {
$wc = New-Object Net.WebClient
$wc.Headers.Add("Content-type", "application/ocsp-request")
try {
$binResponse = $wc.UploadData($URi, $OCSPRequest)
$binResponses += ,$binResponce
} catch {$_; return}
}
} else {Write-Warning "There are no OCSP Responders available"; return}
$Path = [Environment]::GetFolderPath("Desktop") + "\ocsp.rsp"
Set-Content -Path $Path -Value $binResponse -Encoding Byte
}
Copy and paste this code to the PowerShell console (you need PowerShell V2 installed) and run the command:
Test-OCSP -File C:\cert.cer
where C:\cert.cer is a path to a certificate. Please show us any errors (if they appears). Also the script will create a file ocsp.rsp on your desktop. You can send me it via email vpodans&sysadmins.lv (replace & with @).My weblog: http://en-us.sysadmins.lv
PowerShell PKI Module: http://pspki.codeplex.com
Windows PKI reference:
on TechNet wiki
July 25th, 2011 12:48pm


