Page MenuHome GnuPG

Implement access to smartcards via a generic pkcs#11 interface
Open, NormalPublic

Description

Certain smartcards may only be used via their own pkcs#11 driver. Although we try to avoid support for these cards it seems to be justified iff such cards are anyway virtual over-the-network cards.

Event Timeline

werner triaged this task as Normal priority.Oct 10 2022, 7:32 AM
werner created this task.
werner created this object in space Restricted Space.
werner created this object with edit policy "Contributor (Project)".
werner shifted this object from the Restricted Space space to the S1 Public space.Feb 1 2023, 9:41 AM
werner moved this task from Backlog to WiP on the gnupg24 board.

I concluded that (at first, for the initial try) it's not good to start this under scdaemon, because of two different abstractions for accessing the device (the way of scdaemon and the way of PKCS#11).
It's good to start with something like tpm2d. The goal would be integration into scdaemon or tpm2d.

That is:

  • tools like gpg-card is out of scope (use other tools for PKCS#11 itself, to administrate/configure those devices)
  • simply provide the functionalities of:
    • listing keys
    • signing with one of keys
    • decryption with one of keys

I try experiment using Python PKCS#11 (https://python-pkcs11.readthedocs.io/en/latest/index.html)

Listing keys is something like:

import pkcs11
import pkcs11.util
import pkcs11.util.ec
import os, sys

from pkcs11 import KeyType, Attribute, ObjectClass, Mechanism, TokenFlag

lib = pkcs11.lib(os.environ['PKCS11_MODULE'])


if len(sys.argv) >= 2:
    pin = sys.argv[1]
else:
    pin = None

def listkey(token):
    session = token.open(user_pin=pin, rw=False)

    priv_obj_list = session.get_objects({Attribute.CLASS: ObjectClass.PRIVATE_KEY,})
    for priv in priv_obj_list:
        print(priv.id)
        print(priv.label)
        print(priv.key_type)

for slot in lib.get_slots():
    token = slot.get_token()
    if (token.flags & TokenFlag.TOKEN_INITIALIZED):
        print(token)
        listkey(token)

That is, for each slot, for each token, find private keys.

For SoftHSM, we need to 'log in' with PIN to retrieve the information of available private keys.
For Scute, authentication with PIN is the thing between device and user (Scute asks PIN input to user directly, when needed), so, PKCS#11 interface doesn't matter.
I learned that TokenFlag.TOKEN_INITIALIZED is needed, because PKCS#11 interface shows not-yet-initialized token (for SoftHSM, we have no such a thing in Scute).

werner renamed this task from Write app-p11.c to Implement access to smartcards via a generic pkcs#11 interface.Mar 6 2023, 8:52 AM
aheinecke added a subscriber: aheinecke.

Please excuse my question but this issue has been WIP for 8 months. I think it was forgotten a bit. Especially since we are not shipping Okular for general signing of PDF documents this issue might help as a stopgap for Smartcards which we do not yet support natively and reduce the pressure a bit to add more PKCS#15 smartcards which can currently be used with Adobe and Mozilla NSS through their proprietary PKCS#11 modules. So I would like to raise the priority for this a bit. But I don't think high is appropriate. That would be for werner to decide.