Prevent unnecessary object initializations
This commit is contained in:
parent
4720e95cf2
commit
9a025cf2dc
2 changed files with 66 additions and 39 deletions
|
@ -18,6 +18,7 @@ public class MyApplet extends Applet {
|
||||||
final static byte PIN_TRY_LIMIT =(byte)0x03;
|
final static byte PIN_TRY_LIMIT =(byte)0x03;
|
||||||
final static byte MAX_PIN_SIZE =(byte)0x08;
|
final static byte MAX_PIN_SIZE =(byte)0x08;
|
||||||
private byte[] authorName = new byte[] { 'M', 'a', 'n', 'u', 'e', 'l' };
|
private byte[] authorName = new byte[] { 'M', 'a', 'n', 'u', 'e', 'l' };
|
||||||
|
private short storageLength;
|
||||||
private byte[] storage = new byte[] {};
|
private byte[] storage = new byte[] {};
|
||||||
private OwnerPIN pin;
|
private OwnerPIN pin;
|
||||||
|
|
||||||
|
@ -105,8 +106,8 @@ public class MyApplet extends Applet {
|
||||||
} else {
|
} else {
|
||||||
response = storage;
|
response = storage;
|
||||||
|
|
||||||
if (length > response.length) {
|
if (length > storageLength) {
|
||||||
ISOException.throwIt((short)(ISO7816.SW_CORRECT_LENGTH_00 | response.length));
|
ISOException.throwIt((short)(ISO7816.SW_CORRECT_LENGTH_00 | storageLength));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,13 +115,12 @@ public class MyApplet extends Applet {
|
||||||
apdu.sendBytesLong(response, (short) 0, length);
|
apdu.sendBytesLong(response, (short) 0, length);
|
||||||
break;
|
break;
|
||||||
case 0x02:
|
case 0x02:
|
||||||
length = apdu.setIncomingAndReceive();
|
storageLength = apdu.setIncomingAndReceive();
|
||||||
storage = new byte[length];
|
|
||||||
|
|
||||||
if (length > 20) {
|
if (storageLength > 20) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
} else {
|
} else {
|
||||||
Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, storage, (short) 0, length);
|
Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, storage, (short) 0, storageLength);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x20:
|
case 0x20:
|
||||||
|
|
|
@ -18,8 +18,17 @@ import javacardx.crypto.Cipher;
|
||||||
* @author <user>
|
* @author <user>
|
||||||
*/
|
*/
|
||||||
public class SecretApplet extends Applet {
|
public class SecretApplet extends Applet {
|
||||||
private AESKey encryptionKey;
|
private AESKey encryptionKey = null;
|
||||||
private AESKey macKey;
|
private AESKey macKey = null;
|
||||||
|
|
||||||
|
private byte[] cipherIV = new byte[] { 0x18, 0x24, 0x57, (byte)0xD6, (byte)0x97, 0x33, 0x69, (byte)0xED, 0x05, 0x4D, 0x6E, 0x14, (byte)0x93, (byte)0xE4, (byte)0xB7, 0x45 };
|
||||||
|
private byte[] macIV = new byte[] { (byte)0xB6, 0x6C, (byte)0xAC, (byte)0xC7, (byte)0xD6, 0x78, (byte)0x88, 0x18, 0x07, (byte)0x88, (byte)0xA4, 0x27, 0x07, 0x55, 0x50, 0x2A };
|
||||||
|
|
||||||
|
private Cipher cipher = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false);;
|
||||||
|
private Signature signature = Signature.getInstance(Signature.ALG_AES_MAC_128_NOPAD, false);
|
||||||
|
|
||||||
|
private short length;
|
||||||
|
private byte[] storage = new byte[(short)(64 + 16)];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Installs this applet.
|
* Installs this applet.
|
||||||
|
@ -37,8 +46,50 @@ public class SecretApplet extends Applet {
|
||||||
*/
|
*/
|
||||||
protected SecretApplet() {
|
protected SecretApplet() {
|
||||||
register();
|
register();
|
||||||
encryptionKey = initializeKey(new byte[] { 0x59, (byte)0xA3, (byte)0xFA, 0x76, 0x35, 0x40, 0x01, (byte)0x82, (byte)0xA5, (byte)0xC0, (byte)0xAB, (byte)0xE0, 0x1F, 0x30, (byte)0x89, (byte)0xFA });
|
}
|
||||||
macKey = initializeKey(new byte[] { 0x58, (byte)0x9F, 0x61, 0x62, (byte)0xBB, 0x10, (byte)0x89, (byte)0xD8, 0x1A, 0x16, (byte)0xD3, 0x2A, 0x3F, 0x06, 0x27, (byte)0xC6 });
|
|
||||||
|
/**
|
||||||
|
* Gets a key for encrypting and decrypting data.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A key for encrypting and decrypting data.
|
||||||
|
*/
|
||||||
|
protected AESKey getEncryptionKey() {
|
||||||
|
if (encryptionKey == null) {
|
||||||
|
encryptionKey = initializeKey(new byte[] { 0x59, (byte)0xA3, (byte)0xFA, 0x76, 0x35, 0x40, 0x01, (byte)0x82, (byte)0xA5, (byte)0xC0, (byte)0xAB, (byte)0xE0, 0x1F, 0x30, (byte)0x89, (byte)0xFA });
|
||||||
|
}
|
||||||
|
|
||||||
|
return encryptionKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a key for signing and verifying messages.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A key for signing and verifying messages.
|
||||||
|
*/
|
||||||
|
protected AESKey getMACKey() {
|
||||||
|
if (macKey == null) {
|
||||||
|
macKey = initializeKey(new byte[] { 0x58, (byte)0x9F, 0x61, 0x62, (byte)0xBB, 0x10, (byte)0x89, (byte)0xD8, 0x1A, 0x16, (byte)0xD3, 0x2A, 0x3F, 0x06, 0x27, (byte)0xC6 });
|
||||||
|
}
|
||||||
|
|
||||||
|
return macKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AESKey initializeKey(byte[] keyBytes) {
|
||||||
|
AESKey key = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false);
|
||||||
|
key.setKey(keyBytes, (short)0);
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Cipher getEncryptionCipher(byte mode) {
|
||||||
|
cipher.init(encryptionKey, mode, cipherIV, (short)0, (short)cipherIV.length);
|
||||||
|
return cipher;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Signature getMACSignature(byte mode) {
|
||||||
|
signature.init(macKey, mode, macIV, (short)0, (short)macIV.length);
|
||||||
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,7 +99,6 @@ public class SecretApplet extends Applet {
|
||||||
* @param apdu the incoming APDU
|
* @param apdu the incoming APDU
|
||||||
*/
|
*/
|
||||||
public void process(APDU apdu) {
|
public void process(APDU apdu) {
|
||||||
short length;
|
|
||||||
byte[] buffer = apdu.getBuffer();
|
byte[] buffer = apdu.getBuffer();
|
||||||
|
|
||||||
if (selectingApplet()) {
|
if (selectingApplet()) {
|
||||||
|
@ -62,21 +112,19 @@ public class SecretApplet extends Applet {
|
||||||
try {
|
try {
|
||||||
switch (instruction) {
|
switch (instruction) {
|
||||||
case 0x42:
|
case 0x42:
|
||||||
byte[] encrypted;
|
|
||||||
length = apdu.setIncomingAndReceive();
|
length = apdu.setIncomingAndReceive();
|
||||||
|
|
||||||
if (length > 64) {
|
if (length > 64) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
} else {
|
} else {
|
||||||
encrypted = new byte[(short)(length + 16)];
|
|
||||||
Cipher cipher = getEncryptionCipher(Cipher.MODE_ENCRYPT);
|
Cipher cipher = getEncryptionCipher(Cipher.MODE_ENCRYPT);
|
||||||
cipher.doFinal(buffer, ISO7816.OFFSET_CDATA, length, encrypted, (short)0);
|
cipher.doFinal(buffer, ISO7816.OFFSET_CDATA, length, storage, (short)0);
|
||||||
|
|
||||||
Signature signature = getMACSignature(Signature.MODE_SIGN);
|
Signature signature = getMACSignature(Signature.MODE_SIGN);
|
||||||
short totalLength = (short)(length + signature.sign(encrypted, (short)0, length, encrypted, length));
|
short totalLength = (short)(length + signature.sign(storage, (short)0, length, storage, length));
|
||||||
apdu.setOutgoing();
|
apdu.setOutgoing();
|
||||||
apdu.setOutgoingLength(totalLength);
|
apdu.setOutgoingLength(totalLength);
|
||||||
apdu.sendBytesLong(encrypted, (short)0, totalLength);
|
apdu.sendBytesLong(storage, (short)0, totalLength);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x44:
|
case 0x44:
|
||||||
|
@ -93,13 +141,12 @@ public class SecretApplet extends Applet {
|
||||||
if (!signature.verify(buffer, ISO7816.OFFSET_CDATA, messageLength, buffer, signatureOffset, signatureLength)) {
|
if (!signature.verify(buffer, ISO7816.OFFSET_CDATA, messageLength, buffer, signatureOffset, signatureLength)) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||||
} else {
|
} else {
|
||||||
byte[] decrypted = new byte[messageLength];
|
|
||||||
Cipher cipher = getEncryptionCipher(Cipher.MODE_DECRYPT);
|
Cipher cipher = getEncryptionCipher(Cipher.MODE_DECRYPT);
|
||||||
cipher.doFinal(buffer, ISO7816.OFFSET_CDATA, messageLength, decrypted, (short)0);
|
cipher.doFinal(buffer, ISO7816.OFFSET_CDATA, messageLength, storage, (short)0);
|
||||||
|
|
||||||
apdu.setOutgoing();
|
apdu.setOutgoing();
|
||||||
apdu.setOutgoingLength(messageLength);
|
apdu.setOutgoingLength(messageLength);
|
||||||
apdu.sendBytesLong(decrypted, (short)0, messageLength);
|
apdu.sendBytesLong(storage, (short)0, messageLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -115,24 +162,4 @@ public class SecretApplet extends Applet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AESKey initializeKey(byte[] keyBytes) {
|
|
||||||
AESKey key = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false);
|
|
||||||
key.setKey(keyBytes, (short)0);
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Cipher getEncryptionCipher(byte mode) {
|
|
||||||
byte[] initializationVector = new byte[] { 0x18, 0x24, 0x57, (byte)0xD6, (byte)0x97, 0x33, 0x69, (byte)0xED, 0x05, 0x4D, 0x6E, 0x14, (byte)0x93, (byte)0xE4, (byte)0xB7, 0x45 };
|
|
||||||
Cipher cipher = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false);
|
|
||||||
cipher.init(encryptionKey, mode, initializationVector, (short)0, (short)initializationVector.length);
|
|
||||||
return cipher;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Signature getMACSignature(byte mode) {
|
|
||||||
byte[] initializationVector = new byte[] { (byte)0xB6, 0x6C, (byte)0xAC, (byte)0xC7, (byte)0xD6, 0x78, (byte)0x88, 0x18, 0x07, (byte)0x88, (byte)0xA4, 0x27, 0x07, 0x55, 0x50, 0x2A };
|
|
||||||
Signature signature = Signature.getInstance(Signature.ALG_AES_MAC_128_NOPAD, false);
|
|
||||||
signature.init(macKey, mode, initializationVector, (short)0, (short)initializationVector.length);
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue