enforce P1 on LOAD KEY

This commit is contained in:
Michele Balistreri 2017-09-30 12:24:19 +03:00
parent 18ff9b1bdb
commit dd11e0cfa4
4 changed files with 23 additions and 8 deletions

View File

@ -109,7 +109,7 @@ always returns 0x63C0, even if the PUK is inserted correctly. In this case the w
* P1 = 0x01 (ECC SECP256k1 keypair) * P1 = 0x01 (ECC SECP256k1 keypair)
* P2 = 0x00 * P2 = 0x00
* Data = the key data * Data = the key data
* Response SW = 0x9000 on success, 0x6A80 if the format is invalid * Response SW = 0x9000 on success, 0x6A80 if the format is invalid, 0x6A86 if P1 is invalid
* Preconditions: Secure Channel must be opened, user PIN must be verified * Preconditions: Secure Channel must be opened, user PIN must be verified
At the moment P1 can only be 0x01, but new key types could be added later. The ECC SECP256k1 keypair is At the moment P1 can only be 0x01, but new key types could be added later. The ECC SECP256k1 keypair is

View File

@ -17,6 +17,8 @@ public class WalletApplet extends Applet {
static final short EC_KEY_SIZE = 256; static final short EC_KEY_SIZE = 256;
static final byte LOAD_KEY_EC = 0x01;
static final byte TLV_KEY_TEMPLATE = (byte) 0xA1; static final byte TLV_KEY_TEMPLATE = (byte) 0xA1;
static final byte TLV_PUB_KEY = (byte) 0x80; static final byte TLV_PUB_KEY = (byte) 0x80;
static final byte TLV_PRIV_KEY = (byte) 0x81; static final byte TLV_PRIV_KEY = (byte) 0x81;
@ -27,6 +29,7 @@ public class WalletApplet extends Applet {
private ECPublicKey publicKey; private ECPublicKey publicKey;
private ECPrivateKey privateKey; private ECPrivateKey privateKey;
private Signature signature; private Signature signature;
private boolean signInProgress;
public static void install(byte[] bArray, short bOffset, byte bLength) { public static void install(byte[] bArray, short bOffset, byte bLength) {
new WalletApplet(bArray, bOffset, bLength); new WalletApplet(bArray, bOffset, bLength);
@ -51,6 +54,7 @@ public class WalletApplet extends Applet {
ECCurves.setSECP256K1CurveParameters(privateKey); ECCurves.setSECP256K1CurveParameters(privateKey);
signature = Signature.getInstance(Signature.ALG_ECDSA_SHA, false); signature = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
signInProgress = false;
register(bArray, (short) (bOffset + 1), bArray[bOffset]); register(bArray, (short) (bOffset + 1), bArray[bOffset]);
} }
@ -160,6 +164,11 @@ public class WalletApplet extends Applet {
} }
byte[] apduBuffer = apdu.getBuffer(); byte[] apduBuffer = apdu.getBuffer();
if (apduBuffer[ISO7816.OFFSET_P1] != LOAD_KEY_EC) {
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
secureChannel.decryptAPDU(apduBuffer); secureChannel.decryptAPDU(apduBuffer);
short pubOffset = (short)(ISO7816.OFFSET_CDATA + 2); short pubOffset = (short)(ISO7816.OFFSET_CDATA + 2);
@ -180,7 +189,7 @@ public class WalletApplet extends Applet {
JCSystem.commitTransaction(); JCSystem.commitTransaction();
signature.init(privateKey, Signature.MODE_SIGN); signInProgress = false;
} }
private void sign(APDU apdu) { private void sign(APDU apdu) {
@ -189,6 +198,9 @@ public class WalletApplet extends Applet {
if (!(secureChannel.isOpen() && pin.isValidated() && privateKey.isInitialized())) { if (!(secureChannel.isOpen() && pin.isValidated() && privateKey.isInitialized())) {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
} }
//signature.init(privateKey, Signature.MODE_SIGN);
} }
private boolean allDigits(byte[] buffer, short off, short len) { private boolean allDigits(byte[] buffer, short off, short len) {

View File

@ -71,11 +71,11 @@ public class WalletAppletCommandSet {
data[5 + publicKey.length] = (byte) privLen; data[5 + publicKey.length] = (byte) privLen;
System.arraycopy(privateKey, privOff, data, 6 + publicKey.length, privLen); System.arraycopy(privateKey, privOff, data, 6 + publicKey.length, privLen);
return loadKey(data); return loadKey(data, WalletApplet.LOAD_KEY_EC);
} }
public ResponseAPDU loadKey(byte[] data) throws CardException { public ResponseAPDU loadKey(byte[] data, byte keyType) throws CardException {
CommandAPDU loadKey = new CommandAPDU(0x80, WalletApplet.INS_LOAD_KEY, 0, 0, secureChannel.encryptAPDU(data)); CommandAPDU loadKey = new CommandAPDU(0x80, WalletApplet.INS_LOAD_KEY, keyType, 0, secureChannel.encryptAPDU(data));
return apduChannel.transmit(loadKey); return apduChannel.transmit(loadKey);
} }
} }

View File

@ -204,13 +204,16 @@ public class WalletAppletTest {
response = cmdSet.verifyPIN("000000"); response = cmdSet.verifyPIN("000000");
assertEquals(0x9000, response.getSW()); assertEquals(0x9000, response.getSW());
response = cmdSet.loadKey(new byte[] { (byte) 0xAA, 0x02, (byte) 0x80, 0x00}); response = cmdSet.loadKey(new byte[] { (byte) 0xAA, 0x02, (byte) 0x80, 0x00}, (byte) 0x00);
assertEquals(0x6A86, response.getSW());
response = cmdSet.loadKey(new byte[] { (byte) 0xAA, 0x02, (byte) 0x80, 0x00}, WalletApplet.LOAD_KEY_EC);
assertEquals(0x6A80, response.getSW()); assertEquals(0x6A80, response.getSW());
response = cmdSet.loadKey(new byte[] { (byte) 0xA1, 0x02, (byte) 0x80, 0x00}); response = cmdSet.loadKey(new byte[] { (byte) 0xA1, 0x02, (byte) 0x80, 0x00}, WalletApplet.LOAD_KEY_EC);
assertEquals(0x6A80, response.getSW()); assertEquals(0x6A80, response.getSW());
response = cmdSet.loadKey(new byte[] { (byte) 0xA1, 0x06, (byte) 0x80, 0x01, 0x01, (byte) 0x81, 0x01, 0x02}); response = cmdSet.loadKey(new byte[] { (byte) 0xA1, 0x06, (byte) 0x80, 0x01, 0x01, (byte) 0x81, 0x01, 0x02}, WalletApplet.LOAD_KEY_EC);
assertEquals(0x6A80, response.getSW()); assertEquals(0x6A80, response.getSW());
response = cmdSet.loadKey(keyPair); response = cmdSet.loadKey(keyPair);