forked from LedgerHQ/ledger-u2f-javacard
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New Counter/Presence Classes, Minor Refactor
This commit primarily does two things: * Moves the counter logic out of `U2FApplet` and into its own class, `Counter`. This will allow it to be more easily refactored in the future. * Moves the user presence logic out of `U2FApplet`, creating a new interface called `Presence`. This will make it easier to implement devices which have a button for testing presence. Two implementations are provided: `OneShotPresence` (the default) and `NullPresence` (used when the install flags are set to 0x01). The functionality should be completely identical at this point, but the code should be easier to maintain and read.
- Loading branch information
1 parent
8b58c4c
commit 563e31b
Showing
5 changed files
with
148 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package com.ledger.u2f; | ||
|
||
import javacard.framework.ISO7816; | ||
import javacard.framework.ISOException; | ||
import javacard.framework.JCSystem; | ||
import javacard.framework.Util; | ||
|
||
/** | ||
* Simple incrementing counter. | ||
* | ||
* This class implements a simple unsigned 32-bit counter | ||
* that always counts up and cannot be decremented. Once | ||
* it reaches the value 0xFFFFFFFF, all future operations | ||
* throw ISOException with a value of ISO7816.SW_FILE_FULL. | ||
* | ||
* TODO: This should be rewritten to improve flash wear | ||
* leveling behavior and device longevity. | ||
*/ | ||
public class Counter { | ||
private byte[] counter; | ||
private boolean overflow; | ||
|
||
Counter() { | ||
counter = new byte[4]; | ||
overflow = false; | ||
} | ||
|
||
public void inc() { | ||
boolean carry = false; | ||
|
||
if (overflow) { | ||
// Game over | ||
ISOException.throwIt(ISO7816.SW_FILE_FULL); | ||
} | ||
|
||
JCSystem.beginTransaction(); | ||
|
||
for (byte i=0; i<4; i++) { | ||
short addValue = (i == 0 ? (short)1 : (short)0); | ||
short val = (short)((short)(counter[(short)(4 - 1 - i)] & 0xff) + addValue); | ||
if (carry) { | ||
val++; | ||
} | ||
carry = (val > 255); | ||
counter[(short)(4 - 1 - i)] = (byte)val; | ||
} | ||
|
||
if (carry) { | ||
// Game over | ||
overflow = true; | ||
} | ||
|
||
JCSystem.commitTransaction(); | ||
|
||
if (overflow) { | ||
ISOException.throwIt(ISO7816.SW_FILE_FULL); | ||
} | ||
} | ||
|
||
public short writeValue(byte[] dest, short destOffset) { | ||
if (overflow) { | ||
ISOException.throwIt(ISO7816.SW_FILE_FULL); | ||
} | ||
return Util.arrayCopyNonAtomic(counter, (short)0, dest, destOffset, (short)4); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.ledger.u2f; | ||
|
||
/** | ||
* Null user presence detection. | ||
* Suitable for testing only. | ||
*/ | ||
public class NullPresence implements Presence { | ||
@Override | ||
public void verify_user_presence() { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.ledger.u2f; | ||
|
||
import javacard.framework.ISO7816; | ||
import javacard.framework.ISOException; | ||
import javacard.framework.JCSystem; | ||
|
||
/** | ||
* User presence detection that works based on the | ||
* presentation of the token rather than an interaction | ||
* with the token. | ||
* | ||
* This means that, for a presented token, | ||
* only a single operation requiring user presence can | ||
* be performed until the card is reset. | ||
* | ||
* This is suitable for NFC-based authenticators, and | ||
* USB authenticators that don't have buttons. | ||
* | ||
* Note that in many cases the card can be reset by | ||
* software without any physical user action, rendering | ||
* this protection moot. Without a physical button this | ||
* is the best that can be done. | ||
*/ | ||
public class OneShotPresence implements Presence { | ||
private byte[] did_verify_flag; | ||
|
||
OneShotPresence() { | ||
did_verify_flag = JCSystem.makeTransientByteArray((short)1, JCSystem.CLEAR_ON_RESET); | ||
} | ||
|
||
@Override | ||
public void verify_user_presence() { | ||
if (did_verify_flag[0] != 0) { | ||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); | ||
} | ||
did_verify_flag[0] = 1; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.ledger.u2f; | ||
|
||
public interface Presence { | ||
|
||
void verify_user_presence(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters