OpenPGP card on Javacard

Sten Lindgren ged at
Wed Aug 1 16:06:38 CEST 2007

I have released a alpha test version of an applet implementing part of
the OpenPGP card specification on Java card. It is avaible from
sourceforge at Feel free to
test it but don't use it for production use since it is alpha. If you
remove the applet from your card to update in the futureyou loose your

This implementation has only been tested on one brand of cards using Linux
and gnupg. I does not support key sizes above 1536 bits. You may have to
apply a patch to gnupg apdu.c implementing support for "SW_EXACT_LENGTH"
in order to get it to work, the patch is in the release on sourceforge
and attached to this mail. The patch is against GnuPG 1.4.7, no other
version has been tested yet.
Key import doesn't work, only on card key generation. Please read the
README file before trying to use it. Most other parts of the specification
should be implemented.
Only some basic testing of key generation, signing and decryption has been
done. Additional features as use of authentification key has not been
tested. I you use authentification somewhere feel free to test and report
if it works or not.

Questions and bug reports should be sent to me.

Some todo items that remains to be done:
- Support for 2048 bit keys (This will most likely need ENVELOPE to be
implemented both on card and in gnupg. 2048 bit acually work for key
generation and signing but not for decryption due to need for more then
254 bytes of data to be sent to the card).
- Key import. (This might not be possible to do in accordance with the
OpenPGP card specification due to limitations in the Java Card API)
- Automatic generation of random serial numbers for the card (when
- Testing on more cards.

Sten Lindgren				ged at
-------------- next part --------------
*** g10/apdu.c	2006-03-05 15:46:14.000000000 +0100
--- ../gnupg-1.4.7.patched/g10/apdu.c	2007-07-10 12:50:03.000000000 +0200
*** 2640,2645 ****
--- 2640,2660 ----
        return rc? rc : SW_HOST_INCOMPLETE_CARD_RESPONSE;
    sw = (result[resultlen-2] << 8) | result[resultlen-1];
+   /* A small hack to fix support for cards sending back SW_EXACT_LENGTH */
+   if ((sw & 0xff00) == SW_EXACT_LENGTH && (sw & 0x00ff) > 0)
+     {
+       resultlen = RESULTLEN;
+       apdu[apdulen - 1] = (sw & 0x00ff);
+       rc = send_apdu (slot, apdu, apdulen, result, &resultlen, pininfo);
+       if (rc || resultlen < 2)
+ 	{
+ 	  log_error ("apdu_send_simple(%d) failed: %s\n",
+ 		     slot, apdu_strerror (rc));
+ 	  unlock_slot (slot);
+ 	}
+       sw = (result[resultlen-2] << 8) | result[resultlen-1];
+     }
    /* store away the returned data but strip the statusword. */
    resultlen -= 2;
    if (DBG_CARD_IO)

More information about the Gnupg-users mailing list