Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add optional PIN/PUK retry count in INIT #63

Merged
merged 2 commits into from
Dec 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
# Gradle output
/.gradle
/build
/gradle.properties
/gradle.properties
buildSrc/build
buildSrc/.gradle
6 changes: 1 addition & 5 deletions 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 Expand Up @@ -68,10 +68,6 @@ test {
}
}

task wrapper(type: Wrapper) {
gradleVersion = '4.7'
}

task install (type: im.status.keycard.build.InstallTask)

if (testTarget == 'card') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public void install() {
logger.info("Deleting the old instances and package (if present)");
cmdSet.deleteKeycardInstancesAndPackage();
logger.info("Loading the new package");
cmdSet.loadKeycardPackage(new FileInputStream("build/javacard/im/status/keycard/javacard/keycard.cap"), new LoadCallback() {
cmdSet.loadKeycardPackage(new FileInputStream(this.getProject().file("build/javacard/im/status/keycard/javacard/keycard.cap")), new LoadCallback() {
@Override
public void blockLoaded(int loadedBlock, int blockCount) {
logger.info("Loaded block " + loadedBlock + "/" + blockCount);
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
2 changes: 1 addition & 1 deletion gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m"'

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
Expand Down
2 changes: 1 addition & 1 deletion gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DEFAULT_JVM_OPTS="-Xmx64m"

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
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