-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit c731d28
Showing
24 changed files
with
5,270 additions
and
0 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,26 @@ | ||
language: java | ||
|
||
env: | ||
- JC_HOME=$TRAVIS_BUILD_DIR/jckit/java_card_kit-2_2_2 | ||
|
||
before_script: | ||
- mkdir jckit | ||
- cd jckit | ||
- "[ -f java_card_kit-2_2_2-linux.zip ] || curl -L http://download.oracle.com/otn-pub/java/java_card_kit/2.2.2/java_card_kit-2_2_2-linux.zip -o java_card_kit-2_2_2-linux.zip --cookie oraclelicense=accept-securebackup-cookie" | ||
- unzip java_card_kit-2_2_2-linux.zip | ||
- cd java_card_kit-2_2_2/ | ||
- unzip java_card_kit-2_2_2-rr-bin-linux-do.zip | ||
- cd ../.. | ||
- mkdir ext | ||
- cd ext | ||
- mkdir ant | ||
- cd ant | ||
- "[ -f ant-javacard.jar ] || curl -L https://github.com/martinpaljak/ant-javacard/releases/download/v1.3/ant-javacard.jar -o ant-javacard.jar" | ||
- cd ../.. | ||
- CLASSPATH=$CLASSPATH:$JC_HOME/lib | ||
|
||
script: ant dist | ||
|
||
cache: | ||
files: | ||
- $TRAVIS_BUILD_DIR/java_card_kit-2_2_2-linux.zip |
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,19 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project name="Gids Applet" default="dist" basedir="."> | ||
<description>Builds the project. </description> | ||
<target name="dist" description="generate the distribution"> | ||
<tstamp/> | ||
|
||
<!-- Create the distribution directory --> | ||
<taskdef name="javacard" classname="pro.javacard.ant.JavaCard" classpath="ext/ant/ant-javacard.jar"/> | ||
<javacard> | ||
<cap aid="A0:00:00:03:97:42:54:46:59" output="GidsApplet.cap" sources="src/com/mysmartlogon/gidsApplet" version="1.0"> | ||
<applet class="com.mysmartlogon.gidsApplet.GidsApplet" aid="A0:00:00:03:97:42:54:46:59:02:01"/> | ||
</cap> | ||
</javacard> | ||
</target> | ||
<target name="clean" description="clean up"> | ||
<!-- Delete the built applet --> | ||
<delete dir="GidsApplet.cap"/> | ||
</target> | ||
</project> |
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,73 @@ | ||
package com.mysmartlogon.gidsApplet; | ||
|
||
import javacard.framework.Util; | ||
|
||
public class ApplicationFile extends DedicatedFile { | ||
|
||
|
||
byte[] fileControlInformation = null; | ||
byte[] fileManagementData = null; | ||
public ApplicationFile(short fileID, byte[] fileControlParameter, byte[] fileControlInformation, byte[] fileManagementData) { | ||
super(fileID, fileControlParameter); | ||
this.fileControlInformation = fileControlInformation; | ||
this.fileManagementData = fileManagementData; | ||
} | ||
|
||
/** | ||
* \brief Check if this is the AID of the application | ||
* | ||
* \param name The array containing the name to compare with the file's name. | ||
* | ||
* \param offset The offset at where the name begins. | ||
* | ||
* \param length The length of the name. | ||
* | ||
* \return false if the DF has no name or the names do not match, | ||
* true else. | ||
*/ | ||
public boolean isName(byte[] name, short offset, short length) { | ||
short namePos; | ||
short aidlen = 0; | ||
short i; | ||
// Find the position of the AID tag (4F) in the fci. | ||
try { | ||
namePos = UtilTLV.findTag(fileControlInformation, (short)2, fileControlInformation[(short)1], (byte) 0x4F); | ||
} catch (NotFoundException e) { | ||
// This DF has no name. | ||
return false; | ||
} catch (InvalidArgumentsException e) { | ||
return false; | ||
} | ||
// This ADF has a AID. | ||
try { | ||
aidlen = UtilTLV.decodeLengthField(fileControlInformation, (short)(namePos+1)); | ||
if (aidlen < length) { | ||
// aid len to check is to big to match | ||
return false; | ||
} | ||
} catch (InvalidArgumentsException e) { | ||
return false; | ||
} | ||
// Advance namePos from "tag" to value. | ||
try { | ||
namePos += 1 + UtilTLV.getEncodingLengthFieldLength(length); | ||
} catch(InvalidArgumentsException e) { | ||
return false; | ||
} | ||
// check if the name can be a part of the AID | ||
for (i = 0; i < (short)(aidlen - length +1); i++) { | ||
if ((byte)0 == Util.arrayCompare(name, offset, fileControlInformation, (short)(namePos + i), length) ) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
public byte[] getFileManagementData() { | ||
return fileManagementData; | ||
} | ||
|
||
public byte[] getFileControlInformation() { | ||
return fileControlInformation; | ||
} | ||
} |
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,185 @@ | ||
package com.mysmartlogon.gidsApplet; | ||
|
||
import javacard.framework.JCSystem; | ||
import javacard.framework.Util; | ||
|
||
public class BerTlvFile extends ElementaryFile { | ||
|
||
private static final short ELEMENT_COUNT_START = 10; | ||
private static final short ELEMENT_COUNT_MAX = 30; // set to max. 16383 | ||
|
||
private Record[] children; | ||
private byte currentNumChildren; | ||
|
||
/** | ||
* \brief Instantiate a new BER-TLV EF. No data is being added at this point. | ||
* | ||
* \param fileControlInformation The array of bytes containing the valid (!) File Control Information. | ||
* It must contain the File ID (Tag 83). No Copy is made. | ||
* | ||
* \param maxRecords The maximum amount of saved records. | ||
* | ||
* \attention No copy of the FCI is made. Do not pass any buffer that is altered | ||
* later (e.g. the apdu buffer). Max length 257 bytes as the length | ||
* of the FCI Tag (6F) must be a byte. | ||
* | ||
* \attention To be safe, use IsoFileSystem.getSafeFile() to instantiate files. | ||
* | ||
* \throw IllegalArgumentException If necessary tags in the FCI are missing. | ||
*/ | ||
public BerTlvFile(short fileID, byte[] fileControlInformation) { | ||
super(fileID, fileControlInformation); | ||
this.children = new Record[ELEMENT_COUNT_START]; | ||
this.currentNumChildren = 0; | ||
} | ||
|
||
@Override | ||
void clearContents() { | ||
short i; | ||
|
||
for(i = 0; i < currentNumChildren; i++) { | ||
children[i].clearContents(); | ||
children[i] = null; | ||
} | ||
|
||
} | ||
|
||
/** | ||
* \brief Delete a DO | ||
* | ||
* This method requests garbage collection. | ||
* | ||
* \param childNum internal index | ||
*/ | ||
protected void deleteChildren(short childNum) { | ||
|
||
children[childNum] = null; | ||
currentNumChildren--; // We have one less children now. | ||
|
||
// Fill up empty field in children array. | ||
// The last children is one ahead, so it is at currentNumChildren. | ||
if(childNum < currentNumChildren) { | ||
children[childNum] = children[currentNumChildren]; | ||
} | ||
|
||
// Clean up the old file object. | ||
if(JCSystem.isObjectDeletionSupported()) { | ||
JCSystem.requestObjectDeletion(); | ||
} | ||
} | ||
|
||
/** | ||
* \brief remove a DO | ||
* | ||
* \param children The children to add. | ||
* | ||
* \throw NotEnoughSpaceException If CHILDREN_COUNT_MAX is reached. | ||
* @param size | ||
* @param offset_cdata | ||
*/ | ||
public Record addChildren(byte[] buffer, short offset, short wholelength, short lengthavailable) throws NotEnoughSpaceException { | ||
// try to find a previous TLV | ||
short i; | ||
short lengthToCopy = (lengthavailable > wholelength ? wholelength: lengthavailable); | ||
for(i = 0; i < currentNumChildren; i++) { | ||
byte[] value = children[i].GetData(); | ||
|
||
if (UtilTLV.IsBERTLVTagEqual(buffer, offset, (short) (offset + lengthavailable), value)) { | ||
// found => replace or erase ? | ||
|
||
// erase if empty DO pushed and already empty DO stored | ||
short oldlen = UtilTLV.GetBERTLVDataLen(value, (short) 0, (short) value.length); | ||
short newlen = UtilTLV.GetBERTLVDataLen(buffer, offset, (short) (offset + lengthavailable)); | ||
if (oldlen == 0) { | ||
if (newlen == 0) { | ||
deleteChildren(i); | ||
return null; | ||
} | ||
} | ||
// replace | ||
if (oldlen == newlen) { | ||
// no need to add / remove data, just replace the buffer | ||
Util.arrayCopyNonAtomic(buffer, offset, value, (short) 0, lengthToCopy); | ||
} else { | ||
// remove previous data, add new | ||
byte[] data = new byte[wholelength]; | ||
Util.arrayCopyNonAtomic(buffer, offset, data, (short) 0, lengthToCopy); | ||
children[i] = null; | ||
if(JCSystem.isObjectDeletionSupported()) { | ||
JCSystem.requestObjectDeletion(); | ||
} | ||
children[i] = new Record(data); | ||
} | ||
return children[i]; | ||
} | ||
|
||
} | ||
|
||
|
||
// First we have to check for enough space. | ||
if(currentNumChildren >= (short)children.length) { | ||
Record[] newChildren = null; | ||
// The array is full - we try to increase the size. | ||
if((short)(children.length * 2) <= ELEMENT_COUNT_MAX) { | ||
// Doubling the size is possible. | ||
newChildren = new Record[(short)(children.length * 2)]; | ||
copyFileArrayRefs(children, newChildren); | ||
} else { | ||
// Doubling not possible - try to at least increase to CHILDREN_COUNT_MAX. | ||
if(currentNumChildren < ELEMENT_COUNT_MAX) { | ||
newChildren = new Record[ELEMENT_COUNT_MAX]; | ||
copyFileArrayRefs(children, newChildren); | ||
} else { | ||
// CHILDREN_COUNT_MAX exceeded. No "space" left. Fail. | ||
throw NotEnoughSpaceException.getInstance(); | ||
} | ||
} | ||
children = newChildren; // Initial children array is now garbage. | ||
if(JCSystem.isObjectDeletionSupported()) { | ||
JCSystem.requestObjectDeletion(); | ||
} | ||
} // We have enough space (now). | ||
byte[] data = new byte[wholelength]; | ||
Util.arrayCopyNonAtomic(buffer, offset, data, (short) 0, lengthToCopy); | ||
children[currentNumChildren++] = new Record(data); | ||
return children[(short) (currentNumChildren-1)]; | ||
} | ||
|
||
/** | ||
* \brief Copies the references from one File array to the other. | ||
* | ||
* \attention Although only references are copied, this is probably still quite expensive because | ||
* writing to the EEPROM is. Only use this for operations that are not called often (Creating and deleting files etc.). | ||
* | ||
* \param src The source File array to copy from. | ||
* | ||
* \param dest The destination File array to copy to. It MUST be at least of size of the src array. | ||
*/ | ||
private static void copyFileArrayRefs(Record[] src, Record[] dest) { | ||
short i = 0; | ||
short length = src.length > dest.length ? (short)dest.length : (short)src.length; | ||
|
||
for(i=0; i < length; i++) { | ||
dest[i] = src[i]; | ||
} | ||
return; | ||
} | ||
|
||
public Record getData(byte[] tag, short offset, short len) throws NotFoundException { | ||
short i; | ||
|
||
for(i = 0; i < currentNumChildren; i++) { | ||
byte[] value = children[i].GetData(); | ||
if(UtilTLV.IsBERTLVTagEqual(tag, offset, len, value)) { | ||
return children[i]; | ||
} | ||
} | ||
|
||
throw NotFoundException.getInstance(); | ||
} | ||
|
||
public Record[] getAllData() { | ||
return children; | ||
} | ||
|
||
} |
Oops, something went wrong.