mirror of
https://github.com/status-im/status-keycard.git
synced 2025-01-21 11:08:57 +00:00
implement UNBLOCK PIN
This commit is contained in:
parent
f05190111c
commit
91b4a96194
@ -16,7 +16,6 @@ public class WalletApplet extends Applet {
|
|||||||
static final byte PIN_LENGTH = 6;
|
static final byte PIN_LENGTH = 6;
|
||||||
static final byte PIN_MAX_RETRIES = 3;
|
static final byte PIN_MAX_RETRIES = 3;
|
||||||
|
|
||||||
static final short TMP_BUFFER_LENGTH = PIN_LENGTH;
|
|
||||||
static final short EC_KEY_SIZE = 256;
|
static final short EC_KEY_SIZE = 256;
|
||||||
|
|
||||||
|
|
||||||
@ -30,8 +29,8 @@ public class WalletApplet extends Applet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public WalletApplet(byte[] bArray, short bOffset, byte bLength) {
|
public WalletApplet(byte[] bArray, short bOffset, byte bLength) {
|
||||||
short c9Off = (short)(bOffset + bArray[bOffset] + 1);
|
short c9Off = (short)(bOffset + bArray[bOffset] + 1); // Skip AID
|
||||||
c9Off += (short)(bArray[bOffset] + 1 + 2);
|
c9Off += (short)(bArray[c9Off] + 2); // Skip Privileges and parameter length
|
||||||
|
|
||||||
puk = new OwnerPIN(PUK_MAX_RETRIES, PUK_LENGTH);
|
puk = new OwnerPIN(PUK_MAX_RETRIES, PUK_LENGTH);
|
||||||
puk.update(bArray, c9Off, PUK_LENGTH);
|
puk.update(bArray, c9Off, PUK_LENGTH);
|
||||||
@ -112,7 +111,7 @@ public class WalletApplet extends Applet {
|
|||||||
byte[] apduBuffer = apdu.getBuffer();
|
byte[] apduBuffer = apdu.getBuffer();
|
||||||
byte len = secureChannel.decryptAPDU(apduBuffer);
|
byte len = secureChannel.decryptAPDU(apduBuffer);
|
||||||
|
|
||||||
if (!(len == 6 && allDigits(apduBuffer, ISO7816.OFFSET_CDATA, len))) {
|
if (!(len == PIN_LENGTH && allDigits(apduBuffer, ISO7816.OFFSET_CDATA, len))) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +125,22 @@ public class WalletApplet extends Applet {
|
|||||||
if (!(secureChannel.isOpen() && pin.getTriesRemaining() == 0)) {
|
if (!(secureChannel.isOpen() && pin.getTriesRemaining() == 0)) {
|
||||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] apduBuffer = apdu.getBuffer();
|
||||||
|
byte len = secureChannel.decryptAPDU(apduBuffer);
|
||||||
|
|
||||||
|
if (!(len == (PUK_LENGTH + PIN_LENGTH) && allDigits(apduBuffer, ISO7816.OFFSET_CDATA, len))) {
|
||||||
|
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!puk.check(apduBuffer, ISO7816.OFFSET_CDATA, PUK_LENGTH)) {
|
||||||
|
ISOException.throwIt((short)((short) 0x63c0 | (short) puk.getTriesRemaining()));
|
||||||
|
}
|
||||||
|
|
||||||
|
pin.resetAndUnblock();
|
||||||
|
pin.update(apduBuffer, (short)(ISO7816.OFFSET_CDATA + PUK_LENGTH), PIN_LENGTH);
|
||||||
|
pin.check(apduBuffer, (short)(ISO7816.OFFSET_CDATA + PUK_LENGTH), PIN_LENGTH);
|
||||||
|
puk.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadKey(APDU apdu) {
|
private void loadKey(APDU apdu) {
|
||||||
|
@ -40,4 +40,9 @@ public class WalletAppletCommandSet {
|
|||||||
CommandAPDU changePIN = new CommandAPDU(0x80, WalletApplet.INS_CHANGE_PIN, 0, 0, secureChannel.encryptAPDU(pin.getBytes()));
|
CommandAPDU changePIN = new CommandAPDU(0x80, WalletApplet.INS_CHANGE_PIN, 0, 0, secureChannel.encryptAPDU(pin.getBytes()));
|
||||||
return apduChannel.transmit(changePIN);
|
return apduChannel.transmit(changePIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ResponseAPDU unblockPIN(String puk, String newPin) throws CardException {
|
||||||
|
CommandAPDU unblockPIN = new CommandAPDU(0x80, WalletApplet.INS_UNBLOCK_PIN, 0, 0, secureChannel.encryptAPDU((puk + newPin).getBytes()));
|
||||||
|
return apduChannel.transmit(unblockPIN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,8 @@ public class WalletAppletTest {
|
|||||||
response = cmdSet.verifyPIN("000000");
|
response = cmdSet.verifyPIN("000000");
|
||||||
assertEquals(0x63C0, response.getSW());
|
assertEquals(0x63C0, response.getSW());
|
||||||
|
|
||||||
//TODO: Unblock PIN to make the test non-destructive
|
response = cmdSet.unblockPIN("123456789012", "000000");
|
||||||
|
assertEquals(0x9000, response.getSW());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -135,4 +136,47 @@ public class WalletAppletTest {
|
|||||||
response = cmdSet.changePIN("000000");
|
response = cmdSet.changePIN("000000");
|
||||||
assertEquals(0x9000, response.getSW());
|
assertEquals(0x9000, response.getSW());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("UNBLOCK PIN command")
|
||||||
|
void unblockPinTest() throws CardException {
|
||||||
|
ResponseAPDU response = cmdSet.changePIN("123456");
|
||||||
|
assertEquals(0x6985, response.getSW());
|
||||||
|
|
||||||
|
cmdSet.openSecureChannel();
|
||||||
|
|
||||||
|
response = cmdSet.unblockPIN("123456789012", "000000");
|
||||||
|
assertEquals(0x6985, response.getSW());
|
||||||
|
|
||||||
|
response = cmdSet.verifyPIN("123456");
|
||||||
|
assertEquals(0x63C2, response.getSW());
|
||||||
|
|
||||||
|
response = cmdSet.verifyPIN("123456");
|
||||||
|
assertEquals(0x63C1, response.getSW());
|
||||||
|
|
||||||
|
response = cmdSet.verifyPIN("123456");
|
||||||
|
assertEquals(0x63C0, response.getSW());
|
||||||
|
|
||||||
|
response = cmdSet.unblockPIN("12345678901", "000000");
|
||||||
|
assertEquals(0x6A80, response.getSW());
|
||||||
|
|
||||||
|
response = cmdSet.unblockPIN("1234567890123", "000000");
|
||||||
|
assertEquals(0x6A80, response.getSW());
|
||||||
|
|
||||||
|
response = cmdSet.unblockPIN("123456789010", "000000");
|
||||||
|
assertEquals(0x63C4, response.getSW());
|
||||||
|
|
||||||
|
response = cmdSet.unblockPIN("123456789012", "654321");
|
||||||
|
assertEquals(0x9000, response.getSW());
|
||||||
|
|
||||||
|
apduChannel.getCard().getATR();
|
||||||
|
cmdSet.select();
|
||||||
|
cmdSet.openSecureChannel();
|
||||||
|
|
||||||
|
response = cmdSet.verifyPIN("654321");
|
||||||
|
assertEquals(0x9000, response.getSW());
|
||||||
|
|
||||||
|
response = cmdSet.changePIN("000000");
|
||||||
|
assertEquals(0x9000, response.getSW());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user