[gnutls-dev] RFC: PKCS#11 plans

Alon Bar-Lev alon.barlev at gmail.com
Sun Apr 22 14:40:52 CEST 2007


Hello,

I think this is a great idea to finally support PKCS#11!

But:
1. Never link against a specific provider.
2. If you wish to use a daemon, the daemon interface can be PKCS#11...
so actually this is a separate project... To write a PKCS#11 provider
that interacts using sockets with a daemon which loads several
providers into its namespace. I have this in my TODO list... It can
also provide single sign on for the user.
3. You should handle dynamic events such as token remove, token
insert, PIN request.
4. What happens if signature/decrypt is requested and the token is unavailable?
5. What is the meaning of the ID? Where the user may receive it? I
guess I mean you need to support enumeration.

Handling smartcard require significant change in concept... I've
implemented a library that should ease the interaction, and address
the above issues.
http://www.opensc-project.org/pkcs11-helper

I believe that ignoring these will not enable GnuTLS application to
suport hardware based crypto correctly.

To begin with, I think GnuTLS should have generic crypto
engine/provider interface. And using this interface a PKCS#11
engine/provider should be implemented.

Best Regards,
Alon Bar-Lev

On 4/22/07, Simon Josefsson <simon at josefsson.org> wrote:
> 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
>    flexibility.
>
>    Refinement
>    ----------
>
>    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.
>
>    Refinement
>    ----------
>
>    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?
>
> /Simon
>



More information about the Gnutls-dev mailing list