diff --git a/src/fr/anssi/smartpgp/Constants.java b/src/fr/anssi/smartpgp/Constants.java index 9e3070b..6a66b73 100644 --- a/src/fr/anssi/smartpgp/Constants.java +++ b/src/fr/anssi/smartpgp/Constants.java @@ -109,9 +109,9 @@ public final class Constants { protected static final short TAG_KEY_DERIVATION_FUNCTION = (short)0x00f9; protected static final short TAG_ALGORITHM_INFORMATION = (short)0x00fa; - protected static final short CRT_AUTHENTICATION_KEY = (short)0xa400; - protected static final short CRT_SIGNATURE_KEY = (short)0xb600; - protected static final short CRT_DECRYPTION_KEY = (short)0xb800; + protected static final byte CRT_TAG_AUTHENTICATION_KEY = (byte)0xa4; + protected static final byte CRT_TAG_SIGNATURE_KEY = (byte)0xb6; + protected static final byte CRT_TAG_DECRYPTION_KEY = (byte)0xb8; protected static final byte CLA_MASK_CHAINING = (byte)0x10; diff --git a/src/fr/anssi/smartpgp/SmartPGPApplet.java b/src/fr/anssi/smartpgp/SmartPGPApplet.java index 899d7d4..e072ac2 100644 --- a/src/fr/anssi/smartpgp/SmartPGPApplet.java +++ b/src/fr/anssi/smartpgp/SmartPGPApplet.java @@ -730,7 +730,7 @@ public final class SmartPGPApplet extends Applet { ISOException.throwIt(ISO7816.SW_WRONG_P1P2); return; } - if(lc < 6) { + if(lc < 8) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); return; } @@ -741,29 +741,34 @@ public final class SmartPGPApplet extends Applet { } final short len = Common.readLength(buf, (byte)1, (short)(lc - 1)); - final short off = Common.skipLength(buf, (byte)1, (short)(lc - 1)); + short off = Common.skipLength(buf, (byte)1, (short)(lc - 1)); if((short)(off + len) != lc) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); return; } - switch(Util.getShort(buf, off)) { - case Constants.CRT_SIGNATURE_KEY: + byte extended_expect = (byte)0; + + switch(buf[off]) { + case Constants.CRT_TAG_SIGNATURE_KEY: k = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG]; JCSystem.beginTransaction(); Util.arrayFillNonAtomic(data.digital_signature_counter, (short)0, (byte)data.digital_signature_counter.length, (byte)0); JCSystem.commitTransaction(); + extended_expect = (byte)0x01; break; - case Constants.CRT_DECRYPTION_KEY: + case Constants.CRT_TAG_DECRYPTION_KEY: k = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC]; + extended_expect = (byte)0x02; break; - case Constants.CRT_AUTHENTICATION_KEY: + case Constants.CRT_TAG_AUTHENTICATION_KEY: k = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT]; + extended_expect = (byte)0x03; break; default: @@ -771,7 +776,30 @@ public final class SmartPGPApplet extends Applet { return; } - k.importKey(buf, (short)(off + 2), (short)(lc - off - 2)); + ++off; + + if(buf[off] == (byte)0) { + ++off; + } else if(buf[off] == (byte)3) { + ++off; + if(buf[off++] != (byte)0x84) { + ISOException.throwIt(ISO7816.SW_WRONG_DATA); + return; + } + if(buf[off++] != (byte)1) { + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); + return; + } + if(buf[off++] != extended_expect) { + ISOException.throwIt(ISO7816.SW_WRONG_DATA); + return; + } + } else { + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); + return; + } + + k.importKey(buf, off, (short)(lc - off)); } else { final short tag = Util.makeShort(p1, p2); @@ -1084,26 +1112,30 @@ public final class SmartPGPApplet extends Applet { return 0; } - if(lc != 2) { + if(lc < 2) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); return 0; } boolean do_reset = false; PGPKey pkey; + byte extended_expect = (byte)0; - switch(Util.makeShort(buf[0], buf[1])) { - case Constants.CRT_SIGNATURE_KEY: + switch(buf[0]) { + case Constants.CRT_TAG_SIGNATURE_KEY: do_reset = true; pkey = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG]; + extended_expect = (byte)0x01; break; - case Constants.CRT_DECRYPTION_KEY: + case Constants.CRT_TAG_DECRYPTION_KEY: pkey = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC]; + extended_expect = (byte)0x02; break; - case Constants.CRT_AUTHENTICATION_KEY: + case Constants.CRT_TAG_AUTHENTICATION_KEY: pkey = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT]; + extended_expect = (byte)0x03; break; default: @@ -1111,6 +1143,25 @@ public final class SmartPGPApplet extends Applet { return 0; } + if(lc == (short)2) { + if(buf[1] != (byte)0) { + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); + return 0; + } + } else if(lc == (short)5) { + if((buf[1] != (byte)3) || (buf[3] != (byte)1)) { + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); + return 0; + } + if((buf[2] != (byte)0x84) || buf[4] != extended_expect) { + ISOException.throwIt(ISO7816.SW_WRONG_DATA); + return 0; + } + } else { + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); + return 0; + } + if(p1 == (byte)0x80) { assertAdmin();