[gnutls-dev] GnuTLS 1.7.8.p11.0

Simon Josefsson simon at josefsson.org
Fri May 4 16:21:39 CEST 2007

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

> On 5/4/07, Simon Josefsson <simon at josefsson.org> wrote:
>> "Alon Bar-Lev" <alon.barlev at gmail.com> writes:
>> > Hello,
>> >
>> > I was about to get this implementation and suggest an alternative,
>> > only to discover that you are not doing any private key operations.
>> Hi!  Right.  I wanted to get things out as soon as possible, and right
>> now getting the CA trust stuff is all that I can show to be working.
> As I said before... Most tokens do not hold certificate chain within
> them, it is just a waste of memory when you have 16K, 32K or 64K.

GnuTLS doesn't need the entire chain, just the CA.

Also, if the smartcard doesn't contain CA certificates, GnuTLS will not
find them and not use them: thus no problem?

> Also I already warned you that this is highly insecure... Since anyone
> can store whatever certificates as public objects, thus modifying the
> trust.

I don't understand this.  It seems to me that anyone who can make the
PKCS#11 provider give GnuTLS an insecure CA cert can also provide GnuTLS
directly with a insecure CA cert.

Could you describe how the attack would work?

>> It will be something like that.  It may start out as somewhat simpler,
>> to better fit with how the GnuTLS API works today: right now
>> applications can be invoked with a callback to retrieve the appropriate
>> cert+key.  They need some function to get the user certificates and key
>> handles from the PKCS#11 layer.  I'm thinking this interface will be:
>>   int gnutls_pkcs11_get_user_certificates (gnutls_x509_crt_t ** cert_list,
>>                                                 unsigned int *ncerts);
> But you will be able to to implement the above using the API I suggested.
> As I see it you can have the PKCS#11 stuff maintained separately, as
> an optional components, something like gnutls-pkcs11 that will use the
> engine API in order to add the above function.

Sure -- the PKCS#11 support that GnuTLS will provide will always be
optional.  Applications that doesn't like the GnuTLS PKCS#11
implementation can implement their own callback function to retrieve
user/CA certs and handle signing requests.

> You also don't handle much of the issues related of token management...
> 1. Tokens are ****SLOW***** enumerating the certificates takes
> ****LONG**** time.
> 2. Tokens are dynamic, you can remove them and insert them, so
> enumerating all available tokens every time is not wise.
> 3. You may have more than one token available at the same time, you
> may need to handle this state.
> 4. As I understand from your API documentation, gnutls_x509_crt_t  has
> nothing to do with the private key, which is the one that really
> important when you handle hardware tokens.

I don't know how to solve this yet.  If you want to work on it, that
could help, although right now I just want to get client-PKI via the
OpenPGP smart card to work, and that's my main priority.

>> When an application, in the certificate callback, indicate that the
>> private key is 'NULL', they will have to provider another callback to
>> perform the sign operation, otherwise the user certificate will be
>> ignored.  That function should likely receive the user certificate or
>> similar.  GnuTLS should have an API available to perform the sign
>> operation using PKCS#11, but it could also let the application perform
>> the sign operation in any way it chose.  This way, the interface will
>> not be specific to PKCS#11, but it will be easy to make PKCS#11 work.
> I don't understand the above... How do you set the callback in the
> certificate object?
> How do you set user defined data for the callback to be used?
> I did not see this in the GnuTLS documentation.

See gnutls_certificate_client_set_retrieve_function(), and for example
the 'cert_callback' function in src/cli.c (the gnutls-cli tool).  That
callback is invoked during the TLS handshake to get the user certificate
and private key to use.  My idea is to allow the function to return a
private key 'NULL' which indicate that GnuTLS will have to callback into
the application to perform the private key operation.  These APIs will
not be PKCS#11 specific.

> Anyway... I think that your implementation should not be differnet
> than any other one.
> If you have such a generic mechanism, use it, don't implement two
> different methods.

Yup, the idea is to have a generic mechanism, and to provide the
necessary PKCS#11 glue to make it easy to use the generic mechanism with
PKCS#11 providers.  Application doesn't need to use the glue code

>> Of course!  I think the best is for me to produce an API that works for
>> me and fits with how GnuTLS works.  I believe it will be quite close to
>> what you need, even if not perfectly the same.  The API will not be
>> fixed until it is merged into the normal experimental branch.  There
>> will be several iterations of release on the PKCS#11 branch until that
>> happens, and your input is valuable here.  I think it would be useful to
>> demonstrate interoperability with at least some other PKCS#11 provider
>> than Scute until the API is ready.
> All I suggest is an API that fits GnuTLS!
> But I suggest that the low-level PKCS#11 will reuse current effort and
> knowledge.
> Also I think it would be best if the PKCS#11 support will be provided
> as a separate library, that uses GnuTLS API.

Yes, I think it will be possible to use external libraries to implement
the PKCS#11 (or CAPI, or ...) support.

> The functions:
> gnutls_pkcs11_set_config() /* Set providers and parameters */
> gnutls_pkcs11_enum_certificates() /* Enumerate available certificates */
> gnutls_pkcs11_serialize_certificate() /* Serialize specific
> certificate so we don't need enum again */
> gnutls_pkcs11_deserialize_certificate() /* Deserialize certificate,
> good for configuration files */
> Can be implemented using PKCS#11 code and GnuTLS with engine API as a
> separate library.
> Also, if you would like to be more generic you should provide an
> engines much more powerful and allow gnutls to serialize/deserialize
> any certificate includeing the engine specific information, and allow
> callbacks for an engine to enumerate certificates.

I want to keep the PKCS#11 APIs minimal.  It should provide basic
functionality for applications that want to build on it.  Applications
that wants to get fancy can do their own PKCS#11 integration.


More information about the Gnutls-devel mailing list