PKCS#11 card status summary

Zeljko Vrba zvrba at
Sun Nov 21 09:42:36 CET 2004

Hash: RIPEMD160

I caught some time this weekend to play with OpenSC + GPG. Now here are
the results:

===== (conclusion first, as this also goes to users list)
In conclusion, the best I could do, both with MUSCLE and OpenSC[1], is
the following scenario:

1. Support ONE RSA/1024 keypair per card.
2. This keypair would be used exclusively for signing.
3. The card and keypair is initialized by some extra utilities unknown
to GPG.
4. The configuration about existing keypair (and other meta-data that
GNUPG stores normally on OpenPGP card) is read/written from/to
configuration file (in the patch is an example of pkcs11.config).

What I don't know how to do is persuade GPG that a signing keypair is on
the card. GPG 'generate' command assumes that the user has an OpenPGP
card and always tries to generate 3 keypairs.

[1] Within the scope of making a patch to support PKCS#11 cards in
GNUPG. If I had the time I could also make patches to MUSCLE and/or
OpenSC but I think it would be unacceptable to most existing users of
those tools. Also I don't have the time to keep pace with development of
those libraries.

===== (technical details regarding OpenSC)
1. OpenSC pkcs15-init is the only way to format the card and create
PKCS#15 file structure on it (PKCS#15 is what OpenSC is all about). The
sequence goes something like this:

pkcs15-init -E -C
pkcs15-init --store-pin --auth-id 0

After formatting, the Cryptoflex key files are missing. I am not able to
generate a key by PKCS#11 interface after this procedure.

2. After that I generate the key with

pkcs15-init -G rsa/1024 --auth-id 0

Unfortunately the key is marked as sign only for PKCS#11, and the
PKCS#11 reports that the key is inconsistent with its usage when I call

I have not found a way to mark the same key decrypt+sign. Browsing
through the source, it should be made automatically if possible.

Why do I even need C_Decrypt? Well, PKCS#11 tokens can return public and
private keys in arbitrary order and they do not have to be labeled in
any way. I need to pair them and present them as a single fingerprint to
GPG. So I iterate over all public keys on the card, encrypt a sample
message and try decryption with each private key. When the decryption
gives back the original content, I've found a keypair.

I can accomplish the same goal with C_Sign.

3. OpenSC thinks that my card (Cryptoflex 8k) doesn't have RSA keygen
capability so it generates the key off-card and imports it. Well, it
thinks plain *WRONG*. Cryptoflex 8k *DOES* have a keygen capability
(some do, some don't. but anyway, why not first try to generate on-card
and if the card reports an error, generate off-card and import. the card
capabilities are *HARD-CODED* into OpenSC). (BTW, I have rather old
cards, OpenSC didn't have my ATR in its database so I already did hack
throught that part of the code).

4. OpenSC Cryptoflex card profile is strange so that I can't have more
than one key pair. Strangely, pkcs15-init leaves about 4k for user data
which is unused, but there is no room for another keypair directory
(long story about filesystem allocation on cards..)

5. My original idea was using OpenSC PKCS#15 API to access the card.
However, Werner rejected the idea (in private communication) on the
grounds that OpenSC is unstable regarding the API (i.e. arbitrary API
changes between versions, breaking ABI without changing the major
library version number etc.).

Based on his arguments (which I hold valid) I decided to make a new
patch using PKCS#11 and disregard the idea of using OpenSC's PKCS#15 API.

- --
The corresponding PGP public key can be found at:
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Thunderbird -


More information about the Gnupg-devel mailing list