Fields Summary |
---|
static final int | MAX_PATH_DEPTHExpected maximum path depth. |
protected static final byte | INS_SELECTAPDU INS byte. |
protected static final byte | INS_READAPDU INS byte. |
protected static final byte | INS_UPDATEAPDU INS byte. |
short[] | rootRoot path for this application. |
int | pathLengthThe length of path to current DF. |
short[] | currentPathPath to the current DF. Element at index pathLength contains EF
identifier if EF is selected. |
protected Connection | apduConnection used by this file system. |
protected int | currentFileSizeSize of currently selected EF or -1 if DF is selected. |
protected boolean | isEFSelectedTrue if currently selected file is EF. |
Methods Summary |
---|
public int | getCurrrentFileSize()Returns the size of currently selected EF or -1 if DF is
selected.
return currentFileSize;
|
public TLV | loadObject(Location l)Loads and parses one DER encoded object.
select(l.path);
byte[] tmp = readData(0, l.length, l.offset);
return new TLV(tmp, 0);
|
public short[] | makePath(TLV t)If necessary converts path into completely specified path.
short[] path;
short s = Utils.getShort(t.data, t.valueOffset);
if (root == null) { // only file IDs are used
if (t.length == 2) {
path = new short[1];
path[0] = s;
return path;
}
throw new IOException("Invalid path - ID expected");
}
// absolute path
if (s == 0x3f00) {
path = new short[t.length / 2];
for (int i = 0; i < path.length; i++) {
path[i] = Utils.getShort(t.data, t.valueOffset + i * 2);
}
return path;
}
// it must be relative path
int len = root.length + t.length / 2;
int offset = t.valueOffset;
if (s == 0x3fff) {
len--;
offset += 2;
} else {
if (t.length != 2) {
throw new IOException(
"Invalid path - file ID must be used");
}
}
path = new short[len];
System.arraycopy(root, 0, path, 0, root.length);
for (int i = root.length; i < path.length; i++) {
path[i] = Utils.getShort(t.data, offset);
offset += 2;
}
return path;
|
public Location | pathToLocation(TLV path)Converts PKCS#15 path into location.
try {
if (path.type == TLV.SEQUENCE_TYPE) {
path = path.child;
}
short[] p = makePath(path);
int offset = 0;
int length = -1;
if (path.next != null) {
offset = path.next.getInteger();
length = path.next.next.getInteger();
}
return new Location(p, offset, length);
} catch (IOException e) {
throw new IOException("Invalid path structure");
} catch (NullPointerException npe) {
throw new IOException("Invalid path structure");
} catch (IndexOutOfBoundsException iobe) {
throw new IOException("Invalid path structure");
}
|
public abstract byte[] | readData(int offset, int length, int fileOffset)Reads part of selected file.
|
public byte[] | readFile()Reads the current EF.
byte[] data = readData(0, currentFileSize, 0);
return data;
|
public void | select(short[] path)Selects file using only SELECT APDU command with file identifier.
According to WIM specification support of this selection method
is mandatory.
if (root == null) {
if (path.length == 1) {
select(path[0]);
return;
}
throw new IOException(
"Invalid path - file ID must be used");
}
int c = 0; // index of first path element that differs
while (c < pathLength && c < path.length) {
if (currentPath[c] != path[c]) {
break;
}
c++;
}
if (c == 0) {
throw new IOException("Invalid path - wrong root directory");
}
if (c == pathLength &&
pathLength == (path.length - 1) &&
isEFSelected &&
currentPath[pathLength] == path[pathLength]) {
return;
}
while (c < pathLength) {
pathLength--;
select(currentPath[pathLength]);
}
while (pathLength < path.length) {
select(path[pathLength]);
currentPath[pathLength] = path[pathLength];
if (isEFSelected) {
if (pathLength == path.length - 1) {
break;
}
throw new IOException("Invalid path - EF in path");
}
pathLength++;
}
|
public abstract void | select(short id)Selects file by ID.
|
public void | selectRoot(short[] root)Sends the select DF command to the card.
setRoot(root);
for (int i = 0; i < root.length; i++) {
byte[] data = apdu.resetCommand().
putShort(root[i]).
sendCommand(INS_SELECT, 0x0100);
}
|
public void | setRoot(short[] root)Sets the root directory for this file system.
this.root = root;
currentPath = new short[MAX_PATH_DEPTH];
for (int j = 0; j < root.length; j++) {
currentPath[j] = root[j];
}
pathLength = root.length;
|