26 (edited by hayden 2020-12-15 15:24:00)

Re: Example of a client that doesn't attempt to contact OCSP Responder

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.

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

Since we have flash memory limitations, we would like to fit the code into as small a space as possible, while still maintaining adequate timing performance.  I am just trying to turn off things that we know we don't need.  NO_WOLFSSL_SERVER is one of them.  However, we haven't determined that the size is too large.  I would just like to be able to quantify how much turning off the server buys us.

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

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.

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

@hayden,
One thing that seems to be missing in the wolfSSL tests is verification of the WOLFSSL_OCSP_CHECKALL option for OCSP stapling.  How will I be able to verify that this is working?  If I use this option in the tests, I get:
verify error:num=19:self signed certificate in certificate chain

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

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?

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

hayden wrote:

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?

First, I am using certificates in certs/ocsp.  I am creating 4 OCSP Responders, one for the root CA cert and one each for the 3 intermediate CA certs.  Then I am launching the server app (unmodified) and the client app (initially unmodified).  I first test with the -o option on the client and get an error -367, OCSP Responder lookup fail.  In Wireshark (trace attached) I see 3 OCSP Requests, one for the root CA cert, one for the intermediate CA cert, and one for the server cert.  Here are the commands for this test, each in its own command window:

C:\...\wolfSSL\certs\ocsp>openssl ocsp -port 22220 -index index-ca-and-intermediate-cas.txt -rsigner ocsp-responder-cert.pem -rkey ocsp-responder-key.pem -CA root-ca-cert.pem -nmin 11
C:\...\wolfSSL\certs\ocsp>openssl ocsp -port 22221 -index index-intermediate1-ca-issued-certs.txt -rsigner ocsp-responder-cert.pem -rkey ocsp-responder-key.pem -CA intermediate1-ca-cert.pem -nmin 5
C:\...\wolfSSL\certs\ocsp>openssl ocsp -port 22222 -index index-intermediate2-ca-issued-certs.txt -rsigner ocsp-responder-cert.pem -rkey ocsp-responder-key.pem -CA intermediate2-ca-cert.pem -nmin 6
C:\...\wolfSSL\certs\ocsp>openssl ocsp -port 22223 -index index-intermediate3-ca-issued-certs.txt -rsigner ocsp-responder-cert.pem -rkey ocsp-responder-key.pem -CA intermediate3-ca-cert.pem -nmin 4
C:\...\wolfSSL>Debug\server.exe -v 4 -c certs\ocsp\server1-cert.pem -k certs\ocsp\server1-key.pem
C:\...\wolfSSL>Debug\client.exe -v 4 -A certs\ocsp\root-ca-cert.pem -o

I am thinking the error is due to the root cert being self-signed.

OCSP Stapling works differently.  When I change the client code around line 3037 to this:

        //wolfSSL_CTX_EnableOCSP(ctx, 0);
        wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL);
        wolfSSL_CTX_SetOCSP_Cb(ctx, NULL, NULL, NULL);

and run the same as above but change the client to this:

C:\...\wolfSSL>Debug\client.exe -v 4 -A certs\ocsp\root-ca-cert.pem -W 1

I get error -407, Invalid OCSP Status Error.  I also see only one OCSP request in the WireShark trace (attached to next post).

Finally, changing the code at line 3037 to this:

        wolfSSL_CTX_EnableOCSP(ctx, 0);
        //wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL);
        wolfSSL_CTX_SetOCSP_Cb(ctx, NULL, NULL, NULL);

and rerunning the last commands results in success.  (Wireshark trace attached to last post.)

Post's attachments

http lookup.pcapng 15.94 kb, 1 downloads since 2020-12-28 

You don't have the permssions to download the attachments of this post.

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

Wireshark trace with WOLFSSL_OCSP_CHECKALL and forcing OCSP Stapling attached.

Post's attachments

checkall no http lookup.pcapng 11.33 kb, 1 downloads since 2020-12-28 

You don't have the permssions to download the attachments of this post.

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

Wireshark trace without WOLFSSL_OCSP_CHECKALL and forcing OCSP Stapling attached.

Post's attachments

checkone no http lookup.pcapng 14.19 kb, 1 downloads since 2020-12-28 

You don't have the permssions to download the attachments of this post.

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

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.

Share

35 (edited by hayden 2020-12-30 10:48:57)

Re: Example of a client that doesn't attempt to contact OCSP Responder

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.

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

Hayden,
Thanks for the thorough analysis.  I think you provided the information I am looking for.  If I want to use TLS 1.3, I can't traverse the chain.  I can only verify the server cert.  With TLS 1.2, I am able to traverse the chain.  I agree that this behavior seems to be driven by the standards.

Regarding the all zero issuer key hash, is there a way to address that, or is this baked into x509 self-signing?

Thanks for all of your help!

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

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.

Share

38 (edited by hayden 2021-01-04 09:46:50)

Re: Example of a client that doesn't attempt to contact OCSP Responder

I have confirmed that the zeros in the issuerKeyHash do ultimately stem from the fact that the certificate is self-signed, but I don't think that should matter. I made a change to the code to get around this, and when I run the relevant experiment again, I get a valid cert status back from the OCSP responder because the issuerKeyHash is coherent this time. I'll need to talk with the team and run some more tests to determine if this change can be merged, though. I'll let you know. If you're interested in trying the change out in the meantime, here it is: https://github.com/wolfSSL/wolfssl/pull/3618

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

This fixes the unknown status of self-signed certs.

Thanks!

Share

40 (edited by hayden 2021-01-04 15:58:44)

Re: Example of a client that doesn't attempt to contact OCSP Responder

Excellent! No problem.

Share

41 (edited by stroebeljc 2021-01-07 14:06:41)

Re: Example of a client that doesn't attempt to contact OCSP Responder

hayden wrote:

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.

My use case does require checking the status of all certificates in a chain, so I would very much like this functionality as part of TLS 1.3.  Can you make this happen?

Also, my use case is such that my server may not always have an internet connection.  This means that there may not be an OCSP Response when an OCSP Request is made.  I would, when there is a connection, like to force sending an OCSP Request so that I can get and store an updated OCSP Response well before the currently stored OCSP Status expires.  I do not see how to do that in the current implementation.  How is this possible?

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

stroebeljc wrote:

My use case does require checking the status of all certificates in a chain, so I would very much like this functionality as part of TLS 1.3.  Can you make this happen?

Also, my use case is such that my server may not always have an internet connection.  This means that there may not be an OCSP Response when an OCSP Request is made.  I would, when there is a connection, like to force sending an OCSP Request so that I can get and store an updated OCSP Response well before the currently stored OCSP Status expires.  I do not see how to do that in the current implementation.  How is this possible?

I'll talk with the team and get back to you, but yes, I'm quite sure we can add it, from a technical perspective.

As for the second part, if I understand correctly, you essentially want a way to extract the OCSP response from wolfSSL so that you can cache it in your application and check that in the event the internet connection isn't available, right?

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

hayden wrote:

As for the second part, if I understand correctly, you essentially want a way to extract the OCSP response from wolfSSL so that you can cache it in your application and check that in the event the internet connection isn't available, right?

Yes, but I also want the server to force retrieval of an updated response without having a client first request it.  Therefore, when the internet becomes available, the server can generate its own OCSP Request and store the response.

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

stroebeljc wrote:

Yes, but I also want the server to force retrieval of an updated response without having a client first request it.  Therefore, when the internet becomes available, the server can generate its own OCSP Request and store the response.

Ok, that makes sense. You'd be monitoring the Internet connection in your application, and when it comes back, you want a way to tell the wolfSSL server to reach out to the OCSP responder. I'll have to look around our APIs and see if there's a way to do that. Stay tuned.

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

I think the function wolfSSL_CertManagerCheckOCSP *almost* does what you want. The documentation appears to be a bit outdated, though. This results in calls to CheckCertOCSP --> CheckCertOCSP_ex --> CheckOcspRequest, which ultimately sends out the OCSP request to the OCSP responder. However, in CheckOcspRequest, if the status is already cached, no request will be made:

ret = GetOcspStatus(ocsp, ocspRequest, entry, &status, responseBuffer);
if (ret != OCSP_INVALID_STATUS)
    return ret;
...
...
/* code that reaches out to OCSP responder */

So I think we'd need to change this function to accept a new parameter, force, which reaches out to the OCSP responder regardless of whether or not a cached response status for the cert exists.

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

hayden wrote:

So I think we'd need to change this function to accept a new parameter, force, which reaches out to the OCSP responder regardless of whether or not a cached response status for the cert exists.

It seems like that would be a nice feature addition.

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

hayden wrote:

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.

Any update on the status of this addition?

Share

Re: Example of a client that doesn't attempt to contact OCSP Responder

Hey John,

Thanks for checking in. I haven't started work to add the new features we've recently discussed here. To get the ball rolling on that, I have asked our sales rep for your region to reach out about some consulting work. Feel free to reach out to him, too, at paul.dennison@wolfssl.com.

Have a great Sunday!

Thanks,

Hayden

Share