Writing about technical topics is fun because it's a job that allows you to try out a variety of things before you actually start writing about it. This morning, the first 30 pages of my white paper about digital signatures were sent to all the subscribers of our news letter. I'm very curious about the feedback I'll get.
In the meantime, I'm working on the examples for the next couple of chapters. More specifically: on the examples where I use a smart card (the Belgian eID) to sign a PDF. I've been testing different card readers:
From left to right, you can see the Vasco DP 855, the Vasco DP 865, and the Vasco DP 920. The cards in the picture are a test card (an eID for Alice Specimen) and my own Belgian identity card.
In the context of the white paper (and partly because of an assignment for the Belgian Federal Department of Finance), I've written a small eID library, a minimal implementation that is able to send a hash of PDF bytes to Java-enabled chip on the belgian eID, and that gets signed bytes in return. In short: I've written a proof of concept that shows how to sign a PDF document using a smart card.
In the first implementation, this only worked when you entered the PIN code of your eID using the keyboard of your computer. I didn't like that, and I wanted to test with smart card readers that have their own pin pad. This is much safer; there's no risk that somebody logs the keys you've entered. I did my first tests with the DP 855 and they failed miserably.
When I plugged in the device, there was no problem installing the driver. Microsoft immediately found its own Microsoft USB CCID smartcard Reader (WUDF) driver. However, the following command always returned null:
card.transmitControlCommand(CONTROL_CODE_QUERY_FEATURES, new byte);
I was able to transmit
CommandAPDU calls, and I received
ResponseAPDUs in return, but all
transmitControlCommand() calls failed. In plain language: I was able to communicate with the smart card in the reader, but not with the device itself. I was 99% sure that the device driver was the culprit, but I didn't have a clue which driver I could use. I searched the net in vain, and I totally screwed up my OS trying to get the device to work. Silly me: sometimes I'm just to stubborn to ask for help.
In any case, after I contacted Vasco and received an answer with some drivers in attachment, the problem was solved in less than half an hour.
The installation guide provided an explanation as to why my previous efforts didn't have any result:
The PC/SC 2.0 standard defines a set of features and control codes that can be used to interact with the reader directly through I/O commands. Current versions of the Microsoft USB CCID class however driver discard these I/O controls rather than forwarding them, effectively hiding the features provided by the reader from PC/SC 2.0 enabled software.
I installed the new driver I received from Vasco, and:
The VASCO Digipass CCID filter driver circumvents the shortcomings of the Microsoft CCID class driver by filtering I/O control commands before they are processed by the driver itself. This approach allows the filter driver to "re-map" the control commands to (proprietary) APDU calls to be interpreted by the VASCO Digipass card reader.
The following commands and features are forwarded by the VASCO Digipass CCID filter driver:
I tried with the DP 865 first, and it worked from the first try. Then I tested the DP 855 and the DP 920. There was a minor problem because I needed to remove en reinstall the driver every time I switched to another card reader, but that wasn't a huge problem. I can live with that.
I submitted a talk for Java One about this topic, but somehow they didn't seem to be interested in sharing first hand experience about the less than optimal documented
javax.smartcardio package. Maybe it's too early to talk about this topic in the US. I've now submitted the talk for Devoxx. I'm sure the Devoxx committee has a better understanding of high-tech innovation.