Yesterday I wrote about smartcard software for Linux providing a complex UML diagram of various components involved in accessing the cards themselves. While I was quite satisfied with the results, and I feel flattered by Alon’s appreciation of it, I’d like to write a few notes about it, since it turns out it was far from being complete.
First of all, I didn’t make it clear that not all cards and tokens allows for the same stack to be used: for instance even though the original scdaemon
component of GnuPG allows using both PC/SC and CT-API to interface to the readers, it only works with cards that expose the OpenPGP application (on the card itself); this was a by-design omission, mostly because otherwise the diagram would have felt pretty much unreadable.
One particularly nasty mistake I made related to the presence of OpenSSL in that diagram; I knew that older OpenSSL versions (0.9.x) didn’t have support for PKCS#11 at all, but somehow I assumed that they added support for that on OpenSSL 1.0; turns out I was wrong, and even with the latest version you’re required to use an external engine – a plugin – that makes the PKCS#11 API accessible to OpenSSL itself, and thus the software relying on it. This plugin is as usual developed by the OpenSC project.
Interestingly enough, NSS (used by Firefox, Chromium and Evolution among others) supports PKCS#11 natively, and actually seem to use that very interface to access its internal storage. Somehow, even though it has its own share of complexity problems, it makes me feel much more confident. Unfortunately I haven’t been able to make it work with OpenCryptoki, nor I have found how to properly make use of the OpenSC-based devices to store private and public keys accessible to the browser. Ah, NSS seem also to be the only component that allows access to multiple PKCS#11 providers at once.
Also, I found myself considering the diagram confusing, as software providing similar functionality was present at different heights in the image, with interfaces consumed and provided being connected on any side of the components’ representation. I have thus decided to clean it up, giving more sense to the vertical placement of the various components, from top to bottom: hardware devices, emulators, hardware access, access mediators, API providers, abstractions, libraries and – finally – user applications.
I also decided to change the colour of three interface connections: the one between applications and NSS, the new one between OpenSSL and its engines, and the one between OpenCryptoki and the ICA library (which now has an interface with a “S390” hardware device: I don’t know the architecture enough to understand what it accesses, and IBM documentation leaves a lot to be desired, but it seems to be something limited to their systems). These three are in-process interfaces (like PKCS#11 and, theoretically, PCS/SC and CT-API, more to that in a moment), while SCD, agent interfaces, Trousers and and TPM are out-of-process interfaces (requiring inter-process communication, or communication between the userland process and the kernel services) — I don’t know ICA to tell whether it uses in or out of process communication.
Unfortunately to give the proper details of in-process versus out of process communication, I would need to split up a number of those components in multiple ones, as all three of pcsc-lite and OpenCT use multiple interfaces: an in-process interface to provide the public interface to the application, and an out-of-process interface to access the underlying abstraction; the main difference between the two is where this happens (OpenCT implements all the drivers as standalone processes, and the in-process library accesses those; pcsc-lite instead has a single process that loads multiple driver plugins).
In the new diagram, I have detailed more the interaction between GnuPG, OpenSSH and their agents, simply because that situation is quite complex and even I strained to get it right: GnuPG never speaks directly with either of the SCD implementations: there is always another process, gpg-agent
that interfaces them with GnuPG proper, and it is this agent to provide support for OpenSSH as well. The distinction is fundamental to show off that it is quite possible to have the PKCS#11-compatible SCD implementation provide keys for OpenSSH, even though the original ssh-agent
(as well as ssh
itself) have support for the PKCS#11 interface. And also, the original scdaemon
implementation can, in very few cases, speak directly with the USB device via CCID.
I have decided to extend the diagram to incorporate the TPM engine for OpenSSL while at it, making it much more explicit that there is a plugin interface between OpenSSL and PKCS#11. This engine access trousers directly, without going trhough OpenCryptoki.
Speaking about OpenCryptoki, of which I’ll try to write about tomorrow, I decided to expose its internals a bit more than I have done for the rest of the packages for now. Mostly because it’ll make it much easier tomorrow to explain how it works, if I split it out this way. In particular, though, I’d like to note that it is the only component that does not expose a bridge between a daemon process and the applications using it; instead it uses an external daemon to regulate access to the devices, and then users in-process plugin-based communication to abstract access to different source of secure key storage.
OpenCT could use a similar split up, but since I’m not going to write about it for now, I don’t think I’ll work more on this. At any rate, I’m very satisfied with the new diagram. It has more details, and is thus more complex, but it also makes it possible to follow more tightly the interaction between various software, and why it is always so difficult to set up smartcard-based authentication (and hey, I still haven’t added PAM to the mix!)