[openssl-dev] [openssl.org #3668] [PATCH] Don't use the cert list embedded in the OCSP response to build the trust chain
Alessandro Ghedini via RT
rt at openssl.org
Fri Mar 20 12:20:07 UTC 2015
On mar, gen 20, 2015 at 02:31:14 +0100, Alessandro Ghedini wrote:
> Currently the OCSP_basic_verify() function fails with many apparently valid OCSP
> responses (e.g. all those sent by Cloudflare servers). Other libraries (GnuTLS,
> NSS) have no problem with them.
>
> Essentially, in crypto/ocsp/ocsp_vfy.c in the OCSP_basic_verify() function, the
> X509_STORE_CTX_init() function is called like this:
>
> init_res = X509_STORE_CTX_init(&ctx, st, signer, bs->certs);
>
> where ctx is the X509_STORE_CTX to be initialized, st is the trust store passed
> by the user, signer is the signer of the OCSP response (which is what needs to
> be validated), and bs is the decoded OCSP basic response.
>
> The problem is the last argument. OpenSSL uses the cert list embedded in the
> OCSP response to build the trust chain, but it seems that in some cases this
> list is somewhat broken. Other libraries (e.g. GnuTLS), do the verification
> differently, without including those bs->certs that OpenSSL uses.
>
> I attached the patch and a simple test case. You can compile it with:
>
> $ cc ocsp_test.c -lcrypto -lssl
>
> To test the problem run:
>
> $ ./a.out digitalocean.com 443
> OCSP response verification failed
>
> after the patch:
>
> $ ./a.out digitalocean.com 443
> OK
Months have passed and I haven't received a reply yet (even worse, the recent
obfuscation of the OCSP structures in 6ef869d7d0a9d made it impossible to
workaround the issue as curl has been doing [0]), so I thought I'd add some more
information to hopefully have this issue resolved.
The issue affects servers that have an intermediate certificate (so the peer
chain is A -> B -> C, with C being the peer cert, B the intermediate cert issuer
of C, and A the CA cert issuer of B) when the OCSP response is signed by an
additional certificate issued by B (lets call this X), provided by the peer in
the "certs" field of the OCSP basic reponse (bs->certs in the OpenSSL code).
To put this in drawing:
peer
chain bs->certs
("certs")
A
↓
B----------┐
↓ ↓
C X
In this case OpenSSL tries to verify that X is trusted, by using the
user-provided trust store "st" (OK), and the bs->certs stack (which only
includes X itself) *without* including B (that the user is supposed to provide
with the "certs" parameter of OCSP_basic_verify()) which actually issued X, thus
failing miserably.
This is the case for e.g. all CloudFlare sites AFAICT, and possibly many other
certificate authorities.
Cheers
[0] https://github.com/bagder/curl/blob/2b7ac4e/lib/vtls/openssl.c#L1363-L1385
More information about the openssl-dev
mailing list