implement CHANGE PIN

This commit is contained in:
Michele Balistreri 2017-09-27 15:22:34 +03:00
parent b0b5a68d2c
commit 8a06c7d074
4 changed files with 75 additions and 4 deletions

View File

@ -53,7 +53,7 @@ public class SecureChannel {
apdu.setOutgoingAndSend((short) 0, SC_SECRET_LENGTH);
}
public short decryptAPDU(byte[] apduBuffer) {
public byte decryptAPDU(byte[] apduBuffer) {
scCipher.init(scKey, Cipher.MODE_DECRYPT, apduBuffer, ISO7816.OFFSET_CDATA, SC_BLOCK_SIZE);
short len = scCipher.doFinal(apduBuffer, (short)(ISO7816.OFFSET_CDATA + SC_BLOCK_SIZE), (short) (apduBuffer[ISO7816.OFFSET_LC] - SC_BLOCK_SIZE), apduBuffer, ISO7816.OFFSET_CDATA);
@ -61,7 +61,9 @@ public class SecureChannel {
len--;
}
return (short) (len - 1);
apduBuffer[ISO7816.OFFSET_LC] = (byte) (len - 1);
return apduBuffer[ISO7816.OFFSET_LC];
}
public short encryptAPDU(byte[] apduBuffer, short len) {

View File

@ -88,9 +88,9 @@ public class WalletApplet extends Applet {
}
byte[] apduBuffer = apdu.getBuffer();
short len = secureChannel.decryptAPDU(apduBuffer);
byte len = secureChannel.decryptAPDU(apduBuffer);
if (!ownerPIN.check(apduBuffer, ISO7816.OFFSET_CDATA, (byte) len)) {
if (!ownerPIN.check(apduBuffer, ISO7816.OFFSET_CDATA, len)) {
ISOException.throwIt((short)((short) 0x63c0 | (short) ownerPIN.getTriesRemaining()));
}
}
@ -101,6 +101,16 @@ public class WalletApplet extends Applet {
if (!(secureChannel.isOpen() && ownerPIN.isValidated())) {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
}
byte[] apduBuffer = apdu.getBuffer();
byte len = secureChannel.decryptAPDU(apduBuffer);
if (!(len == 6 && allDigits(apduBuffer, ISO7816.OFFSET_CDATA, len))) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
ownerPIN.update(apduBuffer, ISO7816.OFFSET_CDATA, len);
ownerPIN.check(apduBuffer, ISO7816.OFFSET_CDATA, len);
}
private void unblockPIN(APDU apdu) {
@ -126,4 +136,18 @@ public class WalletApplet extends Applet {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
}
}
private boolean allDigits(byte[] buffer, short off, short len) {
while(len > 0) {
len--;
byte c = buffer[(short)(off+len)];
if (c < 0x30 || c > 0x39) {
return false;
}
}
return true;
}
}

View File

@ -35,4 +35,9 @@ public class WalletAppletCommandSet {
CommandAPDU verifyPIN = new CommandAPDU(0x80, WalletApplet.INS_VERIFY_PIN, 0, 0, secureChannel.encryptAPDU(pin.getBytes()));
return apduChannel.transmit(verifyPIN);
}
public ResponseAPDU changePIN(String pin) throws CardException {
CommandAPDU changePIN = new CommandAPDU(0x80, WalletApplet.INS_CHANGE_PIN, 0, 0, secureChannel.encryptAPDU(pin.getBytes()));
return apduChannel.transmit(changePIN);
}
}

View File

@ -95,4 +95,44 @@ public class WalletAppletTest {
//TODO: Unblock PIN to make the test non-destructive
}
@Test
@DisplayName("CHANGE PIN command")
void changePinTest() throws CardException {
ResponseAPDU response = cmdSet.changePIN("123456");
assertEquals(0x6985, response.getSW());
cmdSet.openSecureChannel();
response = cmdSet.changePIN("123456");
assertEquals(0x6985, response.getSW());
response = cmdSet.verifyPIN("000000");
assertEquals(0x9000, response.getSW());
response = cmdSet.changePIN("123456");
assertEquals(0x9000, response.getSW());
response = cmdSet.changePIN("654321");
assertEquals(0x9000, response.getSW());
apduChannel.getCard().getATR();
cmdSet.select();
cmdSet.openSecureChannel();
response = cmdSet.verifyPIN("654321");
assertEquals(0x9000, response.getSW());
response = cmdSet.changePIN("654a21");
assertEquals(0x6A80, response.getSW());
response = cmdSet.changePIN("54321");
assertEquals(0x6A80, response.getSW());
response = cmdSet.changePIN("7654321");
assertEquals(0x6A80, response.getSW());
response = cmdSet.changePIN("000000");
assertEquals(0x9000, response.getSW());
}
}