Skip to content

Commit

Permalink
add optional PIN/PUK retry count in INIT
Browse files Browse the repository at this point in the history
  • Loading branch information
bitgamma committed Dec 8, 2021
1 parent f420fd9 commit 6a40687
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 8 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ javacard {
aid = '0xA0:0x00:0x00:0x08:0x04:0x00:0x01:0x03'
className = 'CashApplet'
}
version = '3.0'
version = '3.1'
}
}

Expand Down
37 changes: 30 additions & 7 deletions src/main/java/im/status/keycard/KeycardApplet.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import javacard.framework.*;
import javacard.security.*;
import javacardx.crypto.Cipher;

import static javacard.framework.ISO7816.OFFSET_P1;

Expand Down Expand Up @@ -30,10 +29,15 @@ public class KeycardApplet extends Applet {

static final short SW_REFERENCED_DATA_NOT_FOUND = (short) 0x6A88;

static final byte PIN_MIN_RETRIES = 2;
static final byte PIN_MAX_RETRIES = 10;
static final byte PUK_MIN_RETRIES = 3;
static final byte PUK_MAX_RETRIES = 12;

static final byte PUK_LENGTH = 12;
static final byte PUK_MAX_RETRIES = 5;
static final byte DEFAULT_PUK_MAX_RETRIES = 5;
static final byte PIN_LENGTH = 6;
static final byte PIN_MAX_RETRIES = 3;
static final byte DEFAULT_PIN_MAX_RETRIES = 3;
static final byte KEY_PATH_MAX_DEPTH = 10;
static final byte PAIRING_MAX_CLIENT_COUNT = 5;
static final byte UID_LENGTH = 16;
Expand Down Expand Up @@ -326,17 +330,36 @@ private void processInit(APDU apdu) {
} else if (apduBuffer[ISO7816.OFFSET_INS] == INS_INIT) {
secureChannel.oneShotDecrypt(apduBuffer);

if ((apduBuffer[ISO7816.OFFSET_LC] != (byte)(PIN_LENGTH + PUK_LENGTH + SecureChannel.SC_SECRET_LENGTH)) || !allDigits(apduBuffer, ISO7816.OFFSET_CDATA, (short)(PIN_LENGTH + PUK_LENGTH))) {
byte defaultLimitsLen = (byte)(PIN_LENGTH + PUK_LENGTH + SecureChannel.SC_SECRET_LENGTH);
byte withLimitsLen = (byte) (defaultLimitsLen + 2);

if (((apduBuffer[ISO7816.OFFSET_LC] != defaultLimitsLen) && (apduBuffer[ISO7816.OFFSET_LC] != withLimitsLen)) || !allDigits(apduBuffer, ISO7816.OFFSET_CDATA, (short)(PIN_LENGTH + PUK_LENGTH))) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}

JCSystem.beginTransaction();
byte pinLimit;
byte pukLimit;

if (apduBuffer[ISO7816.OFFSET_LC] == withLimitsLen) {
pinLimit = apduBuffer[(short) (ISO7816.OFFSET_CDATA + defaultLimitsLen)];
pukLimit = apduBuffer[(short) (ISO7816.OFFSET_CDATA + defaultLimitsLen + 1)];

if (pinLimit < PIN_MIN_RETRIES || pinLimit > PIN_MAX_RETRIES || pukLimit < PUK_MIN_RETRIES || pukLimit > PUK_MAX_RETRIES) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}
} else {
pinLimit = DEFAULT_PIN_MAX_RETRIES;
pukLimit = DEFAULT_PUK_MAX_RETRIES;
}

secureChannel.initSecureChannel(apduBuffer, (short)(ISO7816.OFFSET_CDATA + PIN_LENGTH + PUK_LENGTH));

pin = new OwnerPIN(PIN_MAX_RETRIES, PIN_LENGTH);
JCSystem.beginTransaction();

pin = new OwnerPIN(pinLimit, PIN_LENGTH);
pin.update(apduBuffer, ISO7816.OFFSET_CDATA, PIN_LENGTH);

puk = new OwnerPIN(PUK_MAX_RETRIES, PUK_LENGTH);
puk = new OwnerPIN(pukLimit, PUK_LENGTH);
puk.update(apduBuffer, (short)(ISO7816.OFFSET_CDATA + PIN_LENGTH), PUK_LENGTH);

JCSystem.commitTransaction();
Expand Down

0 comments on commit 6a40687

Please sign in to comment.