Handle extended length CRT

This commit is contained in:
Arnaud Fontaine 2019-06-17 13:58:37 +02:00
parent c67545e128
commit bf29d95c60
2 changed files with 66 additions and 15 deletions

View File

@ -109,9 +109,9 @@ public final class Constants {
protected static final short TAG_KEY_DERIVATION_FUNCTION = (short)0x00f9; protected static final short TAG_KEY_DERIVATION_FUNCTION = (short)0x00f9;
protected static final short TAG_ALGORITHM_INFORMATION = (short)0x00fa; protected static final short TAG_ALGORITHM_INFORMATION = (short)0x00fa;
protected static final short CRT_AUTHENTICATION_KEY = (short)0xa400; protected static final byte CRT_TAG_AUTHENTICATION_KEY = (byte)0xa4;
protected static final short CRT_SIGNATURE_KEY = (short)0xb600; protected static final byte CRT_TAG_SIGNATURE_KEY = (byte)0xb6;
protected static final short CRT_DECRYPTION_KEY = (short)0xb800; protected static final byte CRT_TAG_DECRYPTION_KEY = (byte)0xb8;
protected static final byte CLA_MASK_CHAINING = (byte)0x10; protected static final byte CLA_MASK_CHAINING = (byte)0x10;

View File

@ -730,7 +730,7 @@ public final class SmartPGPApplet extends Applet {
ISOException.throwIt(ISO7816.SW_WRONG_P1P2); ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
return; return;
} }
if(lc < 6) { if(lc < 8) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
return; return;
} }
@ -741,29 +741,34 @@ public final class SmartPGPApplet extends Applet {
} }
final short len = Common.readLength(buf, (byte)1, (short)(lc - 1)); 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) { if((short)(off + len) != lc) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
return; return;
} }
switch(Util.getShort(buf, off)) { byte extended_expect = (byte)0;
case Constants.CRT_SIGNATURE_KEY:
switch(buf[off]) {
case Constants.CRT_TAG_SIGNATURE_KEY:
k = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG]; k = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG];
JCSystem.beginTransaction(); JCSystem.beginTransaction();
Util.arrayFillNonAtomic(data.digital_signature_counter, Util.arrayFillNonAtomic(data.digital_signature_counter,
(short)0, (byte)data.digital_signature_counter.length, (short)0, (byte)data.digital_signature_counter.length,
(byte)0); (byte)0);
JCSystem.commitTransaction(); JCSystem.commitTransaction();
extended_expect = (byte)0x01;
break; break;
case Constants.CRT_DECRYPTION_KEY: case Constants.CRT_TAG_DECRYPTION_KEY:
k = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC]; k = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC];
extended_expect = (byte)0x02;
break; break;
case Constants.CRT_AUTHENTICATION_KEY: case Constants.CRT_TAG_AUTHENTICATION_KEY:
k = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT]; k = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT];
extended_expect = (byte)0x03;
break; break;
default: default:
@ -771,7 +776,30 @@ public final class SmartPGPApplet extends Applet {
return; 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 { } else {
final short tag = Util.makeShort(p1, p2); final short tag = Util.makeShort(p1, p2);
@ -1084,26 +1112,30 @@ public final class SmartPGPApplet extends Applet {
return 0; return 0;
} }
if(lc != 2) { if(lc < 2) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
return 0; return 0;
} }
boolean do_reset = false; boolean do_reset = false;
PGPKey pkey; PGPKey pkey;
byte extended_expect = (byte)0;
switch(Util.makeShort(buf[0], buf[1])) { switch(buf[0]) {
case Constants.CRT_SIGNATURE_KEY: case Constants.CRT_TAG_SIGNATURE_KEY:
do_reset = true; do_reset = true;
pkey = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG]; pkey = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG];
extended_expect = (byte)0x01;
break; break;
case Constants.CRT_DECRYPTION_KEY: case Constants.CRT_TAG_DECRYPTION_KEY:
pkey = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC]; pkey = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC];
extended_expect = (byte)0x02;
break; break;
case Constants.CRT_AUTHENTICATION_KEY: case Constants.CRT_TAG_AUTHENTICATION_KEY:
pkey = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT]; pkey = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT];
extended_expect = (byte)0x03;
break; break;
default: default:
@ -1111,6 +1143,25 @@ public final class SmartPGPApplet extends Applet {
return 0; 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) { if(p1 == (byte)0x80) {
assertAdmin(); assertAdmin();