Added functionality to retrieve status of password and reset password with VERIFY command
This commit is contained in:
parent
53fcff53f8
commit
5db38b3d31
|
|
@ -4,10 +4,16 @@ This is a Java Card implementation of the OpenPGP smart card specifications.
|
|||
|
||||
# Building
|
||||
|
||||
`git submodule init ext/oracle_javacard_sdks`
|
||||
`git submodule update --init --recursive`
|
||||
|
||||
`ant`
|
||||
|
||||
# Testing
|
||||
|
||||
`ant test`
|
||||
|
||||
# Installing
|
||||
|
||||
This can easily be done using GlobalPlatformPro (https://github.com/martinpaljak/GlobalPlatformPro):
|
||||
|
||||
`java -jar gp.jar -install openpgpcard.cap`
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ public class OpenPGPApplet extends Applet implements ISO7816 {
|
|||
|
||||
// VERIFY
|
||||
case (byte) 0x20:
|
||||
verify(apdu, p2);
|
||||
verify(apdu, p2, p1);
|
||||
break;
|
||||
|
||||
// CHANGE REFERENCE DATA
|
||||
|
|
@ -400,6 +400,17 @@ public class OpenPGPApplet extends Applet implements ISO7816 {
|
|||
in_received = 0;
|
||||
}
|
||||
|
||||
private OwnerPIN getPIN(byte mode) {
|
||||
OwnerPIN pw = pw1;
|
||||
if (mode == (byte) 0x81 || mode == (byte) 0x82) {
|
||||
pw = pw1;
|
||||
} else if (mode == (byte) 0x83) {
|
||||
pw = pw3;
|
||||
} else {
|
||||
ISOException.throwIt(SW_INCORRECT_P1P2);
|
||||
}
|
||||
return pw;
|
||||
}
|
||||
/**
|
||||
* Provide the VERIFY command (INS 20)
|
||||
*
|
||||
|
|
@ -410,34 +421,61 @@ public class OpenPGPApplet extends Applet implements ISO7816 {
|
|||
* @param mode
|
||||
* Password and mode to be verified
|
||||
*/
|
||||
private void verify(APDU apdu, byte mode) {
|
||||
if (mode == (byte) 0x81 || mode == (byte) 0x82) {
|
||||
// Check length of input
|
||||
if (in_received < PW1_MIN_LENGTH || in_received > PW1_MAX_LENGTH)
|
||||
ISOException.throwIt(SW_WRONG_LENGTH);
|
||||
private void verify(APDU apdu, byte mode, byte action) {
|
||||
if(in_received == 0) {
|
||||
// Select correct PIN
|
||||
OwnerPIN pw = getPIN(mode);
|
||||
|
||||
// Check given PW1 and set requested mode if verified succesfully
|
||||
if (pw1.check(buffer, _0, (byte) in_received)) {
|
||||
if (mode == (byte) 0x81)
|
||||
pw1_modes[PW1_MODE_NO81] = true;
|
||||
else
|
||||
pw1_modes[PW1_MODE_NO82] = true;
|
||||
} else {
|
||||
ISOException
|
||||
.throwIt((short) (0x63C0 | pw1.getTriesRemaining()));
|
||||
}
|
||||
} else if (mode == (byte) 0x83) {
|
||||
// Check length of input
|
||||
if (in_received < PW3_MIN_LENGTH || in_received > PW3_MAX_LENGTH)
|
||||
ISOException.throwIt(SW_WRONG_LENGTH);
|
||||
|
||||
// Check PW3
|
||||
if (!pw3.check(buffer, _0, (byte) in_received)) {
|
||||
ISOException
|
||||
.throwIt((short) (0x63C0 | pw3.getTriesRemaining()));
|
||||
if (action == 0x00) {
|
||||
// Status for password requested
|
||||
if(pw.isValidated()) {
|
||||
// Return 9000 if password is still valid
|
||||
ISOException.throwIt(SW_NO_ERROR);
|
||||
} else {
|
||||
// Return remaining number of tries otherwise
|
||||
ISOException
|
||||
.throwIt((short) (0x63C0 | pw.getTriesRemaining()));
|
||||
}
|
||||
} else if (action == (byte)0xFF) {
|
||||
// Reset PIN
|
||||
pw.reset();
|
||||
|
||||
// For PW1 also reset PW1 mode
|
||||
if (mode == (byte) 0x81 || mode == (byte) 0x82) {
|
||||
pw1_modes[PW1_MODE_NO81] = false;
|
||||
pw1_modes[PW1_MODE_NO82] = false;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
ISOException.throwIt(SW_INCORRECT_P1P2);
|
||||
if (mode == (byte) 0x81 || mode == (byte) 0x82) {
|
||||
// Check length of input
|
||||
if (in_received < PW1_MIN_LENGTH || in_received > PW1_MAX_LENGTH)
|
||||
ISOException.throwIt(SW_WRONG_LENGTH);
|
||||
|
||||
// Check given PW1 and set requested mode if verified succesfully
|
||||
if (pw1.check(buffer, _0, (byte) in_received)) {
|
||||
if (mode == (byte) 0x81)
|
||||
pw1_modes[PW1_MODE_NO81] = true;
|
||||
else
|
||||
pw1_modes[PW1_MODE_NO82] = true;
|
||||
} else {
|
||||
ISOException
|
||||
.throwIt((short) (0x63C0 | pw1.getTriesRemaining()));
|
||||
}
|
||||
} else if (mode == (byte) 0x83) {
|
||||
// Check length of input
|
||||
if (in_received < PW3_MIN_LENGTH || in_received > PW3_MAX_LENGTH)
|
||||
ISOException.throwIt(SW_WRONG_LENGTH);
|
||||
|
||||
// Check PW3
|
||||
if (!pw3.check(buffer, _0, (byte) in_received)) {
|
||||
ISOException
|
||||
.throwIt((short) (0x63C0 | pw3.getTriesRemaining()));
|
||||
}
|
||||
} else {
|
||||
ISOException.throwIt(SW_INCORRECT_P1P2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,32 @@ public class OpenPGPAppletTest {
|
|||
new byte[] { 0x00, 0x20, 0x00, (byte) 0x81, 0x06, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 });
|
||||
assertArrayEquals(new byte[] { (byte) 0x63, (byte) 0xc0 }, response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_userPINStatus() {
|
||||
byte[] response = simulator.transmitCommand(
|
||||
new byte[] { 0x00, 0x20, 0x00, (byte) 0x81, 0x06, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31 });
|
||||
assertArrayEquals(new byte[] { (byte) 0x63, (byte) 0xc2 }, response);
|
||||
response = simulator.transmitCommand(
|
||||
new byte[] { 0x00, 0x20, 0x00, (byte) 0x81, 0x00 });
|
||||
assertArrayEquals(new byte[] { (byte) 0x63, (byte) 0xc2 }, response);
|
||||
|
||||
// Verify correct password
|
||||
response = simulator.transmitCommand(
|
||||
new byte[] { 0x00, 0x20, 0x00, (byte) 0x81, 0x06, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 });
|
||||
assertArrayEquals(new byte[] { (byte) 0x90, 0x00 }, response);
|
||||
response = simulator.transmitCommand(
|
||||
new byte[] { 0x00, 0x20, 0x00, (byte) 0x81, 0x00 });
|
||||
assertArrayEquals(new byte[] { (byte) 0x90, (byte) 0x00 }, response);
|
||||
|
||||
// Invalidate correctly verified password
|
||||
response = simulator.transmitCommand(
|
||||
new byte[] { 0x00, 0x20, (byte)0xFF, (byte) 0x81, 0x00 });
|
||||
assertArrayEquals(new byte[] { (byte) 0x90, (byte) 0x00 }, response);
|
||||
response = simulator.transmitCommand(
|
||||
new byte[] { 0x00, 0x20, 0x00, (byte) 0x81, 0x00 });
|
||||
assertArrayEquals(new byte[] { (byte) 0x63, (byte) 0xc3 }, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reset of PIN try counter by first verifying a wrong PIN, followed by
|
||||
|
|
|
|||
Loading…
Reference in New Issue