closes #32
This commit is contained in:
parent
73b73ffa3c
commit
a33aae5ed5
24
README.md
24
README.md
|
@ -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
|
||||
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).
|
||||
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.
|
||||
|
@ -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).
|
||||
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
|
||||
|
||||
* The applet requires JavaCard 3.0.4 (with the addition of KeyAgreement.ALG_EC_SVDP_DH_PLAIN_XY
|
||||
|
|
23
build.gradle
23
build.gradle
|
@ -5,11 +5,13 @@ buildscript {
|
|||
repositories {
|
||||
maven { url 'http://releases.marmeladburk.fidesmo.com/' }
|
||||
mavenCentral()
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.fidesmo:gradle-javacard:0.2.7'
|
||||
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'
|
||||
}
|
||||
|
||||
task install(type: Exec) {
|
||||
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"))
|
||||
}
|
||||
task install (type: im.status.keycard.build.InstallTask)
|
||||
|
||||
if (project.properties['im.status.keycard.test.simulated'] != 'true') {
|
||||
tasks.install.dependsOn(convertJavacard)
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
repositories {
|
||||
mavenCentral()
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.github.status-im.status-keycard-java:desktop:2.0rc1'
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue