Tag Archives: REVOCATION

CryptoAPI, Revocation checking, OCSP and the Unknown certStatus

In CryptoAPI one can use the CertGetCertificateChain API to do the path building and basic chain validation, this validation may include revocation checking depending on which flags you pass via dwFlags; for example these flags control if revocation checking occurs, and if so, on which certificates:

  • CERT_CHAIN_REVOCATION_CHECK_END_CERT
  • CERT_CHAIN_REVOCATION_CHECK_CHAIN
  • CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT

Typically you would specify CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT which ensures the whole chain is checked (where possible – e.g. one shouldn’t bother asking the root if he considers himself revoked).

But in the context of OCSP what are the potential revocation related returns we might see?

  1. Revoked – I have received a signed response from the CA or have had policy pushed to me that tells me that this certificate is not to be trusted.
  2. Not Revoked – I have received a signed response from the CA that says this certificate was not revoked.
  3. Unknown – I have received signed response from the CA that says it doesn’t know anything about this certificate.
  4. Offline – I was unable to reach the responder to verify the status of the certificate.

Each of these cases are clearly represented in the API that is used by CertGetCertificateChain to perform the revocation check, this API is CertVerifyRevocation. The higher level CertGetCertificateChain however only has two possible returns: Revoked and Unknown outside the “not revoked” case.

One might assume the OCSP Unknown would get mapped into the Revoked state, this unfortunately is not the case, it is returned as unknown, as does the Offline error.

This means that if OCSP was used you cannot tell what the actual status was, this is especially problematic since IE and Chrome both default to modes where they ignore “Unknown” revocations due to concerns over Revocation responder performance and reliability.

It is possible to work around this platform behavior though — the problem is that it’s not documented anywhere, let’s take a quick stab at doing that here.

First since CertGetCertificateChain doesn’t tell us what method was used to do revocation checking we have to use heuristics to figure it out. Thankfully to enable OCSP stapling in higher level protocols like TLS the OCSP response is passed back to the caller if OCSP was used; to get that we need to know:

1. The CERT_CHAIN_ELEMENT in the returned CHAIN_CONTEXT points to the following revocation information:

  • PCERT_REVOCATION_INFO pRevocationInfo;
  • PCERT_REVOCATION_CRL_INFO   pCrlInfo;
  • PCCRL_CONTEXT           pBaseCrlContext;

2. For an OCSP response, the CRL_CONTEXT is specially created to contain the full OCSP response in the following critical extension szOID_PKIX_OCSP_BASIC_SIGNED_RESPONSE.

  • The presence of this extension indicates an OCSP response was used.
  • The Issuer name in the CRL is the name of the OCSP signer.
  • The signature algorithm is sha1NoSign.
  • ThisUpdate and NextUpdate contain the response validity period.

With this we can take the OCSP response from the CRL_CONTEXT and then look at the “ResponseData” within it, you will need to look within the “responses” here,  you will need to find the right “SingleResponse” based on its “CertID”.

NOTE: Some responders will return the status of multiple certificates in a response even if the status of only one was requested.

You now can determine what the responder said the status of the certificate was by inspecting “certStatus” element.

This is a fair amount of work unfortunately but it does enable you to do the right thing with authoritative “Unknown” responses.

Ryan

Serving OCSP on a CDN

So last week we moved our revocation repositories behind a CDN, this has a number of great benefits but it does have downsides though, for example.

  1. Cache misses result in a slower response – About a 110ms in my tests.
  2. OCSP clients that create POSTs get a slower response – This is because they are treated like a cache miss.

Our CDN provider mitigates much he first issue by having a pre-loader that ensures its cache is pre-populated based on request history.

Addressing the second issue requires the CDN provider to be aware of OCSP protocol semantics, specifically the fact that one can compute what a GET request would look like by simply Base64 encoding the binary body of the POST variation.

A CDN with knowledge of this can optimize out the POST derived cache miss, our CDN has done this the change has not yet propagated to all of their datacenters but where it has POST performs the same as a GET.

Hopefully this optimization will have propagated to all their datacenters by next week, when this logic is fully deployed the clients that generate POST based OCSP requests (without a nonce) will also have ~100ms response times.

I should probably ad that in our case almost all of the POST based OCSP requests we receive come from Firefox and do not contain a nonce, hopefully soon Firefox will move to using GET for requests without a nonce like other clients.

Using Monitis to monitor OCSP and CRL performance

Earlier I did a post on the performance of revocation repositories, in that I used the Monitis do some basic bench-marking for repository performance.

They have a cool feature that allows me to create a public monitoring portal on one of my own domains, I have created two:

  1. OCSP Performance
  2. CRL Performance

It also looks like CloudFlare (one of our CDN partners), the ones we are working with to get these great numbers have also done a blog post on what we are doing here – cool stuff!

Ryan

 

Revocation repositories, IPv6 support, message size, and performance

So the last few weeks I have spent a reasonable amount of time looking at performance and networking related problems associated with revocation repositories. I still have some additional work to do but I figured I would capture some of my findings in a quick post.

CRL repositories and IPv6
CA Host Supports V6
GlobalSign crl.globalsign.com Yes
Comodo crl.comodoca.com No/Sometimes
CyberTrust sureseries-crl.cybertrust.ne.jp No
Symantec/GeoTrust EVSSL-crl.geotrust.com No
Symantec/VeriSign EVIntl-crl.verisign.com No
DigiCert crl3.digicert.com No
StartSSL crl.startssl.com No
TrustWave crl.securetrust.com No
TrustCenter crl.ix.tcclass3.tcuniversal-i.trustcenter.de No
GoDaddy crl.godaddy.com No
Entrust crl.entrust.net No
Certum crl.certum.pl No

* IPv6 Capability was checked via http://ipv6-test.com/validate.php

 

OCSP repositories and IPv6
CA Host Supports V6
GlobalSign ocsp.globalsign.com Yes
COMODO ocsp.comodoca.com No
GoDaddy ocsp.godaddy.com No
DigiCert ocsp.digicert.com No
StartCom ocsp.startssl.com No
TrustCenter ocsp.tcuniversal-I.trustcenter.de No
TrustWave ocsp.trustwave.com No
Enstrust ocsp.entrust.net No
Symantec/GeoTrust ocsp.geotrust.com No
Symantec/VeriSign ocsp.verisign.com No
CyberTrust sureseries-ocsp.cybertrust.ne.jp No
Certum ocsp.certum.pl No

* IPv6 Capability was checked via http://ipv6-test.com/validate.php

 

CRL Size
CA CRL Size # Entries
Certum http://crl.certum.pl/evca.crl 862 7
Symantec/Geotrust http://EVSSL-crl.geotrust.com/crls/gtextvalca.crl 720 12
Cybertrust http://sureseries-crl.cybertrust.ne.jp/SureServer/2021_ev/cdp.crl 1742 17
GlobalSign http://crl.globalsign.com/gs/gsextendvalg2.crl 1114 18
TrustWave http://crl.securetrust.com/STCA.crl 2158 65
StartSSL http://crl.startssl.com/crt4-crl.crl 2339 90
DigiCert http://crl3.digicert.com/evca1-g1.crl 5393 100
GoDaddy http://crl.godaddy.com/gds3-37.crl 6848 153
Comodo http://crl.comodoca.com/COMODOExtendedValidationSecureServerCA.crl 12959 351
TrustCenter http://crl.ix.tcclass3.tcuniversal-i.trustcenter.de/crl/v2/tc_class3_L1_CA_IX.crl 16138 407
Entrust http://crl.entrust.net/level1e.crl 40995 1005
Symantec/VeriSign http://EVIntl-crl.verisign.com/EVIntl2006.crl 207922 5972
* CRL count was determined using “curl url>crl & openssl crl -in crl -inform der -text | grep -c “Serial”
* Size was determined using the Content-Length header, “curl –verbose –url *”

 

OCSP response Size
CA Host Size
Comodo ocsp.comodoca.com 471
Digicert ocsp.digicert.com 471
GlobalSign ocsp2.globalsign.com 1491
CyberTrust sureseries-ocsp.cybertrust.ne.jp 1588
StartSSL ocsp.startssl.com 1596
Symantec/Verisign ocsp.verisign.com 1739
GoDaddy ocsp.godaddy.com 1923
Entrust ocsp.entrust.net 1939
Certum ocsp.certum.pl 2113
Trustwave ocsp.trustwave.com 2519
TrustCenter ocsp.tcuniversal-I.trustcenter.de 3135
Symantec/Geotrust ocsp.geotrust.com 3346

* Size was determined using the Content-Length header, “curl –verbose –url *”

 

OCSP Response Performance
CA Host Average (ms)
GlobalSign ocsp2.globalsign.com

95

DigiCert ocsp.digicert.com

156

GoDaddy ocsp.godaddy.com

163

COMODO ocsp.comodoca.com

202

StartCom ocsp.startssl.com

280

Enstrust ocsp.entrust.net

293

Symantec/GeoTrust ocsp.geotrust.com

293

Symantec/VeriSign ocsp.verisign.com

295

TrustWave ocsp.trustwave.com

297

TrustCenter ocsp.tcuniversal-I.trustcenter.de

389

CyberTrust sureseries-ocsp.cybertrust.ne.jp

421

Certum ocsp.certum.pl

568

* Measuring with Monitis points in US-MID, US-EST-US-WST, Canada, Denmark, Netherlands, Germany, Spain, UK, Sweden, China, Austrailia, Signapore, Japan were used.

 

CRL Repository Performance
CA Host Average (ms)
GlobalSign crl.globalsign.com 101
DigiCert crl3.digicert.com 102
Entrust crl.entrust.net 120
Comodo crl.comodoca.com 178
GoDaddy crl.godaddy.com 186
StartCom crl.startssl.com 267
TrustWave crl.securetrust.com 272
Symantec/GeoTrust EVSSL-crl.geotrust.com 298
Symantec/Verisign EVIntl-crl.verisign.com 298
TrustCenter crl.ix.tcclass3.tcuniversal-i.trustcenter.de 371
Certum crl.certum.pl 426
CyberTrust sureseries-crl.cybertrust.ne.jp 454
* Measuring with Monitis points in US-MID, US-EST-US-WST, Canada, Denmark, Netherlands, Germany, Spain, UK, Sweden, China, Austrailia, Signapore, Japan were used.

 

Setting HTTP headers with OpenSSL and the OCSP test client

So I have been doing some OCSP performance bench-marking the last few weeks, one of the things we noticed while doing this is that OpenSSL does not set the HOST header when sending requests.

This is a problem when interacting with a OCSP responder that is on a shared host (a virtual host), without it the web-server doesn’t know which instance to send the request to. You can work around this by using the “-header” command, for example:

openssl ocsp -noverify -no_nonce -respout ocspglobalsignca.resp -reqout ocspglobalsignca.req -issuer globalsigng2.cer -cert globalsign.com.cer -url “http://ocsp2.globalsign.com/gsextendvalg2” -header “HOST'” “ocsp2.globalsign.com”

You need to ensure the HOST header is set consistently with the host contained in the -url switch but it works.

Ryan

Testing OCSP Stapling

So you have configured OCSP stapling and you want know if it’s actually working, it’s easy enough to check using the openssl  s_client command:

openssl s_client -connect login.live.com:443 -tls1  -tlsextdebug  -status

Loading ‘screen’ into random state – done

CONNECTED(0000017C)

TLS server extension “status request” (id=5), len=0

….

OCSP response:

======================================

OCSP Response Data:

OCSP Response Status: successful (0x0)

Cert Status: good

This Update: Jun 12 02:58:39 2012 GMT

Next Update: Jun 19 02:58:39 2012 GMT

In this example you see that the client is requesting the servers OCSP response, you then see the server providing that response successfully and openssl determining the servers certificate is good.

For another example we can query the US Mint’s website for an example of a site that has not yet (and probably won’t for some time since it’s a government site) configured OCSP stapling:

openssl s_client -connect www.usmint.gov:443 -tls1  -tlsextdebug  -status

Loading ‘screen’ into random state – done

CONNECTED(0000017C)

OCSP response: no response sent

….

Hope this helps you deploy OCSP Stapling successfully.

Ryan

OCSP Stapling in IIS

Windows Server 2008 and later support a feature called OCSP stapling. When enabled a server pre-fetches the OCSP response for its own certificate and delivers it to the user’s browser during the TLS handshake. This approach offers a privacy advantage. But, the main benefit is the browser doesn’t have to make a separate connection to the CA’s revocation service before it can display the Web page. This gives better performance and reliability.

For this pre-fetching to work the web-server certificate needs to contain a pointer to the OCSP responder, this is a best practice and a recommendation of the CA/Browser Forums baseline requirements so it’s almost certain your certificate has it.

Unlike Apache this feature is enabled by default, it’s possible your servers are already doing OCSP stapling and you do not even know it.

With that said chances are you have a firewall between your webservers and the internet; it’s also likely that firewall disallows outbound connections from your servers unless explicitly allowed. So you might need to allow your web servers to communicate with the OCSP responder before it will work.

To figure out what host and port you will need to open you will need to look at the certificates you use on your webserver; one way to do that is to browse to your current site and view the details of the certificates you are currently using, for example:

   

The value you want is in the “Authority Information Access” field, you want the ones (there may be multiple) that have the “Access Method” of “On-line Certificate Status Protocol”.

Once these two conditions are met OCSP Stapling will “Just work” there is nothing else you need to do.

Ryan

OCSP Stapling in Apache

Apache 2.3 and later support a feature called OCSP stapling. When enabled a server pre-fetches the OCSP response for its own certificate and delivers it to the user’s browser during the TLS handshake. This approach offers a privacy advantage. But, the main benefit is the browser doesn’t have to make a separate connection to the CA’s revocation service before it can display the Web page. This gives better performance and reliability.

For this pre-fetching to work the web-server certificate needs to contain a pointer to the OCSP responder, this is a best practice and a recommendation of the CA/Browser Forums baseline requirements so it’s almost certain your certificate has it.

Chances are you have a firewall between your webservers and the internet; it’s also likely that firewall disallows outbound connections from your servers unless explicitly allowed. So before you enable OCSP stapling you are going to need to allow your web servers to communicate with the OCSP responder.

To figure out what host and port you will need to open you will need to look at the certificates you use on your webserver; one way to do that is via OpenSSL, for example:

1. Get the certificate using s_client

openssl.exe s_client -connect www.globalsign.com:443


—–BEGIN CERTIFICATE—–
—–END CERTIFICATE—–

You need to copy the PEM header and footer (“—–BEGIN/END CERTIFICATE—–“) and the Base64 between them into a file.

2. Identify the OCSP responders within the server certificate

openssl.exe x509 -in globalsign.com.cer -text


X509v3 extensions:
..
Authority Information Access:
CA Issuers – URI:
http://secure.globalsign.com/cacert/gsextendvalg2.crt
OCSP – URI:
http://ocsp2.globalsign.com/gsextendvalg2

You need to find the “OCSP – URI” section, in the example certificate above the OCSP responder is http://ocsp2.globalsign.com/gsextendvalg2 there may be multiple responders specified, you should allow your servers to initiate outbound traffic to all of them.

Once your servers can request OCSP responses enabling stapling is very straight forward, there are just two directives that need to be added, these directives can be global or specific to a specific to one instance:

SSLUseStapling on
SSLStaplingCache “shmcb:logs/stapling_cache(128000)”

Their purpose is self-evident; SSLUseStapling turns the feature on while SSLStaplingCache specifies where to store the cache and how big it should be.

There are other directives also you can use but you should not need to worry about them.

As long as you are running the most recent stable versions of Apache and OpenSSL enabling this feature is safe. It is only used when the client supports it so there won’t be compatibility issues and if the server for some reason fails to populate its cache with a valid OCSP response the client will typically fall back to doing a live OCSP request on its own.

Ryan

 

Additional Resources

Overclocking Mod_SSL

Attending workshop on “Improving the Availability of Revocation Information”

At the most recent CA/Browser Forum folks from DigiCert and I both made presentations on what’s needed to improve the current state of revocation in X.509.

There were really two different themes in these presentations:

  1. We can better use the technologies we have today.
  2. We can make “tweaks” to the technologies we have today to improve the situation.

It was not really possible to go into any details about these proposals given the time slots allocated were more presentation oriented and since the DigiCert guys had already engaged with Maximiliano Palla of NYU Polytechnic University (the founder of the OpenCA project) they agreed to work with him to arrange this workshop.

The session is April 16th (I leave tomorrow) and I am looking forward to the chance to talk about this topic, my goals for the session are we get to agreements on:

  1. Authoring a whitepaper on OCSP responder best practices.
  2. Authoring a whitepaper on revocation client best practices.
  3. Agreeing on an approach to “opt-in” hard revocation checking.
  4. Agreeing on a path forward to resolve the many outstanding Firefox revocation issues.
  5. Funding Nginx to add support for OCSP stapling this year.

There are lots of other potentially interesting topics I am sure will come up:

  1. Getting Apache’s OCSP stapling enabled by default.
  2. Short-lived certificates, their potential and challenges.
  3. Defining a new transport for OCSP via DNS.
  4. Defining a new query-less OCSP like protocol.
  5. CRLsets and their place in the browser ecosystem.

Should be an interesting day for sure.