[gnutls-devel] Fwd: support of stapled OCSP responses under TLS1.3

Nikos Mavrogiannopoulos n.mavrogiannopoulos at gmail.com
Wed Nov 29 13:56:12 CET 2017

On Tue, Nov 28, 2017 at 7:53 AM, Thomas Klute
<thomas2.klute at uni-dortmund.de> wrote:
> Am 27.11.2017 um 14:35 schrieb Nikos Mavrogiannopoulos:
>>> 1) If I understand the comment in lib/tls13/certificate.c,
>>> append_status_request() correctly stapling multiple certificates would
>>> actually not work together with
>>> gnutls_certificate_set_retrieve_function2, which mod_gnutls needs to use
>>>  for virtual hosts.
>> The use of gnutls_certificate_set_retrieve_function2 remains
>> unaffected. However, to take advantage of multiple responses, it would
>> have to be modified to utilize
>> gnutls_certificate_set_ocsp_status_request_function3.
> Ah, I might have misunderstood the API doc for
> gnutls_certificate_set_ocsp_status_request_function3 here:
>>  * When the flag %GNUTLS_OCSP_CB_GLOBAL_SET is specified in @flags, this
>>  * function can be used to set a callback that is used even when the
>>  * certificates are provided by the application via a callback. That is,
>>  * when gnutls_certificate_set_retrieve_function() and friends are used.
>>  * In that case the callback will be called with the selected certificate.
> What is that different from setting the callback without
> GNUTLS_OCSP_CB_GLOBAL_SET? I would have expected the const
> gnutls_cert_info_st *cinfo parameter for the callback to refer to the
> certificate GnuTLS needs an OCSP response for either way. If it iterates
> over the chain it should work for certificates set via retrieve function
> just as well.

Without this flag this function will set a callback for the
certificate chain in the credentials function specified by the index
(idx). That is, without that flag it works only if
gnutls_certificate_set_x509_key_file* or mem is used.

>>       assert(session->internals.selected_ocsp_func != NULL);
>>       /* The global ocsp callback function can only be used to return
>>        * a single certificate request */
>>       if (!session->internals.selected_ocsp_func && ctx->cert_index != 0)
>>               return 0;

> This is the comment in append_status_request() I was referring to, but
> it appears I missed the preceding assert(). On the other hand, that
> should make the if condition always false, so I'm not sure what it is for.

The comment and the corresponding code seems incorrect. I'm checking
it; thanks for the catch.

>>> 2) The certificate is passed to the callback as a gnutls_pcert_st. I'd
>>> need to call gnutls_pcert_export_x509 during each run of the callback to
>>> get a gnutls_x509_crt_t and access things like fingerprint (used for the
>>> cache key) or OCSP responder URL. I'm not sure if that might hurt
>>> performance.
>> If you are storing the certificate as a gnutls_pcert_st internally,
>> I'd also store the OCSP response in the same structure. E.g.
>> struct int_store_st {
>>   gnutls_pcert_st *certs[];
>>   gnutls_datum_t ocsp_responses[];
>> }
>> where each response corresponds to each cert. When the callback from
>> gnutls_certificate_set_ocsp_status_request_function3 is set, you'll
>> get a gnutls_cert_info_st which has an index indicating the positioni
>> n the chain the OCSP is asked for. With such a setup no additional
>> parsing will be required. If I misread what you were describing,
>> please let me know.
> I was referring to how I might use the new API, not the current
> implementation. The current mod_gnutls implementation keeps certificate
> chains as both gnutls_pcert_st and gnutls_x509_crt_t arrays, and the
> OCSP responses in a key/value cache.

So is the existing information sufficient to figure the key, or is
there something else we should add in gnutls_cert_info_st?

> Another approach could be to add a certificate retrieve callback type
> that can return OCSP responses along with selected certificates, but
> that's also fairly complex.

That could also be. I think the main reason a separate callback was
used for the multiple OCSP responses is because there was already such
a callback in place. Would that approach be simpler for mod_gnutls?

> I was just considering that *if* you want to add a response caching
> mechanism in GnuTLS itself for applications that do not want to
> implement their own cache, applications that do manage their own cache
> should be able to replace that GnuTLS cache: Basically let GnuTLS get
> responses directly from the application's cache using a retrieve
> function, let the application do the rest. My point is that the
> application should be able to update the OCSP responses in the cache
> periodically, without involving the callback. However, I personally
> doubt that the complexity is worth it.

I kind of agree here.

>>> For OCSP response files, an equivalent to gnutls_ocsp_resp_import2 that
>>> parses a file containing multiple responses into a list would be
>>> helpful. The current mod_gnutls implementation just pushes the file
>>> content into the internal cache, and a list would make it easy to do the
>>> same for multiple certificates. Of course applications could do that on
>>> their own, but it seems like a common use case.
>> Do you mean something like gnutls_x509_crt_list_import2? That is a
>> function which will import the responses from a memory buffer and
>> store them as gnutls_ocsp_resp_t?
> Exactly. I admit I didn't look at the tool diffs too closely, but it
> looked like they got support for that format, so it'd be useful if other
> applications could just reuse that to support multi-response files.

I'll check it.


More information about the Gnutls-devel mailing list