enforce P1 on LOAD KEY
This commit is contained in:
parent
18ff9b1bdb
commit
dd11e0cfa4
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue