This commit is contained in:
Michele Balistreri 2018-12-14 12:04:30 +03:00
parent 73b73ffa3c
commit a33aae5ed5
4 changed files with 87 additions and 44 deletions

View File

@ -4,17 +4,6 @@ The project is built using Gradle with the [Fidesmo Javacard Gradle plugin](http
You can set the JavaCard HOME not only through the environment but also creating a gradle.properties file with the You can set the JavaCard HOME not only through the environment but also creating a gradle.properties file with the
property "com.fidesmo.gradle.javacard.home" set to the correct path. property "com.fidesmo.gradle.javacard.home" set to the correct path.
Loading and installing the applet requires [gpshell](https://sourceforge.net/p/globalplatform/wiki/GPShell/) to be
installed on the system. The gradle.properties file must contain the following properties
* im.status.gradle.gpshell = the path to the gpshell executable
* im.status.gradle.gpshell.isd = the AID of the issuer security domain
* im.status.gradle.gpshell.mac_key = the MAC key for the ISD
* im.status.gradle.gpshell.enc_key = the ENC key for the ISD
* im.status.gradle.gpshell.kek_key = the KEK key for the ISD
* im.status.gradle.gpshell.kvn = the Key Version Number for the ISD
* im.status.keycard.test.simulated = true if the test should run on the simulator, false (or anything else) otherwise
Testing is done with JUnit and performed either on a real card or on [jCardSim](https://github.com/status-im/jcardsim). Testing is done with JUnit and performed either on a real card or on [jCardSim](https://github.com/status-im/jcardsim).
Although the tests are comprehensive, debugging on the real card is not easy because raw APDUs are not shown in the test Although the tests are comprehensive, debugging on the real card is not easy because raw APDUs are not shown in the test
log and there is no way to set breakpoints in the applet. log and there is no way to set breakpoints in the applet.
@ -40,19 +29,6 @@ In order to test with the simulator with an IDE, you need to pass these addition
installed. For more information check [here](https://stackoverflow.com/questions/41580489/how-to-install-unlimited-strength-jurisdiction-policy-files). installed. For more information check [here](https://stackoverflow.com/questions/41580489/how-to-install-unlimited-strength-jurisdiction-policy-files).
3. Run `./gradlew test` 3. Run `./gradlew test`
## Example gradle.properties file
```
com.fidesmo.gradle.javacard.home=/home/username/javacard-3_0_4
im.status.gradle.gpshell=/usr/local/bin/gpshell
im.status.gradle.gpshell.isd=A000000151000000
im.status.gradle.gpshell.mac_key=404142434445464748494a4b4c4d4e4f
im.status.gradle.gpshell.enc_key=404142434445464748494a4b4c4d4e4f
im.status.gradle.gpshell.kek_key=404142434445464748494a4b4c4d4e4f
im.status.gradle.gpshell.kvn=0
im.status.keycard.test.simulated=false
```
## Implementation notes ## Implementation notes
* The applet requires JavaCard 3.0.4 (with the addition of KeyAgreement.ALG_EC_SVDP_DH_PLAIN_XY * The applet requires JavaCard 3.0.4 (with the addition of KeyAgreement.ALG_EC_SVDP_DH_PLAIN_XY

View File

@ -5,11 +5,13 @@ buildscript {
repositories { repositories {
maven { url 'http://releases.marmeladburk.fidesmo.com/' } maven { url 'http://releases.marmeladburk.fidesmo.com/' }
mavenCentral() mavenCentral()
maven { url 'https://jitpack.io' }
} }
dependencies { dependencies {
classpath 'com.fidesmo:gradle-javacard:0.2.7' classpath 'com.fidesmo:gradle-javacard:0.2.7'
classpath 'org.junit.platform:junit-platform-gradle-plugin:1.1.1' classpath 'org.junit.platform:junit-platform-gradle-plugin:1.1.1'
classpath 'com.github.status-im.status-keycard-java:desktop:2.0rc1'
} }
} }
@ -59,26 +61,7 @@ task wrapper(type: Wrapper) {
gradleVersion = '4.7' gradleVersion = '4.7'
} }
task install(type: Exec) { task install (type: im.status.keycard.build.InstallTask)
def gpShellScript = """
mode_211
enable_trace
establish_context
card_connect
select -AID ${project.properties['im.status.gradle.gpshell.isd']}
open_sc -security 1 -keyind 0 -keyver ${project.properties['im.status.gradle.gpshell.kvn']} -mac_key ${project.properties['im.status.gradle.gpshell.mac_key']} -enc_key ${project.properties['im.status.gradle.gpshell.enc_key']} -kek_key ${project.properties['im.status.gradle.gpshell.kek_key']}
send_apdu_nostop -sc 1 -APDU 80E400800E4F0C53746174757357616C6C6574
install_for_load -pkgAID 53746174757357616C6C6574
load -file build/javacard/im/status/keycard/javacard/keycard.cap
install_for_install -AID 53746174757357616C6C6574417070 -pkgAID 53746174757357616C6C6574 -instAID 53746174757357616C6C6574417070
install_for_install -AID 53746174757357616C6C65744e4643 -pkgAID 53746174757357616C6C6574 -instAID D2760000850101
card_disconnect
release_context
"""
executable project.properties['im.status.gradle.gpshell']
standardInput new ByteArrayInputStream(gpShellScript.getBytes("UTF-8"))
}
if (project.properties['im.status.keycard.test.simulated'] != 'true') { if (project.properties['im.status.keycard.test.simulated'] != 'true') {
tasks.install.dependsOn(convertJavacard) tasks.install.dependsOn(convertJavacard)

8
buildSrc/build.gradle Normal file
View File

@ -0,0 +1,8 @@
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
dependencies {
compile 'com.github.status-im.status-keycard-java:desktop:2.0rc1'
}

View File

@ -0,0 +1,76 @@
package im.status.keycard.build;
import im.status.keycard.desktop.PCSCCardChannel;
import im.status.keycard.globalplatform.GlobalPlatformCommandSet;
import im.status.keycard.globalplatform.LoadCallback;
import im.status.keycard.io.APDUException;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.logging.Logger;
import org.gradle.api.tasks.TaskAction;
import javax.smartcardio.*;
import java.io.FileInputStream;
import java.io.IOException;
public class InstallTask extends DefaultTask {
@TaskAction
public void install() {
Logger logger = getLogger();
TerminalFactory tf = TerminalFactory.getDefault();
CardTerminal cardTerminal = null;
try {
for (CardTerminal t : tf.terminals().list()) {
if (t.isCardPresent()) {
cardTerminal = t;
break;
}
}
} catch(CardException e) {
throw new GradleException("Error listing card terminals", e);
}
if (cardTerminal == null) {
throw new GradleException("No available PC/SC terminal");
}
Card apduCard;
try {
apduCard = cardTerminal.connect("*");
} catch(CardException e) {
throw new GradleException("Couldn't connect to the card", e);
}
logger.info("Connected to " + cardTerminal.getName());
PCSCCardChannel sdkChannel = new PCSCCardChannel(apduCard.getBasicChannel());
GlobalPlatformCommandSet cmdSet = new GlobalPlatformCommandSet(sdkChannel);
try {
logger.info("Selecting the ISD");
cmdSet.select().checkOK();
logger.info("Opening a SecureChannel");
cmdSet.openSecureChannel();
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() {
@Override
public void blockLoaded(int loadedBlock, int blockCount) {
logger.info("Loaded block " + loadedBlock + "/" + blockCount);
}
});
logger.info("Installing the Keycard Applet");
cmdSet.installKeycardApplet();
logger.info("Installing the NDEF Applet");
cmdSet.installNDEFApplet(new byte[0]);
} catch (IOException e) {
throw new GradleException("I/O error", e);
} catch (APDUException e) {
throw new GradleException(e.getMessage(), e);
}
}
}