[gnutls-dev] [RFC] gnutls-pkcs11

Alon Bar-Lev alon.barlev at gmail.com
Sat Aug 18 19:42:11 CEST 2007

Hello Simon,

On 8/18/07, Simon Josefsson <simon at josefsson.org> wrote:
> I think I have identified one problem.  How do you handle multiple
> certificates/keys?  In the callback, you don't appear to inspect the
> cert variable, and thus your code cannot know which certificate GnuTLS
> want to use for signing.
> That is, if I'm reading the code correctly.  I just looked briefly.

Maybe I don't understand your API correctly...

> 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().

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

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"...)

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.

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.

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.

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.

I may be wrong... But the simpler approach of
gnutls_certificate_client_set_retrieve_function() is more generic... 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.

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.

Does it make any sense?

More information about the Gnutls-devel mailing list