Version without elliptic curves and secure messaging compatible with JavaCard 3.0.1
This commit is contained in:
@@ -27,18 +27,14 @@ import javacardx.crypto.*;
|
||||
|
||||
public final class SmartPGPApplet extends Applet {
|
||||
|
||||
private final ECCurves ec;
|
||||
private final Persistent data;
|
||||
private final SecureMessaging sm;
|
||||
|
||||
private final Transients transients;
|
||||
|
||||
|
||||
public SmartPGPApplet() {
|
||||
ec = new ECCurves();
|
||||
data = new Persistent();
|
||||
transients = new Transients();
|
||||
sm = new SecureMessaging(transients);
|
||||
}
|
||||
|
||||
public static final void install(byte[] buf, short off, byte len) {
|
||||
@@ -53,8 +49,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
return data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC];
|
||||
case 2:
|
||||
return data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG];
|
||||
case 3:
|
||||
return sm.static_key;
|
||||
default:
|
||||
ISOException.throwIt(Constants.SW_REFERENCE_DATA_NOT_FOUND);
|
||||
return null;
|
||||
@@ -128,15 +122,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
}
|
||||
|
||||
private final void sensitiveData() {
|
||||
final byte proto = APDU.getProtocol();
|
||||
|
||||
if(((proto & APDU.PROTOCOL_MEDIA_MASK) == APDU.PROTOCOL_MEDIA_CONTACTLESS_TYPE_A) ||
|
||||
((proto & APDU.PROTOCOL_MEDIA_MASK) == APDU.PROTOCOL_MEDIA_CONTACTLESS_TYPE_B)) {
|
||||
if(sm.isInitialized() && !transients.secureMessagingOk()) {
|
||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void assertAdmin() {
|
||||
@@ -358,15 +343,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
k.attributes_length);
|
||||
break;
|
||||
|
||||
case Constants.TAG_ALGORITHM_ATTRIBUTES_SM:
|
||||
buf[off++] = (byte)0xd4;
|
||||
k = sm.static_key;
|
||||
off = Common.writeLength(buf, off, k.attributes_length);
|
||||
off = Util.arrayCopyNonAtomic(k.attributes, (short)0,
|
||||
buf, off,
|
||||
k.attributes_length);
|
||||
break;
|
||||
|
||||
case Constants.TAG_APPLICATION_RELATED_DATA:
|
||||
tlen = (short)(1 + 1 + Constants.EXTENDED_CAPABILITIES.length +
|
||||
1 + 1 + data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG].attributes_length +
|
||||
@@ -840,16 +816,12 @@ public final class SmartPGPApplet extends Applet {
|
||||
k = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT];
|
||||
break;
|
||||
|
||||
case Constants.CRT_SECURE_MESSAGING_KEY:
|
||||
k = sm.static_key;
|
||||
break;
|
||||
|
||||
default:
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return;
|
||||
}
|
||||
|
||||
k.importKey(ec, buf, (short)(off + 2), (short)(lc - off - 2));
|
||||
k.importKey(buf, (short)(off + 2), (short)(lc - off - 2));
|
||||
|
||||
} else {
|
||||
final short tag = Util.makeShort(p1, p2);
|
||||
@@ -1034,7 +1006,7 @@ public final class SmartPGPApplet extends Applet {
|
||||
|
||||
case Constants.TAG_ALGORITHM_ATTRIBUTES_SIG:
|
||||
assertAdmin();
|
||||
data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG].setAttributes(ec, buf, (short)0, lc);
|
||||
data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG].setAttributes(buf, (short)0, lc);
|
||||
JCSystem.beginTransaction();
|
||||
Util.arrayFillNonAtomic(data.digital_signature_counter, (short)0,
|
||||
(byte)data.digital_signature_counter.length, (byte)0);
|
||||
@@ -1043,17 +1015,12 @@ public final class SmartPGPApplet extends Applet {
|
||||
|
||||
case Constants.TAG_ALGORITHM_ATTRIBUTES_DEC:
|
||||
assertAdmin();
|
||||
data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC].setAttributes(ec, buf, (short)0, lc);
|
||||
data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC].setAttributes(buf, (short)0, lc);
|
||||
break;
|
||||
|
||||
case Constants.TAG_ALGORITHM_ATTRIBUTES_AUT:
|
||||
assertAdmin();
|
||||
data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT].setAttributes(ec, buf, (short)0, lc);
|
||||
break;
|
||||
|
||||
case Constants.TAG_ALGORITHM_ATTRIBUTES_SM:
|
||||
assertAdmin();
|
||||
sm.static_key.setAttributes(ec, buf, (short)0, lc);
|
||||
data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT].setAttributes(buf, (short)0, lc);
|
||||
break;
|
||||
|
||||
case Constants.TAG_PW_STATUS:
|
||||
@@ -1191,10 +1158,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
pkey = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT];
|
||||
break;
|
||||
|
||||
case Constants.CRT_SECURE_MESSAGING_KEY:
|
||||
pkey = sm.static_key;
|
||||
break;
|
||||
|
||||
default:
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return 0;
|
||||
@@ -1204,7 +1167,7 @@ public final class SmartPGPApplet extends Applet {
|
||||
|
||||
assertAdmin();
|
||||
|
||||
pkey.generate(ec);
|
||||
pkey.generate();
|
||||
|
||||
if(do_reset) {
|
||||
JCSystem.beginTransaction();
|
||||
@@ -1286,7 +1249,7 @@ public final class SmartPGPApplet extends Applet {
|
||||
return res;
|
||||
}
|
||||
|
||||
return data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC].decipher(ec, transients.buffer, lc);
|
||||
return data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC].decipher(transients.buffer, lc);
|
||||
}
|
||||
|
||||
/* PSO : ENCIPHER */
|
||||
@@ -1332,9 +1295,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
sensitiveData();
|
||||
assertUserMode82();
|
||||
return data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT].sign(transients.buffer, lc, true);
|
||||
|
||||
case (byte)0x01:
|
||||
return sm.establish(transients, ec, transients.buffer, lc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1390,10 +1350,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
|
||||
if(data.isTerminated) {
|
||||
switch(p2) {
|
||||
case (byte)1:
|
||||
sm.reset(transients);
|
||||
//missing break is intentional
|
||||
|
||||
case (byte)0:
|
||||
transients.clear();
|
||||
data.reset();
|
||||
@@ -1411,7 +1367,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
data.user_puk.reset();
|
||||
data.admin_pin.reset();
|
||||
transients.clear();
|
||||
sm.clearSession(transients);
|
||||
}
|
||||
|
||||
public final void process(final APDU apdu) {
|
||||
@@ -1429,8 +1384,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
return;
|
||||
}
|
||||
|
||||
transients.setSecureMessagingOk(false);
|
||||
|
||||
if(data.isTerminated) {
|
||||
if(apdubuf[ISO7816.OFFSET_CLA] != 0) {
|
||||
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
|
||||
@@ -1480,34 +1433,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
|
||||
short lc = transients.chainingInputLength();
|
||||
|
||||
if((apdubuf[ISO7816.OFFSET_CLA] & Constants.CLA_MASK_SECURE_MESSAGING) == Constants.CLA_MASK_SECURE_MESSAGING) {
|
||||
short off = lc;
|
||||
|
||||
if((short)(off + 1 + 1 + 1 + 1 + 3) > Constants.INTERNAL_BUFFER_MAX_LENGTH) {
|
||||
ISOException.throwIt(Constants.SW_MEMORY_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
transients.buffer[off++] = apdubuf[ISO7816.OFFSET_CLA];
|
||||
transients.buffer[off++] = apdubuf[ISO7816.OFFSET_INS];
|
||||
transients.buffer[off++] = p1;
|
||||
transients.buffer[off++] = p2;
|
||||
if(lc > (short)0xff) {
|
||||
transients.buffer[off++] = (byte)0;
|
||||
transients.buffer[off++] = (byte)((lc >> 8) & (byte)0xff);
|
||||
}
|
||||
transients.buffer[off++] = (byte)(lc & (byte)0xff);
|
||||
|
||||
transients.setChainingInputLength((short)0);
|
||||
|
||||
lc = sm.verifyAndDecryptCommand(transients, lc, off);
|
||||
|
||||
transients.setSecureMessagingOk(true);
|
||||
|
||||
} else if(sm.isSessionAvailable()) {
|
||||
clearConnection();
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
switch(apdubuf[ISO7816.OFFSET_INS]) {
|
||||
@@ -1576,23 +1501,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
sw = e.getReason();
|
||||
}
|
||||
|
||||
if(transients.secureMessagingOk()) {
|
||||
|
||||
if(available_le > 0) {
|
||||
short tmp = (short)(Constants.AES_BLOCK_SIZE - (available_le % Constants.AES_BLOCK_SIZE));
|
||||
available_le = Util.arrayCopyNonAtomic(SecureMessaging.PADDING_BLOCK, (short)0,
|
||||
transients.buffer, available_le,
|
||||
tmp);
|
||||
}
|
||||
|
||||
if((available_le != 0) ||
|
||||
(sw == (short)0x9000) ||
|
||||
((short)(sw & (short)0x6200) == (short)0x6200) ||
|
||||
((short)(sw & (short)0x6300) == (short)0x6300)) {
|
||||
available_le = sm.encryptAndSign(transients, available_le, sw);
|
||||
}
|
||||
}
|
||||
|
||||
transients.setOutputLength(available_le);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user