26

(8 replies, posted in wolfSSL)

Hi John,

Could you give the changes in this pull request a try and see if it gets you what you need? https://github.com/wolfSSL/wolfssl/pull/3617/files

Thanks,

Hayden

27

(8 replies, posted in wolfSSL)

Hi John,

I recently overhauled wolfSSL's CMake, and Tesfa is correct, what you describe hasn't been added, yet. I'll take a look at it today; it shouldn't be very complex.

Thanks,

Hayden

Sure thing! Happy to help. And, just to be clear, I do think we can make this work for TLS 1.3, it would just be outside of OCSP stapling v2 and would be something we'd have to build out. I edited my last reply to reflect this, but I may not have gotten that bit in before you replied.

Regarding the zeros in the isserKeyHash, I do want to look into that and figure out what the root cause is. It could have something to do with self-signing, but I'm not sure, yet. I'm about to head out and won't be back in the office until next week, but I'll get back to you hopefully sometime next week with an explanation for that.

After spending some time looking at your captures and doing similar experiments of my own, here's what I've found.

  • I don't think turning on stapling and WOLFSSL_OCSP_CHECKALL in the client will have the desired effect of having the server get the statuses of the certs in the chain on behalf of the client. I built the client with WOLFSSL_OCSP_CHECKALL turned on, as you did, and ran the server with ./examples/server/server -v 3 -d -c ./certs/ocsp/server1-cert.pem -k ./certs/ocsp/server1-key.pem and client with examples/client/client -v 3 -W 1m -A ./certs/ocsp/root-ca-cert.pem. In Wireshark, I do see 3 OCSP requests, but only one is coming from the server. The other two (for the "non-leaf" certificates) are coming from the client. Hence, I think WOLFSSL_OCSP_CHECKALL is only relevant if you're doing vanilla OCSP, not OCSP stapling. That doesn't answer why the experiment fails, though. I'm pretty sure it's because the OCSP request for the root CA cert (serial number 99) has an issuerKeyHash of all zeros, for some reason. That's why the responder returns a cert status of "unknown" for this cert.

  • As a separate experiment, I set up one machine to run the server and the responders, and a separate machine to run the client. I downgraded to TLS 1.2 and enabled OCSP stapling v2 (./configure --enable-ocspstapling2). From RFC 6961 for OCSP stapling v2: "Also defined is a new method based on the Online Certificate Status Protocol (OCSP) that servers can use to provide status information about not only the server's own certificate but also the status of intermediate certificates in the chain." That seems like the behavior you want. I ran the server with the same command as shown above but with -v 4 changed to -v 3, and the client (on the other machine) with ./client -h <server IP> -A ./certs/ocsp/root-ca-cert.pem -W 3m -v 3. This still fails because the OCSP request for the root CA cert has zeros for the issuerKeyHash, but it does correctly have the server reach out to the responders with 3 OCSP requests, and bundle the responses in a Certificate Status message that it sends back to the client.

To chart a path forward, I think I need to know more about your requirements. Is TLS 1.3 a must? If so, I don't believe that you can get multiple stapled OCSP responses from the server, per what I've shown above. You could use regular, non-stapling OCSP, though, if you need to check all certs in the chain and not just the peer's. If TLS 1.3 isn't required, then downgrading to TLS 1.2 and using -W 3m should do the trick. If you need both TLS 1.3 and the ability to check all certs with OCSP stapling (stapling v2), then I don't think we support that. For reasons unknown to me, stapling v2 is disallowed in TLS 1.3. See RFC 8446: https://tools.ietf.org/html/rfc8446#section-4.4.2.1. I'm asking my colleagues if there's another way outside of downgrading to TLS 1.2 to get what you want; I'll let you know if there is.

EDIT: After talking with some colleagues, we agree that it's possible with TLS 1.3 to get multiple stapled cert statuses (i.e. for the server's whole cert chain) from the server to the client in a single Certificate Status message. However, we don't currently support that with TLS 1.3. Right now, the server will only request its own cert status. If you are interested in us building support for this functionality, let us know.

Thanks for the detailed information and packet captures. I'm out of time to get started on this today, but I'll dive in tomorrow.

Could you let me know what tests specifically you're referring to? If you could also attach the full log of the failing test(s), that would be helpful, too, as well as any changes I need to make to the source code to trigger the failure you describe.

I'm also curious about your use case for this option. Are you looking to check every certificate in the chain up to and including the peer's, using stapling for each?

Thanks for that context. Feel free to try out the latest changes on my GitHub PR to see if it gets you past the issues with NO_WOLFSSL_SERVER. As always, let me know if any questions arise.

After discussing with the team, I’ve realized that my understanding of the NO_WOLFSSL_SERVER/CLIENT defines was incomplete. The ability to enable/disable the client/server options was put in the library awhile back to reduce the memory footprint, but not every feature we’ve introduced since then is specifically designed to work with those options. While wolfSSL has added SOME client/server side considerations to the OCSP stapling design at the behest of customers and under a “feature request” agreement, OCSP stapling in its entirety has not been wholly designed for use without the client or server. The OCSP stapling original design was done with the assumption that users of it would be building the full library, not just client or server and we will continue to expand on that design on a per-customer basis. wolfSSL is capable and of course, changing it so you can build just client or server with OCSP stapling is possible (as I’ve started to do with my changes). Can you tell us a bit about your need for NO_WOLFSSL_SERVER/CLIENT? Are you exceeding memory requirements that you have? I think some context here will help us figure out a path forward.

EDIT: For what it's worth, I'll have changes on my PR up this evening that should fix the issue with building a server with NO_WOLFSSL_CLIENT defined. The above paragraph is relevant for going forward, especially if it turns out that even more changes are required to get OCSP stapling working perfectly with these defines.

I added some more changes to my PR: https://github.com/wolfSSL/wolfssl/pull/3544

I was also getting "wolfSSL_connect(-406): Bad Certificate Status Message Error" until I made the latest changes there. Now, I'll investigate your issue building a server with NO_WOLFSSL_CLIENT defined.

Ok, got it.

In 4.5.0, I believe there's a bug in internal.c and internal.h. In internal.c, line 11118 should be:

#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_CLIENT)

And similarly, line 2331 of internal.h should be:

#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_CLIENT)

The internal.h fix isn't in master yet, which is why I was getting a compilation error, as I mentioned in my last reply.

The code guarded by the line in internal.c is indeed what performs verification of the certificate status request on the client side, so this bug would explain why you're not seeing that verification in 4.5.0.

Could you make those changes and see if things start working? I'll have a PR to fix internal.h in the near future.

Thanks for that information. I'm currently building on a Linux machine using autotools instead of CMake, but I get this compilation error if I try to enable OCSP stapling and define NO_WOLFSSL_SERVER:

src/internal.c: In function ‘ProcessPeerCerts’:
src/internal.c:11202:62: error: ‘CertificateStatusRequest {aka struct <anonymous>}’ has no member named ‘response’
                                     ret = ProcessCSR(ssl, csr->response.buffer,
                                                              ^~
src/internal.c:11203:62: error: ‘CertificateStatusRequest {aka struct <anonymous>}’ has no member named ‘response’
                                                     &idx, csr->response.length);

Do you get a compilation error when you try to define it, or are we talking runtime behavior where you don't see the client verify the stapled response?

Ok, thanks for that information. A few follow-up questions.

  • What version of wolfSSL were you using before? I'm curious to see how the CMake changed between your last version and 4.5.0. I recently did a big update of the CMake on the master branch of our repo, that, among other things, generates options.h.

  • What platform are you building on? OS/compiler?

  • Can you describe how you typically invoke CMake (either via GUI or command line, and what options you're using)? What are you using to build in lieu of CMake currently?

  • Can you send your options.h?

With that information, I can hopefully reproduce what you're seeing on my end, and figure out why OCSP stapling verification goes away when you define NO_WOLFSSL_SERVER.

When you build wolfSSL, it generates a header file wolfssl/options.h. This contains the defines that the library was built with. Are you including that in your client application? That would ensure that everything matches up between your client app and the built wolfSSL library. Based on your description of the latest issues, I think that might help, but let me know if you're already doing that, or if it doesn't fix anything.

Interesting. I'm going to check this out today and get back to you soon.

I have a pull request waiting for merge into the wolfSSL repository that should fix the issue: https://github.com/wolfSSL/wolfssl/pull/3544

If you get a chance, could you download the patch for that PR, apply it to the wolfSSL code, re-build wolfSSL, and try your setup again?

Thanks for bringing this bug to our attention and for your detailed responses!

I just wanted to update you and let you know that I think there's a bug in our stapling code that's the root cause here. I'm working on a fix. I think I should be able to get it fixed by tomorrow, but I'll keep you posted.

Hi stroebeljc,

Thanks for all the information and packet captures. I'm currently working on this, but it may be Monday before I'm able to get back to you.

Hayden

stroebeljc wrote:

I created an OCSP Responder using openssl.  The problem is that I do not see the wolfSSL server application attempting to pull its OCSP Status from the responder.  Since it doesn't do this, it never responds to the stapling request from the client.  Am I configuring the wolfSSL server application incorrectly?  Note, as mentioned previously, I am not using the -o or -O options with the server because they seem to cause it to want to verify the client, when it connects, instead of pulling its own OCSP Response and holding it for a client stapling request.

When I run scripts/ocsp-stapling.test and capture the traffic with Wireshark, I see our wolfSSL server reach out to the openSSL OCSP responder and get its cert status, which it then returns to the wolfSSL client.

The issue could definitely be an incorrectly configured wolfSSL server, and yes, you don't need to use -o/-O. Like you said, that will make the server request the cert status of the client.

As a next step, could you send me the commands you're using to set up your client, server, and OCSP responder? Then I can compare with scripts/ocsp-stapling.test and see where things might be going wrong. Feel free to send a PCAP, too, if readily available.

Since I am using TLS1.3 I can't use OCSP Stapling V2, correct?  I believe I need to use the -W 1 option for the client.

That's correct. If you're using TLS 1.3 you'll need to use OCSP Stapling V1.

I did get the client to work with an openSSL server that was configured to support the stapling request, so I believe my issue is with the server side of wolfSSL.

The problem is that the example server.c only seems to want to do peer status checks and does not perform a self status check that can be used to formulate an OCSP Response to a client OCSP Status Request.  Am I correct?  Do I need to implement this myself?

You'll need an OCSP responder server to act in concert with the wolfSSL server. We have an example of this, if you take a look at scripts/ocsp-stapling.test in the wolfSSL repository. This script sets up an OpenSSL server as an OCSP responder, which a wolfSSL server then contacts to get a certificate status that it then staples and passes along to a wolfSSL client.

Hi,

Thanks for reaching out. I'm Hayden, a software engineer at wolfSSL.

If I configure wolfSSL 4.5.0 with --enable-ocspstapling2 and build, I'm able to use our example client to make a certificate status request using OCSP stapling:

examples/client/client -h example.com -p 443 -W 2 -A <path to cert>

I verified in Wireshark that no HTTP request goes out to the OCSP responder. If you want to try this specific example out yourself, using example.com, you can download the necessary root certificate here: https://cacerts.digicert.com/DigiCertGl … CA.crt.pem

Under the hood, in our example client, passing -W 2 turns on OCSP stapling V2. This results in function calls to wolfSSL_UseOCSPStaplingV2 and wolfSSL_CTX_EnableOCSP, which you can find documentation for here: https://www.wolfssl.com/doxygen/ssl_8h.html.

For the server side, check out our example server, examples/server/server.c. There, the -O option allows the user to specify an OCSP responder URL for the server to use. This results in calls to wolfSSL_CTX_SetOCSP_OverrideURL and wolfSSL_CTX_EnableOCSP. If you configured the library with --enable-ocspstapling2, wolfSSL_CTX_EnableOCSPStapling will also get called. You can find documentation for these additional functions at the same link above.

Let me know if that helps, and if you need anything else!

Best,

Hayden