windowsocspcertutil

Microsoft OCSP Check (OCSP vs Lightweight OCSP) & confusing Responses by "certutil -url"


Regular OCSP (RFC 6960)

I have written an OCSP Responder where the Response based itself on the RFC 6960 which states that :

If nextUpdate is not set, the responder is indicating that newer revocation information is available all the time.

So I did not set the nextUpdate and just used the BouncyCastle BasicOCSPRespBuilder like here (which sets thisUpdate by default,as also seen in Wireshark Capture) :

basicOCSPRespBuilder.addResponse(certID, responseList.get(certID));

But these responses were rejected by the certificate authenticator in IIS. On trying certutil the response Status was always "Expired".

enter image description here

This was verified using "certutil -url " command.

Lightweight OCSP (RFC 5019)

A bit of googling revealed that Microsoft supports Lightweight OCSP as per RFC 5019 which states:

Clients MUST check for the existence of the nextUpdate field and MUST ensure the current time, expressed in GMT time as described in Section 2.2.4, falls between the thisUpdate and nextUpdate times. If the nextUpdate field is absent, the client MUST reject the response.

So I modified the implementation to include a nextUpdate Date ( a few minutes in future ), as below :

basicOCSPRespBuilder.addResponse(certID, responseList.get(certID), getNextUpdateDate(), null);

This got me out of the "Expired" Status problem, but now the issue is that when this is deployed to the Webserver and I attempt to perform the "certutil -url" check, it returns "Verified" for WebProxy link in the Certificate, but if I provide the URL of the server directly it displays an "OK". The Response structure remaining the same in both cases as it is the same responder ( Verified using the Wireshark Capture, I could attach this as well if you like ).

enter image description here

issuerKeyHash field

The interesting fact here is that the OCSP Requests sent to the server are different in case of via WebProxy and Direct URL. The difference being the OCSP Request does not include the issuerKeyHash when sending the request to the direct link.

Wireshark capture of OCSP Request sent to Webproxy that returned a "Verified" :-

enter image description here

Wireshark Capture of OCSP Request sent to direct link that returned status "OK" :-

enter image description here

The question is how come the request includes the issuerKeyHash in one and in the other instance not. Furthermore, why is the the Status not same for both the queries even though the OCSP Response from the Server is similar (confirmed by Wireshark Caputres).

I would also be grateful for any insightful documentation / link for the "URL Retrieval Tool" or "certutil -verify" in this regard.

I can also include the Wireshark Captures on request.

I haven't included Java and Bouncycastle as a tags as the OCSP Responses are accepted by Java, openssl etc. without any issues (with or without nextUpdate as per RFC 6960). This Question is to understand what's going on with Microsoft certutil & the OCSP Check here.

Update #1

--- Begin Update #1 ---

As suggested by @Crypt32; I could verify that when using a URL in the URL Field, a complete Certificate-Path is not built for reasons unknown and hence the missing IssuerKeyHash.

The assumption was that the Response always contains IssuerKeyHash and this could be leading to the OK instead of Verified status. To confirm this I modified the response to match the request and did not send an IssuerKeyHash if it was not delivered in the Request but the status remained OK and didn't change to Verified.

The idea is to correctly understand how Microsoft Applications process OCSP Responses and how to implement the Responder correctly so that no Microsoft Applications fall flat on their face.

Research ongoing, any advise and suggestions appreciated !!

--- End Update #1 ---


Solution

  • Re. nextUpdate

    Microsoft uses the Lightweight OCSP and hence requires a thisUpdate and nextUpdate as mandatory as cited in the RFC 5019.

    Re. certutil

    The query regarding certutil has now been clarified thanks to @Crypt32.

    Re. IssuerKeyHash

    When using a custom URL in the "URL to download" box of certutil, a complete certificate chain is not generated and hence resulting in an OCSP Request without IssuerKeyHash.

    Standard CryptoAPI clients never send an OCSP Request with empty IssuerKeyHash and this is just peculiar certutil behavior which may be ignored as it also tends to fail with Windows OCSP Servers (verified at my end with a Microsoft CA as well)