PKISolutions / PSPKI

PowerShell PKI Module
Microsoft Public License
368 stars 59 forks source link

Random NetworkRetrievalError for OCSP when running Get-EnterprisePKIHealthStatus #216

Open PChipVIA opened 1 month ago

PChipVIA commented 1 month ago

For some reason, randomly the Get-EnterprisePKIHealthStatus returns a NetworkRetrievalError on the OCSP. However the Enterprise PKI and even testing with OpenSSL do not return any errors.

Environment Information: Powershell version 5.1.14393.6343. Also the same with 5.1.19041.4412. PSPKI version 4.2.0 (latest with fix #215)

PS C:\> Get-EnterprisePKIHealthStatus -CertificateAuthority (Get-CertificationAuthority server.******.tld) | Select -ExpandProperty Childs | Select -f 1 -ExpandProperty URLs

Name              : AIA Location #1
Status            : Ok
ExtendedErrorInfo :
Url               : http://pki1.******.ca/PKI-12(1).crt
ExpirationDate    : 2/2/2029 8:46:28 AM
UrlType           : Certificate

Name              : AIA Location #2
Status            : Ok
ExtendedErrorInfo :
Url               : http://pki2.******.ca/PKI-12(1).crt
ExpirationDate    : 2/2/2029 8:46:28 AM
UrlType           : Certificate

Name              : CDP Location #1
Status            : Ok
ExtendedErrorInfo :
Url               : http://pki1.******.ca/PKI-12(1).crl
ExpirationDate    : 6/3/2024 4:55:48 PM
UrlType           : Crl

Name              : CDP Location #2
Status            : Ok
ExtendedErrorInfo :
Url               : http://pki2.******.ca/PKI-12(1).crl
ExpirationDate    : 6/3/2024 4:55:48 PM
UrlType           : Crl

Name              : OCSP Location #1
Status            : NetworkRetrievalError
ExtendedErrorInfo :
Url               : http://ocsp.******.ca/ocsp
ExpirationDate    :
UrlType           : Ocsp
Crypt32 commented 1 month ago

Can you conduct a quick test:

ipmo PSPKI
$xchg = Get-CA server.******.tld | Get-CAExchangeCertificate -X509
$ocspReq = New-Object SysadminsLV.PKI.OcspClient.OCSPRequest $xchg
$ocspReq.SendRequest()

and show any error

PChipVIA commented 1 month ago

Got one

PS C:\> $xchg = Get-CAExchangeCertificate -X509 -CertificationAuthority (Get-CA $([System.Net.DNS]::GetHostEntry('').HostName))
PS C:\> $ocspReq = New-Object SysadminsLV.PKI.OcspClient.OCSPRequest $xchg
PS C:\> $ocspReq.SendRequest()

Exception calling "SendRequest" with "0" argument(s): "Input data does not represent valid 'GeneralizedTime' type."
At line:1 char:1
+ $ocspReq.SendRequest()
+ ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : Asn1InvalidTagException

PS C:\> 

Here's an Export-CliXML of the $ocspReq (renamed domain of ocsp)

<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <TN RefId="0">
      <T>SysadminsLV.PKI.OcspClient.OCSPRequest</T>
      <T>System.Object</T>
    </TN>
    <ToString>SysadminsLV.PKI.OcspClient.OCSPRequest</ToString>
    <Props>
      <I32 N="Version">1</I32>
      <B N="Nonce">false</B>
      <Nil N="NonceValue" />
      <Obj N="RequestList" RefId="1">
        <TN RefId="1">
          <T>SysadminsLV.PKI.OcspClient.OCSPSingleRequestCollection</T>
          <T>SysadminsLV.PKI.BasicCollection`1[[SysadminsLV.PKI.OcspClient.OCSPSingleRequest, SysadminsLV.PKI.OcspClient, Version=4.2.0.0, Culture=neutral, PublicKeyToken=null]]</T>
          <T>System.Object</T>
        </TN>
        <IE>
          <Obj RefId="2">
            <TN RefId="2">
              <T>SysadminsLV.PKI.OcspClient.OCSPSingleRequest</T>
              <T>System.Object</T>
            </TN>
            <ToString>SysadminsLV.PKI.OcspClient.OCSPSingleRequest</ToString>
            <Props>
              <S N="CertId">SysadminsLV.PKI.OcspClient.CertID</S>
              <Obj N="Extensions" RefId="3">
                <TN RefId="3">
                  <T>System.Security.Cryptography.X509Certificates.X509ExtensionCollection</T>
                  <T>System.Object</T>
                </TN>
                <IE />
              </Obj>
              <Obj N="CertificateName" RefId="4">
                <TN RefId="4">
                  <T>System.Security.Cryptography.X509Certificates.X500DistinguishedName</T>
                  <T>System.Security.Cryptography.AsnEncodedData</T>
                  <T>System.Object</T>
                </TN>
                <ToString>System.Security.Cryptography.X509Certificates.X500DistinguishedName</ToString>
                <Props>
                  <BA N="RawData">MHMxCzAJBgNVBAYTAkNBMRIwEAYKCZImiZPyLGQBGRYCY2ExFzAVBgoJkiaJk/IsZAEZFgd2aWFyYWlsMRAwDgYDVQQKEwdWSUFSYWlsMQwwCgYDVQQLEwNQS0kxFzAVBgNVBAMTDlZJQVBLSS0xMi1YY2hn</BA>
                </Props>
              </Obj>
            </Props>
          </Obj>
        </IE>
        <Props>
          <I32 N="Count">1</I32>
          <B N="IsReadOnly">false</B>
        </Props>
      </Obj>
      <Obj N="Extensions" RefId="5">
        <TNRef RefId="3" />
        <IE />
        <Props>
          <I32 N="Count">0</I32>
          <B N="IsSynchronized">false</B>
          <Ref N="SyncRoot" RefId="5" />
        </Props>
      </Obj>
      <URI N="URL">http://ocsp.domain.ca/ocsp</URI>
      <Nil N="SignerCertificate" />
      <Nil N="Proxy" />
      <Obj N="AcceptedSignatureAlgorithms" RefId="6">
        <TN RefId="5">
          <T>System.Security.Cryptography.Oid[]</T>
          <T>System.Array</T>
          <T>System.Object</T>
        </TN>
        <LST>
          <Obj RefId="7">
            <TN RefId="6">
              <T>System.Security.Cryptography.Oid</T>
              <T>System.Object</T>
            </TN>
            <ToString>sha1RSA (1.2.840.113549.1.1.5)</ToString>
            <Props>
              <S N="Value">1.2.840.113549.1.1.5</S>
              <S N="FriendlyName">sha1RSA</S>
            </Props>
          </Obj>
        </LST>
      </Obj>
      <BA N="RawData">MFQwUjBQME4wTDAJBgUrDgMCGgUABBQ2zpAvKWOUMw2afYilvaVl8dQIyQQUM4u/nCATOKj9kEr40DNXzdbTIZgCEyAAAMxsBtSL03bA/GgAAQAAzGw=</BA>
    </Props>
  </Obj>
</Objs>
Crypt32 commented 1 month ago

Ok, so the problem is in ASN.1 parser which has some issues with parsing GeneralizedTime. Can you do one more test, please:

$rsp = Invoke-WebRequest -Uri "http://ocsp.domain.ca/ocsp/MFQwUjBQME4wTDAJBgUrDgMCGgUABBQ2zpAvKWOUMw2afYilvaVl8dQIyQQUM4u/nCATOKj9kEr40DNXzdbTIZgCEyAAAMxsBtSL03bA/GgAAQAAzGw="
# ensure that yo get HTTP 200 response
$rsp
# this will produce a binary response
[convert]::ToBase64String($rsp.Content)

And post this base64 string. Alternatively (for privacy concerns), you can email it to me: vpodans&sysadmins.lv (replace ampersnad with @). This will provide me enough information to find exact issue and fix it.

Crypt32 commented 1 month ago

I was able to debug the code and find the root cause. The issue is that my ASN.1 parser is quite smart and found that your OCSP Responder KeyID attribute is a complex object, not a simple octet string (KeyID must be a plain octet string without nested content): image

Here is linked issue in underlying library: https://github.com/PKISolutions/pkix.net/issues/80

Crypt32 commented 1 month ago

The fix will be available in v4.3