Skip to content

Commit

Permalink
Merge pull request #28 from fidesmo/feature-support-android-reader
Browse files Browse the repository at this point in the history
Add support for android phones as card reader
  • Loading branch information
slomo committed Dec 2, 2015
2 parents 0c71c1d + e38be7e commit 43d6d16
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 15 deletions.
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ Features
* upload executable load file to the Fidesmo server [^1]
* install applet to Fidesmo card [^1]
* delete applet from Fidesmo card [^1]
* send and receives APDUs
* send and receives APDUs with CLI
* **experimental**: use phone as card reader

[^1]: These features interact with the fidesmo server, hence a working internet connection and a
[fidesmo developer account](https://developer.fidesmo.com)(free of charge) is required.
Expand Down Expand Up @@ -77,6 +78,28 @@ command:
This will take the first defined applet and create an instance of on the card with the same aid as
the applet.

Android phone as card reader
----------------------------

The app can also use an usb attached android phone instead of a card
reader. It requires the android platform tools (adb) on the computer
and the Fidesmo Android App on the phone.

In order to install your cardlet via the phone:

1. Enable developer mode of Fidesmo Android App
2. Start *Card reader mode* from main menu
3. Place card on the back of the phone
4. Run the following commands

export ANDROID_HOME=/.../path/to/android/tools
./gradlew installToLocalCard -P fidesmo.adb_reader


5. Run more operations commands

./gradlew deleteFromLocalCard -P fidesmo.adb_reader

Console
-------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class FidesmoPlugin implements Plugin<Project> {

project.tasks.create('deleteFromLocalCard', OperationTask) {
group = 'publish'
description = 'Deletes the executable load file from the fidesm card via a locally attached card reader'
description = 'Deletes the executable load file from the fidesm card via a locally attached card reader or android phone'

doLast {
// TODO: should be inputs of the task
Expand All @@ -86,7 +86,7 @@ class FidesmoPlugin implements Plugin<Project> {
def installToLocalCard = { encryptLoad ->
{ task ->
task.group = 'publish'
task.description = 'Installs the executable load file to fidesmo card via a locally attached card reader'
task.description = 'Installs the executable load file to fidesmo card via a locally attached card reader or android phone'
task.dependsOn(project.uploadExecutableLoadFile)
task.dependsOn(project.deleteFromLocalCard)

Expand Down
36 changes: 24 additions & 12 deletions src/main/groovy/com/fidesmo/gradle/plugin/OperationTask.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,31 @@ class OperationTask extends FidesmoBaseTask {

def executeOperation(UUID operationId) {

// execute operation by implementing sec-client flow
def client = (new OperationClientImpl()).get(
operationId,
(Transceiver) new SmartcardioTransceiver(),
RetrofitSecClient.client
)
client.transceive().toBlocking().last()
/* semantically both options differ. On android after return
* the operation has been started, locally the last apdu was
* already send.
*/
if (project.hasProperty('fidesmo.adb_reader')) {
// call activity (and therefore sec-client) on android phone
def android_home = System.env.ANDROID_HOME
def cmd = "${android_home}/platform-tools/adb shell " +
"am start -W " +
"--es descriptionExtra 'Run `${name}` task' " +
"--es operationIdExtra '${operationId}' " +
"com.fidesmo.sec.android/.ui.OperationActivity_"
def proc = cmd.execute()
proc.waitFor()
} else {
// execute operation by implementing sec-client flow
def client = (new OperationClientImpl()).get(
operationId,
(Transceiver) new SmartcardioTransceiver(),
RetrofitSecClient.client)
client.transceive().toBlocking().last()
}

// check operation result by querying the status service
int maxRetries = 9
int maxRetries = 30
for(int i = 0; i <= maxRetries; i ++) { // try ten times
try {
def response = fidesmoService.getStatus(operationId)
Expand All @@ -58,12 +73,11 @@ class OperationTask extends FidesmoBaseTask {
if (i == maxRetries || retrofitError?.response?.status != 404) {
throw new Exception("Unable to determine out come of operation", retrofitError)
} else {
sleep(100)
sleep(1000)
logger.info("Failed to fetch operation result for ${operationId} retrying ${i+1}/${maxRetries}")
}
}
}

}


Expand Down Expand Up @@ -100,6 +114,4 @@ class OperationTask extends FidesmoBaseTask {

restAdapter.create(FidesmoService.class)
}


}

0 comments on commit 43d6d16

Please sign in to comment.