OCSP Stapling - tls.Certificate OCSPStaple

1308 views
Skip to first unread message

Paul van Brouwershaven

unread,
Jun 4, 2013, 8:56:17 AM6/4/13
to golan...@googlegroups.com
Go looks to have support for OCSP Stapling on the server and client side.

Currently the OCSP status is not included when you run a Go TLS server but I can't find a way to enable OCSP Stapling?

I could set the OCSPStaple in the Certificate struct, but how to get the OCSP response in Go and why is this not done by default?


// OCSPStaple contains an optional OCSP response which will be served
// to clients that request it.
OCSPStaple []byte

agl

unread,
Jun 4, 2013, 11:05:56 AM6/4/13
to golan...@googlegroups.com
On Tuesday, June 4, 2013 8:56:17 AM UTC-4, Paul van Brouwershaven wrote:
I could set the OCSPStaple in the Certificate struct, but how to get the OCSP response in Go and why is this not done by default?

Go doesn't check for certificate revocation and therefore doesn't request OCSP stapling. Requesting an OCSP staple would not be an unreasonable request for the client, I've just never needed to do it and nobody has asked before. Do you have need of it?


Cheers

AGL 

Paul van Brouwershaven

unread,
Jun 4, 2013, 12:52:05 PM6/4/13
to golan...@googlegroups.com, Adam Langley
I would like to have support for OCSP stapling to give secure access to an application behind a restricted firewall. Another reason for OCSP lookups is to verify the validity of client certificates that are used for authentication via tls.Config and "ClientAuth: tls.RequireAndVerifyClientCert".

Thanks,

Paul

Adam Langley

unread,
Jun 4, 2013, 12:56:57 PM6/4/13
to Paul van Brouwershaven, golang-nuts
On Tue, Jun 4, 2013 at 12:52 PM, Paul van Brouwershaven
<pa...@vanbrouwershaven.com> wrote:
> I would like to have support for OCSP stapling to give secure access to an
> application behind a restricted firewall. Another reason for OCSP lookups is
> to verify the validity of client certificates that are used for
> authentication via tls.Config and "ClientAuth:
> tls.RequireAndVerifyClientCert".

So aren't you actually requesting certificate revocation checking
support? That gets complex because it involves making HTTP requests,
which would have crypto/x509 depend on net/http and we can't have
cyclic dependencies. It's also very complex and generally useless in
the non-stapling case because it cannot be made hard-fail without
sacrificing availability.


Cheers

AGL

Paul van Brouwershaven

unread,
Jun 4, 2013, 1:11:22 PM6/4/13
to Adam Langley, golang-nuts

I think any OCSP lookup or other revocation check would need a HTTP request at some point.

Maybe the HTTP request can be done separately. As long the OCSP server can be extracted from the certificate and the OCSP response can be parsed.

This wouldn't be perfect but a working situation.

Paul van Brouwershaven

unread,
Jun 6, 2013, 3:58:15 AM6/6/13
to golan...@googlegroups.com, Adam Langley
Hi Adam,

The attached file, ocsp_request.go contains a function CreateRequest that will return a DER encoded OCSP request for the supplied certificate chain. This file is created as part of your existing OCSP response parser at https://code.google.com/p/go/source/browse/?repo=crypto#hg%2Focsp

I have also created a test client located in ocspLookup.go that makes a few requests to several public CAs and parses the response though your existing ParseResponse function.

While code works for most CA's I'm running into a problem with a few where the keyIdentifier is not composed of the 160-bit SHA-1 hash of the value of the BIT STRING subjectPublicKey (excluding the tag, length, and number of unused bits).

I'm currently using the keyIdentifier value of the issuer certificate for the issuerKeyHash (which is the same in most cases) as I can't figure out how to generate the issuerKeyHash myself with the public key data currently available in Go.

I tried to create the issuerKeyHash from "cert.PublicKey.(*rsa.PublicKey).N)" but that din't give me the expected result unfortunately.

Any idea how we could create a issuerKeyHash?

Thanks,

Paul

ocsp_request.go
ocspLookup.go

agl

unread,
Jun 6, 2013, 11:08:27 AM6/6/13
to golan...@googlegroups.com, Adam Langley
On Thursday, June 6, 2013 3:58:15 AM UTC-4, Paul van Brouwershaven wrote:
The attached file, ocsp_request.go contains a function CreateRequest that will return a DER encoded OCSP request for the supplied certificate chain. This file is created as part of your existing OCSP response parser at https://code.google.com/p/go/source/browse/?repo=crypto#hg%2Focsp

Passing a []*x509.Certificate threw me for a second. An OCSP request depends only on a cert and its issuer, so I'd expect (cert, issuer *x509.Certificate) - but that's unimportant.
 
While code works for most CA's I'm running into a problem with a few where the keyIdentifier is not composed of the 160-bit SHA-1 hash of the value of the BIT STRING subjectPublicKey (excluding the tag, length, and number of unused bits).

In getIssuerKeyHash, you are hashing cert.RawTBSCertificate, and that's got to be wrong.

I think what you want is this:

func getIssuerKeyHash(cert *x509.Certificate) []byte {
»·······var publicKeyInfo struct {
»·······»·······Algorithm pkix.AlgorithmIdentifier
»·······»·······PublicKey asn1.BitString
»·······}
»·······asn1.Unmarshal(cert.RawSubjectPublicKeyInfo, &publicKeyInfo)
»·······h := sha1.New()
»·······h.Write(publicKeyInfo.PublicKey.RightAlign())
»·······return h.Sum(nil)
}


Cheers

AGL

Paul van Brouwershaven

unread,
Jul 4, 2013, 4:21:06 AM7/4/13
to golan...@googlegroups.com, Adam Langley
Hi Admin,

I see that you have committed a CreateRequest function in go.crypto/ocsp. I was just writing my test function for the patch I created when I noticed that you already finished this, thanks as this saves me a bit of work :-).

In the commit below you fixed the cert-less responses which was an issues with the previous version but I think it would be better to also allow an issuer certificate to be passed in the ParseResponse function. When no certificate is available in the OCSP response the response should be validated with the issuer certificate.


-- 
Regards,

Paul van Brouwershaven

Adam Langley

unread,
Jul 11, 2013, 5:05:57 PM7/11/13
to Paul van Brouwershaven, golang-nuts
On Thu, Jul 4, 2013 at 4:21 AM, Paul van Brouwershaven
<pa...@vanbrouwershaven.com> wrote:
> I see that you have committed a CreateRequest function in go.crypto/ocsp. I
> was just writing my test function for the patch I created when I noticed
> that you already finished this, thanks as this saves me a bit of work :-).
>
> In the commit below you fixed the cert-less responses which was an issues
> with the previous version but I think it would be better to also allow an
> issuer certificate to be passed in the ParseResponse function. When no
> certificate is available in the OCSP response the response should be
> validated with the issuer certificate.
>
> https://code.google.com/p/go/source/detail?spec=svn.crypto.81eec9b5ce2de5ed8e958e097fc083a01e8da8a4&repo=crypto&r=32525e9c4e9fc29598fa3df3e48c9c6a2248c99d

Sorry, I think you're probably right that it's a better function.

Hopefully I'll remember to make the change tomorrow!


Cheers

AGL

Adam Langley

unread,
Jul 12, 2013, 12:03:28 PM7/12/13
to Paul van Brouwershaven, golang-nuts
Can you let me know whether this looks reasonable to you?:
https://codereview.appspot.com/11220043


Cheers

AGL

Paul van Brouwershaven

unread,
Jul 29, 2013, 11:09:43 AM7/29/13
to Adam Langley, golang-nuts
Thanks, these changes are quite simple and I have tested the OCSP lookup on every certificate in the chain for all major CA public facing websites without running into any issues.

agl

unread,
Jul 29, 2013, 6:17:52 PM7/29/13
to golan...@googlegroups.com, Adam Langley
On Monday, July 29, 2013 11:09:43 AM UTC-4, Paul van Brouwershaven wrote:
Thanks, these changes are quite simple and I have tested the OCSP lookup on every certificate in the chain for all major CA public facing websites without running into any issues.

Thanks. Have landed.


Cheers

AGL 
Reply all
Reply to author
Forward
0 new messages