[gnutls-dev] RFC: PKCS#11 plans

Simon Josefsson simon at josefsson.org
Mon Apr 23 11:13:35 CEST 2007


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

> On 4/22/07, Simon Josefsson <simon at josefsson.org> wrote:
>> GnuTLS can't talk PKCS#11 to the gnutls-daemon, can it?  I want GnuTLS
>> and gnutls-daemon to be separate processes.  So GnuTLS will have to
>> use some protocol to talk with gnutls-daemon, and the protocol could
>> be something like:
>
> Why reinvent the wheel?
> PKCS#11 is an API... A generic interface to access crypto devices.
> Your daemon can expose such an interface, and route all PKCS#11
> commands into providers loaded.
>
> If you implement:
>
> Application -[API]-> GnuTLS -[PKCS#11]-> Provider
>
> Then you will be able to use a proxy provider without extra development.
>
> Application -[API]-> GnuTLS -[PKCS#11]-> Proxy Provider -[Socket]->
> Daemon -[PKCS#11]-> Provider
>
> The proxy provider will be a different project and will provide the
> same level of security you are interested in to any PKCS#11 enabled
> applications.
> While GnuTLS keep standard interface.

Ah, I now understand what you mean.  And yes, the
gnutls_1_7_8_with_pkcs11 branch will support PKCS#11 directly, thus
allowing for the approach you refer to here.

However, does any proxy providers exist?  If not, then GnuTLS will
link directly to the PKCS#11 providers, either directly or through
dlopen(), which is something that I'd really want to avoid.  (The code
on the branch do that, just as a proof-of-concept.)

>> etc.  That is quite similar to the GnuPG 2.x protocols, I was just
>> using them as an anology for how the protocol would work.
>
> Why not serialize PKCS#11 request and simply forward them to the daemon?
> Why reinvent the wheel and have a different spec?

Serializing PKCS#11 is not simple, and I don't know if anyone has done
this before.  Further, the serialization of PKCS#11 doesn't have to be
exactly mapped to the PKCS#11 API, it only have to support the same
things that PKCS#11 support.

>> >> to talk with a PKCS11 provider
>> >
>> > Well... You have:
>> > http://gnupg-pkcs11.sourceforge.net
>>
>> That seem to use the scdaemon protocol, but that protocol isn't
>> sufficient for what GnuTLS needs -- for example, I can't read
>> certificates from the smartcard via that protocol for OpenPGP cards.
>> GnuTLS needs the certificates.
>
> Yes it does... Your example of OpenPGP cards is incorrect.
> This implementation work with gpgsm, loading certificate objects too.

But not with OpenPGP cards:

http://lists.gnupg.org/pipermail/gnupg-users/2007-April/030898.html

Since I don't have anything other than OpenPGP cards available, that's
what is the main priority for me right now.  I don't even know
how/where to purchase one X.509 smart card for a reasonable price with
sufficient documentation for me to be able to use it.

>> > If you wish to do this properly you should consider how application
>> > will use your API....
>>
>> I proposed APIs that the GnuTLS application would use in my initial
>> post.  Do you think the APIs need to be more advanced?  What more is
>> needed?
>
> Yes... A library API should be generic...
>
> Have a look at my high-level certificate API:
> http://www.opensc-project.org/files/pkcs11-helper/doc/api/group__pkcs11h__certificate.html
>
> These are the atoms required for certificate management.
>
> Also please have a look at the core API:
> http://www.opensc-project.org/files/pkcs11-helper/doc/api/group__pkcs11h__core.html
>
> Required to manage the providers.
>
> I don't think GnuTLS can provide good service with much simpler API.

Well, let's see, I'm close to having PKCS#11 via Scute work in GnuTLS
with just one API.

>> > There is a lot of logic to find the right objects, to cache sessions
>> > so user will not be prompt every time for passphrase, track the same
>> > token if it moves from one slot to another, support serialization,
>> > multiple providers at the same times and much more.
>>
>> Ok.  gnutls-daemon could then support, say:
>>
>> * Any PKCS#11 token via libp11
>>
>> * Simple PKCS#11 tokens directly (it takes < 50 lines of code to sign
>>   something with scute, and I have this code working now).
>>
>> * GNOME Seahorse crypto provider (although possibly this will happen
>>   via PKCS#11).
>>
>> * gpg-agent for OpenPGP keys + OpenPGP signing.
>>
>> * Microsoft CAPI
>>
>> * Other crypto providers...
>>
>> If the protocol to gnutls-daemon is well-specified, anyone can write a
>> replacement for their own neat stuff, although I hope that the
>> 'default' gnutls-daemon will be sufficient for most users.
>
> OK... I got your view.

I have not yet decided though, this discussion is input to that
decision.  And anything that is decided now can be revised after
review.  And if you don't like the decisions, you can always fork or
send patches.. ;-)

Right now, what I'm actually implementing (direct PKCS#11 access in
GnuTLS) is not the same thing as I'm describing.  I have not started
working on a gnutls-daemon approach, since I'm not yet sure if that is
required to solve all problems.  Since it is more work, I'd like to
defer it if possible.

> I understand we going to loose another open source project accessing
> smartcards correctly.
>
> In the end we will have a different daemon for each open source project...

Until someone develops an inter-application protocol that all these
projects can use, yes likely.  PKCS#11 isn't a wire protocol, so that
isn't the answer.

> We have one for OpenSSH, a differnet one for GnuPG, for Gnome... Now
> we have something new! We have a daemon for an API.... A daemon for
> GnuTLS...
> The poor user will have to run about 20 daemons for interactive
> system, all loading the same PKCS#11 provider which could have been
> directly used by applications.

Applications don't want to load PKCS#11 providers.  They don't want to
know what a PKCS#11 provider is.  Thus, GnuTLS should offer to hide
this stuff from applications.  Some applications may want to know the
details, but then they can use other APIs to solve what they want.

> My "mission" is to help open source projects to realize that the above
> scenario is invalid, so they must focus on standardization. PKCS#11 is
> the only independent standard available to access cryptographic
> devices. Even if the standard seems a little complicated it is of our
> users based interest to support it.

But PKCS#11 is not a protocol...

> It is true that loading a library into your process is dangerous, but
> it can be solved using a proxy PKCS#11 provider that will enable
> safe-guarding all PKCS#11 enabled applications, while being
> transparent.

Do such a PKCS#11 proxy exists?

> It is true that without a daemon, multiple instances or applications
> cannot share the same authenticated sessions, but the same PKCS#11
> proxy will be able to provide a solution for this issue as well, while
> being transparent.

Yes, a proxy of some kind is probably needed to solve the sharing
issue.

> So you have a simple option to use libassuan and work with gpg-agent
> not developing any PKCS#11 code, while users may use my
> gnupg-pkcs11-scd implementation to access PKCS#11 tokens (But I think
> many users will tell you that the application->gpg-agent->scdaemon
> implementation is much too complex for them to use).

I think an assumption here has been that GnuTLS should support
PKCS#11, and since gpg-agent cannot solve one problem (I can't read
certificates via it) we have to consider options.

> You have an option to reinvent the whole wheel... Writing your own daemon.

That may be the most flexible and simplest solution.  It is not
completely reinventing the wheel, since I do not know about any other
solution that provides the same features.

> Or you can design an in-process interface and allow to separate GnuTLS
> from the decision of where and how crypto is implemented. Keeping
> GnuTLS at the API domain.

This is what I'm doing now on the gnutls_1_7_8_with_pkcs11 branch.
However, if there are no PKCS#11 proxy providers, I don't think this
will be the ultimate solution.  Then we need to come up with something
to proxy the signing requests.  In that case, using PCKS#11 is no
longer a generic good idea.  It isn't compatible with Microsoft CAPI,
for instance, something I'd want to support in the long run.

/Simon




More information about the Gnutls-devel mailing list