[gnutls-dev] [RFC] gnutls-pkcs11

Simon Josefsson simon at josefsson.org
Mon Aug 27 16:54:19 CEST 2007

"Alon Bar-Lev" <alon.barlev at gmail.com> writes:

>> Consider the following scenario: the user has two certificates with one
>> private keys for each.  The certificates are stored in GnuTLS using
>> normal APIs (i.e., gnutls_certificate_set_x509_key_mem with NULL keys).
>> GnuTLS will select the appropriate user cert (one of the two certs) to
>> use against each server, depending on the CA list received from the
>> server.  The certificate (which uniquely identify the private) to use
>> for signing is passed in the 'cert' parameter to the sign_callback
>> function.  The callback need to locate the private key in the PKCS#11
>> backend(s) that match that user certificate, and use that key for
>> signing.
> I thought all the above scenario is done in:
> cert_callback set by gnutls_certificate_client_set_retrieve_function().

That function is only used to retrieve the users' certificates.  It
doesn't handle the private keys.

However, of course, if you only let GnuTLS know about one user
certificate via the cert_callback, GnuTLS will never ask the
sign_callback about any other private key.

> So you do have a chance to do the above logic...

Right, and it works now.  But not all applications use the cert_callback
approach, and they should be able to retrieve the appropriate private
key to use with the chosen user certificate.

> But you say that gnutls have some automatic method for this...
> I was not aware of it... (The term "set" is misleading... Should be "add"...)

The automatic method is used when the application doesn't use
gnutls_certificate_client_set_retrieve_function.  I don't follow the
remark about set vs add, the function set the function callback, it
doesn't add it -- you can't have two function callbacks.

> And now I get why you added the certificate into the sign callback...
> I let it go last time... But here it is back... Seems I cannot escape
> from it :)
> I don't understand how did you expect people to use this... Here are
> some of my thoughts...
> 1. You assume a static list of available certificates and objects is
> available to application, so that you can call
> gnutls_certificate_set_x509_key_mem() at initialization. But this is
> not true with smartcard aware application, as the user may insert his
> smartcard after initializtion.

True, and you can use gnutls_certificate_client_set_retrieve to solve
this.  But not all applications need to use that interface.

> 2. You don't allow passing user data for the
> gnutls_certificate_set_x509_key_mem() function, so the application has
> to enumerate all available certificates during initialization, and
> then again enumerate all available certificates in sign callback in
> order to find a match.

It doesn't have to enumerate them, there are other solutions depending
on the application.

However, if you use the cert_callback approach, this shouldn't be a
problem, right?

> 3. Even if you allow to pass user data, it will solve (2), but there
> is an issue with resource cleaning, is there a callback to take the
> user data during credential clean?
> Of course I can put some user data in the session that have a
> reference between a certificate and its private key data, but this
> looks like a bad idea.

I don't see any reason to re-design the cert_callback API right now, it
seems to be working and doing everything that is needed.

> 4. Do you expect building a new credentials object before each
> session? Maybe if you do, I understand (1) solution... But not the way
> the callback be efficiently implemented.

It depends, some applications will build a new object each time, some
won't.  I think there are appropriate APIs for both variants.

> I may be wrong... But the simpler approach of
> gnutls_certificate_client_set_retrieve_function() is more generic...

Hm, I don't follow what you prefer -- that function is already there.

> A helper function will can be appropriate (maybe you already have it),
> that receives the callback parameters and a list of end certificate
> and return the index of the best certificate to use. This function be
> be called at the cert_callback without any resource/user implications.

There's no such helper function.  We could add it if you send a patch,
but it doesn't seem like a generically useful thing

> But as I see now, it the current implementation of the sign callback
> is not suitable for the API at all... It looks like you will not be
> able to escape implementing one type/structure to hold a public
> component and private reference which is passed throughout the code...
> This structure should have user data, sign callback, cleanup callback.

The API may not be perfect, I admit that, but to design a really clean
API, GnuTLS would need to have data types or functions that work on
generic "user credential" that contains both user certificate (both
OpenPGP and X.509) and private keys (OpenPGP/X509).  That is a
significant amount of work, and there is yet little indication that
people request this feature often.


More information about the Gnutls-devel mailing list