github-af / SmartPGP

SmartPGP is a JavaCard implementation of the OpenPGP card specifications
GNU General Public License v2.0
229 stars 48 forks source link

Command chaining? #6

Closed fredriklj closed 6 years ago

fredriklj commented 6 years ago

Greetings. I am trying to figure out how to put a DO larger than 252 bytes on the card. It seems the application does not understand command chaining using the ENVELOPE command (INS C2/C3) - or I am doing it completely wrong.

Could you please shed some light wether it is supported or not? Also, I have tried to increase the APDU_MAX_LENGTH in Constants.java, but is unable to have the application accept extended length APDUs.

Thanks for any clarifications on the matter.

af-anssi commented 6 years ago

The ENVELOPE command from the ISO7816 standard is not supported by SmartPGP, but command chaining as specificed in the OpenPGP specification is (see pages 70 and 77 of the v3.3 specification). The OpenPGP specification actually tolerates any of these mechanisms. You can have a look at the python script in bin/smartpgp/commands.py to see some examples of a chained command (https://github.com/ANSSI-FR/SmartPGP/blob/master/bin/smartpgp/commands.py#L240) and a chained response (https://github.com/ANSSI-FR/SmartPGP/blob/master/bin/smartpgp/commands.py#L261).

Large APDUs are not supported by default because many readers are not supporting them correctly, even if they announce they do, especially contacless ones. If you know your readers are working properly, you need (at least):

  1. to increase the APDU_MAX_LENGTH to some value lower than the value in the INTERNAL_BUFFER_MAX_LENGTH field in the Constants class;
  2. to make the applet class implement the javacardx.apdu.ExtendedLength interface.
fredriklj commented 6 years ago

Many thanks! I'll try to set the CLA byte to make command chaining work, should be straight-forward.

Regarding (2) on enabling extended length support, would that be as simple as just changing line 29 of SmartPGPApplet.java to:

public final class SmartPGPApplet extends Applet implements ExtendedLength { ..

..or should I go through the code to make sure multiple-byte Lc/Le is handled correctly?

af-anssi commented 6 years ago

Basically yes. The applet was written to support large APDUs so it handles Lc/Le on several bytes correctly.

I pushed a patch here to support large APDUs. I tested it on just one card so I cannot guarantee it will work as is. Could you try it and tell me ?

fredriklj commented 6 years ago

Works for me :) Also only tested on one type of card but works both using contact- and contactless interface. Thanks again!

fredriklj commented 6 years ago

On a side note, I noticed in Constants.java in the HISTORICAL_BYTES declaration that card service data had the tag 0xC1. I think it should be 0x31.

af-anssi commented 6 years ago

Good news ! For the "card service data", you are right about the fact that the value is incorrect when "extended length" is supported. According to the spec (see page 40 of the v3.3 specification), it appears several bits should also be set, in addition to the already set ones, which by the way implies to handle some EF data that do not exist in the current version of SmartPGP. As of today, they are not used by GnuPG nor by OpenKeychain. We could consider to handle these data if some implementation rely on them.