[gnutls-dev] RFC: PKCS#11 plans

Simon Josefsson simon at josefsson.org
Sun Apr 22 14:27:16 CEST 2007

Hi!  I've started experimenting with PKCS#11 support in GnuTLS, and it
seems possible to do it.  This e-mail provides a starting point for
discussions.  I'm not at all sure how to implement this, so your
thoughts and ideas are very much appreciated!

I've created a new branch gnutls_1_7_8_with_pkcs11 that will contain
these experiments.  If they are successful, they will be integrated
into the 1.7.x branch and become part of the next stable release
(which I hope to get out before or during the summer).

There are several ways to support PKCS#11 in GnuTLS, I can think of at
least three:

1) Build-time linking to a particular PKCS#11 implementation.

   Applications would likely have to call a new API, and my initial
   guess at what it would look would be:

   int gnutls_certificate_set_pkcs11 (gnutls_certificate_credentials_t res,
                                      const char *key_id);

   where KEY_ID would be an optional string denoting the Key ID of the
   key to use as the private key.  If KEY_ID is NULL, it would use any
   private key it finds.

   This is easy to use and program for, but offers limited


   One way to make this more flexible would be to place the API in a
   special library: libgnutls_pkcs11_foo where foo is the PKCS#11
   library it uses.  In other words, there could be:

   libgnutls_pkcs11_scute.so     uses the GnuPG 2.x PKCS#11 module
   libgnutls_pkcs11_seahorse.so  uses the GNOME SeaHorse PKCS#11 plugin
   libgnutls_pkcs11_nss.so       uses the Mozilla NSS PKCS#11 module

   Each of those libraries would be directly linked to the particular
   PKCS#11 library.  Applications, if they need PKCS#11 functionality,
   would have to link to one of these libraries.  They are mutually
   exclusive, so you can't use both seahorse and scute, which is a
   serious disadvantage.  Still, sometimes it may be sufficient.

2) Runtime linking to a application-chosen PKCS#11 implementation.

   This would likely use dlopen(), and applications would need to
   specify the path to the PKCS#11 plugin.  You'll need a new API for
   this as well, I'm thinking something like this:

   int gnutls_certificate_set_pkcs11 (gnutls_certificate_credentials_t res,
                                      const char *library,
                                      const char *key_id);

   This would dlopen() LIBRARY and search for KEY_ID, which may be
   NULL to indicate that any private key is fine.

   Applications can support more than one PKCS#11 plugin with this
   approach.  For example, it can do two calls:

     gnutls_certificate_set_pkcs11 (res, "/usr/lib/libscute.so", NULL);
     gnutls_certificate_set_pkcs11 (res, "/usr/lib/libnss.so", NULL);

   This seems like a nice approach, although it seems sub-optimal that
   applications have to provide library paths.  Applications shouldn't
   have to care about such details.


   If LIBRARY is NULL, GnuTLS could use a static list of known
   PKCS#11-providers, or it could read the list from a
   /etc/gnutls-pkcs11.conf, ~/.gnutls-pkcs11.conf, GNUTLS_PKCS11
   environment variable, or similar.

3) IPC to a gnutls-daemon that is responsible for the PKCS#11 management.

   Here there is no linkage to any PKCS#11 plugin at all, which I
   consider a major advantage -- I would not want buffer-overflow
   attacks in PKCS#11 plugins to cause problems in the GnuTLS library.

   The gnutls-daemon is responsible for loading and calling the
   PKCS#11 plugins correctly.  The APIs can look the same as previous,
   in case the gnutls-daemon can dlopen() libraries.  In other words,
   the following:

   int gnutls_certificate_set_pkcs11 (gnutls_certificate_credentials_t res,
                                      const char *library,
                                      const char *key_id);

   would indicate that the certificate structure should talk to the
   gnutls-daemon, and ask it to search for KEY_ID (if non-null) in
   LIBRARY (if given), or just be happy with any private key at all.

What do you think?


More information about the Gnutls-devel mailing list