Skip to content

Commit c731d28

Browse files
committed
initial commit
0 parents  commit c731d28

24 files changed

+5270
-0
lines changed

.travis.yml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
language: java
2+
3+
env:
4+
- JC_HOME=$TRAVIS_BUILD_DIR/jckit/java_card_kit-2_2_2
5+
6+
before_script:
7+
- mkdir jckit
8+
- cd jckit
9+
- "[ -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"
10+
- unzip java_card_kit-2_2_2-linux.zip
11+
- cd java_card_kit-2_2_2/
12+
- unzip java_card_kit-2_2_2-rr-bin-linux-do.zip
13+
- cd ../..
14+
- mkdir ext
15+
- cd ext
16+
- mkdir ant
17+
- cd ant
18+
- "[ -f ant-javacard.jar ] || curl -L https://github.com/martinpaljak/ant-javacard/releases/download/v1.3/ant-javacard.jar -o ant-javacard.jar"
19+
- cd ../..
20+
- CLASSPATH=$CLASSPATH:$JC_HOME/lib
21+
22+
script: ant dist
23+
24+
cache:
25+
files:
26+
- $TRAVIS_BUILD_DIR/java_card_kit-2_2_2-linux.zip

build.xml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project name="Gids Applet" default="dist" basedir=".">
3+
<description>Builds the project. </description>
4+
<target name="dist" description="generate the distribution">
5+
<tstamp/>
6+
7+
<!-- Create the distribution directory -->
8+
<taskdef name="javacard" classname="pro.javacard.ant.JavaCard" classpath="ext/ant/ant-javacard.jar"/>
9+
<javacard>
10+
<cap aid="A0:00:00:03:97:42:54:46:59" output="GidsApplet.cap" sources="src/com/mysmartlogon/gidsApplet" version="1.0">
11+
<applet class="com.mysmartlogon.gidsApplet.GidsApplet" aid="A0:00:00:03:97:42:54:46:59:02:01"/>
12+
</cap>
13+
</javacard>
14+
</target>
15+
<target name="clean" description="clean up">
16+
<!-- Delete the built applet -->
17+
<delete dir="GidsApplet.cap"/>
18+
</target>
19+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.mysmartlogon.gidsApplet;
2+
3+
import javacard.framework.Util;
4+
5+
public class ApplicationFile extends DedicatedFile {
6+
7+
8+
byte[] fileControlInformation = null;
9+
byte[] fileManagementData = null;
10+
public ApplicationFile(short fileID, byte[] fileControlParameter, byte[] fileControlInformation, byte[] fileManagementData) {
11+
super(fileID, fileControlParameter);
12+
this.fileControlInformation = fileControlInformation;
13+
this.fileManagementData = fileManagementData;
14+
}
15+
16+
/**
17+
* \brief Check if this is the AID of the application
18+
*
19+
* \param name The array containing the name to compare with the file's name.
20+
*
21+
* \param offset The offset at where the name begins.
22+
*
23+
* \param length The length of the name.
24+
*
25+
* \return false if the DF has no name or the names do not match,
26+
* true else.
27+
*/
28+
public boolean isName(byte[] name, short offset, short length) {
29+
short namePos;
30+
short aidlen = 0;
31+
short i;
32+
// Find the position of the AID tag (4F) in the fci.
33+
try {
34+
namePos = UtilTLV.findTag(fileControlInformation, (short)2, fileControlInformation[(short)1], (byte) 0x4F);
35+
} catch (NotFoundException e) {
36+
// This DF has no name.
37+
return false;
38+
} catch (InvalidArgumentsException e) {
39+
return false;
40+
}
41+
// This ADF has a AID.
42+
try {
43+
aidlen = UtilTLV.decodeLengthField(fileControlInformation, (short)(namePos+1));
44+
if (aidlen < length) {
45+
// aid len to check is to big to match
46+
return false;
47+
}
48+
} catch (InvalidArgumentsException e) {
49+
return false;
50+
}
51+
// Advance namePos from "tag" to value.
52+
try {
53+
namePos += 1 + UtilTLV.getEncodingLengthFieldLength(length);
54+
} catch(InvalidArgumentsException e) {
55+
return false;
56+
}
57+
// check if the name can be a part of the AID
58+
for (i = 0; i < (short)(aidlen - length +1); i++) {
59+
if ((byte)0 == Util.arrayCompare(name, offset, fileControlInformation, (short)(namePos + i), length) ) {
60+
return true;
61+
}
62+
}
63+
return false;
64+
}
65+
66+
public byte[] getFileManagementData() {
67+
return fileManagementData;
68+
}
69+
70+
public byte[] getFileControlInformation() {
71+
return fileControlInformation;
72+
}
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
package com.mysmartlogon.gidsApplet;
2+
3+
import javacard.framework.JCSystem;
4+
import javacard.framework.Util;
5+
6+
public class BerTlvFile extends ElementaryFile {
7+
8+
private static final short ELEMENT_COUNT_START = 10;
9+
private static final short ELEMENT_COUNT_MAX = 30; // set to max. 16383
10+
11+
private Record[] children;
12+
private byte currentNumChildren;
13+
14+
/**
15+
* \brief Instantiate a new BER-TLV EF. No data is being added at this point.
16+
*
17+
* \param fileControlInformation The array of bytes containing the valid (!) File Control Information.
18+
* It must contain the File ID (Tag 83). No Copy is made.
19+
*
20+
* \param maxRecords The maximum amount of saved records.
21+
*
22+
* \attention No copy of the FCI is made. Do not pass any buffer that is altered
23+
* later (e.g. the apdu buffer). Max length 257 bytes as the length
24+
* of the FCI Tag (6F) must be a byte.
25+
*
26+
* \attention To be safe, use IsoFileSystem.getSafeFile() to instantiate files.
27+
*
28+
* \throw IllegalArgumentException If necessary tags in the FCI are missing.
29+
*/
30+
public BerTlvFile(short fileID, byte[] fileControlInformation) {
31+
super(fileID, fileControlInformation);
32+
this.children = new Record[ELEMENT_COUNT_START];
33+
this.currentNumChildren = 0;
34+
}
35+
36+
@Override
37+
void clearContents() {
38+
short i;
39+
40+
for(i = 0; i < currentNumChildren; i++) {
41+
children[i].clearContents();
42+
children[i] = null;
43+
}
44+
45+
}
46+
47+
/**
48+
* \brief Delete a DO
49+
*
50+
* This method requests garbage collection.
51+
*
52+
* \param childNum internal index
53+
*/
54+
protected void deleteChildren(short childNum) {
55+
56+
children[childNum] = null;
57+
currentNumChildren--; // We have one less children now.
58+
59+
// Fill up empty field in children array.
60+
// The last children is one ahead, so it is at currentNumChildren.
61+
if(childNum < currentNumChildren) {
62+
children[childNum] = children[currentNumChildren];
63+
}
64+
65+
// Clean up the old file object.
66+
if(JCSystem.isObjectDeletionSupported()) {
67+
JCSystem.requestObjectDeletion();
68+
}
69+
}
70+
71+
/**
72+
* \brief remove a DO
73+
*
74+
* \param children The children to add.
75+
*
76+
* \throw NotEnoughSpaceException If CHILDREN_COUNT_MAX is reached.
77+
* @param size
78+
* @param offset_cdata
79+
*/
80+
public Record addChildren(byte[] buffer, short offset, short wholelength, short lengthavailable) throws NotEnoughSpaceException {
81+
// try to find a previous TLV
82+
short i;
83+
short lengthToCopy = (lengthavailable > wholelength ? wholelength: lengthavailable);
84+
for(i = 0; i < currentNumChildren; i++) {
85+
byte[] value = children[i].GetData();
86+
87+
if (UtilTLV.IsBERTLVTagEqual(buffer, offset, (short) (offset + lengthavailable), value)) {
88+
// found => replace or erase ?
89+
90+
// erase if empty DO pushed and already empty DO stored
91+
short oldlen = UtilTLV.GetBERTLVDataLen(value, (short) 0, (short) value.length);
92+
short newlen = UtilTLV.GetBERTLVDataLen(buffer, offset, (short) (offset + lengthavailable));
93+
if (oldlen == 0) {
94+
if (newlen == 0) {
95+
deleteChildren(i);
96+
return null;
97+
}
98+
}
99+
// replace
100+
if (oldlen == newlen) {
101+
// no need to add / remove data, just replace the buffer
102+
Util.arrayCopyNonAtomic(buffer, offset, value, (short) 0, lengthToCopy);
103+
} else {
104+
// remove previous data, add new
105+
byte[] data = new byte[wholelength];
106+
Util.arrayCopyNonAtomic(buffer, offset, data, (short) 0, lengthToCopy);
107+
children[i] = null;
108+
if(JCSystem.isObjectDeletionSupported()) {
109+
JCSystem.requestObjectDeletion();
110+
}
111+
children[i] = new Record(data);
112+
}
113+
return children[i];
114+
}
115+
116+
}
117+
118+
119+
// First we have to check for enough space.
120+
if(currentNumChildren >= (short)children.length) {
121+
Record[] newChildren = null;
122+
// The array is full - we try to increase the size.
123+
if((short)(children.length * 2) <= ELEMENT_COUNT_MAX) {
124+
// Doubling the size is possible.
125+
newChildren = new Record[(short)(children.length * 2)];
126+
copyFileArrayRefs(children, newChildren);
127+
} else {
128+
// Doubling not possible - try to at least increase to CHILDREN_COUNT_MAX.
129+
if(currentNumChildren < ELEMENT_COUNT_MAX) {
130+
newChildren = new Record[ELEMENT_COUNT_MAX];
131+
copyFileArrayRefs(children, newChildren);
132+
} else {
133+
// CHILDREN_COUNT_MAX exceeded. No "space" left. Fail.
134+
throw NotEnoughSpaceException.getInstance();
135+
}
136+
}
137+
children = newChildren; // Initial children array is now garbage.
138+
if(JCSystem.isObjectDeletionSupported()) {
139+
JCSystem.requestObjectDeletion();
140+
}
141+
} // We have enough space (now).
142+
byte[] data = new byte[wholelength];
143+
Util.arrayCopyNonAtomic(buffer, offset, data, (short) 0, lengthToCopy);
144+
children[currentNumChildren++] = new Record(data);
145+
return children[(short) (currentNumChildren-1)];
146+
}
147+
148+
/**
149+
* \brief Copies the references from one File array to the other.
150+
*
151+
* \attention Although only references are copied, this is probably still quite expensive because
152+
* writing to the EEPROM is. Only use this for operations that are not called often (Creating and deleting files etc.).
153+
*
154+
* \param src The source File array to copy from.
155+
*
156+
* \param dest The destination File array to copy to. It MUST be at least of size of the src array.
157+
*/
158+
private static void copyFileArrayRefs(Record[] src, Record[] dest) {
159+
short i = 0;
160+
short length = src.length > dest.length ? (short)dest.length : (short)src.length;
161+
162+
for(i=0; i < length; i++) {
163+
dest[i] = src[i];
164+
}
165+
return;
166+
}
167+
168+
public Record getData(byte[] tag, short offset, short len) throws NotFoundException {
169+
short i;
170+
171+
for(i = 0; i < currentNumChildren; i++) {
172+
byte[] value = children[i].GetData();
173+
if(UtilTLV.IsBERTLVTagEqual(tag, offset, len, value)) {
174+
return children[i];
175+
}
176+
}
177+
178+
throw NotFoundException.getInstance();
179+
}
180+
181+
public Record[] getAllData() {
182+
return children;
183+
}
184+
185+
}

0 commit comments

Comments
 (0)