Fields Summary |
---|
public static final byte | A_CLA |
public static short | ST_ERROR_BAD_TRANSIENT_MEM_DESELECT |
public static short | ST_ERROR_BAD_TRANSIENT_MEM_DESELECT_ELEMENT |
public static short | ST_ERROR_BAD_TRANSIENT_MEM_RESET |
public static short | ST_ERROR_BAD_TRANSIENT_MEM_RESET_ELEMENT |
public static short | ST_ERROR_MEM_MATCH_OBJECTS |
public static short | ST_ERROR_MEM_MATCH_TRANSIENT_DESELECT_OBJECTS |
public static short | ST_ERROR_TRANSIENT_DESELECT_OBJECTS_EXIST |
public static short | ST_ERROR_TRANSIENT_RESET_OBJECTS_EXIST |
public static short | ST_ERROR_MEM_MATCH_TRANSIENT_RESET_OBJECTS |
public static short | ST_ERROR_MEM_MATCH_ALL_ATTRIBUTES |
public static short | ST_ERROR_MEM_MATCH_INITIAL |
public static short | ST_ERROR_MEM_MATCH_BEFORE_PACK |
public static short | ST_ERROR_APPLET_AID_NOT_FOUND |
public static short | ST_ERROR_SHAREABLE_NOT_FOUND |
public static short | ST_ERROR_TRANSIENT_DESELECT_MEM_NOT_RETURNED |
public static short | ST_ERROR_TRANSIENT_RESET_MEM_NOT_RETURNED |
public static short | SUCCESS |
public static byte[] | BApp1AID |
short | initialMemUsage |
short | initialTransientDeselectMem |
short | initialTransientResetMem |
short | objectRefMemUsage |
short | transientDeselectUninitializedMemUsage |
short | transientDeselectMemUsage |
short | transientResetUninitializedMemUsage |
short | transientResetMemUsage |
ATreeNode | left |
ATreeNode | right |
static ATreeNode | sleft |
static ATreeNode | sright |
Object[] | transientDeselectMem |
Object[] | transientResetMem |
Shareable | BApp1Ref |
private static final short | NUM_OBJECTS |
private static final short | MAX_TREE_DEPTH |
static final byte | SETUP_PERSISTENT |
static final byte | SETUP_TRANSIENT |
static final byte | REQUEST_OD |
static final byte | REMOVE_TREES |
static final byte | ANALYZE_REMOVE_TREES |
static final byte | ANALYZE_TRANSIENT_DESELECT_MEM |
static final byte | ANALYZE_TRANSIENT_RESET_MEM |
static final byte | REMOVE_ALL_ATTRIBUTES |
static final byte | ANALYZE_REMOVE_ALL_ATTRIBUTES |
static final byte | CAPTURE_INITIAL_MEM |
static final byte | COMPARE_INITIAL_MEM |
static final byte | GET_SHAREABLE_REF |
static final byte | LOSE_REF_BAPP1 |
Methods Summary |
---|
private void | analyzeRemoveAllAttributes()method analyzes if all transient and persistent memory have been
returned to the memory manager. It is called after the card has
been reset.
//now the memory should have gone back to initial mem
short tempMem=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
if(tempMem!=initialMemUsage){
ISOException.throwIt(ST_ERROR_MEM_MATCH_ALL_ATTRIBUTES);
}
//test if all transient reset and deselect memory is returned
if(initialTransientResetMem!=
JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET))
ISOException.throwIt(ST_ERROR_TRANSIENT_RESET_MEM_NOT_RETURNED);
if(initialTransientDeselectMem!=
JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT))
ISOException.throwIt(ST_ERROR_TRANSIENT_DESELECT_MEM_NOT_RETURNED);
|
private void | analyzeRemoveTrees()method verifies if all memory pointed to the persistent objects
was collected
short tempMem=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
if(tempMem!=transientResetMemUsage){
//error. not all memory collected
ISOException.throwIt(transientResetMemUsage);
//ISOException.throwIt(ST_ERROR_MEM_MATCH_OBJECTS);
}
//verify all other objs pointed to by the DESELECT array are intact
short ret=verifyTransientDeselect();
if(ret!=SUCCESS)
ISOException.throwIt(ret);
//verify all objects pointed to by the RESET array are intact
ret=verifyTransientReset();
if(ret!=SUCCESS)
ISOException.throwIt(ret);
|
private void | analyzeTransientDeselectMem()this method should be called after deselecting and selecting
//by this point the arrays must have had there values nulled and references
//to all transientarrayelements lost. Object deletion mechanism here would have deleted
//all transientarrayelement objects pointed to by deselect array
//verify objects pointed to by DESELECT array are gone
short ret=verifyTransientDeselect();
if(ret!=ST_ERROR_BAD_TRANSIENT_MEM_DESELECT_ELEMENT)
ISOException.throwIt(ST_ERROR_TRANSIENT_DESELECT_OBJECTS_EXIST);
//verify persistent memory collected for all objects
short tempMem=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
if(tempMem!=(short)(transientResetMemUsage+
(transientDeselectUninitializedMemUsage-transientDeselectMemUsage))){
//error. not all memory collected
ISOException.throwIt( ST_ERROR_MEM_MATCH_TRANSIENT_DESELECT_OBJECTS);
}
//verify all objects pointed to by the RESET array are intact
ret=verifyTransientReset();
if(ret!=SUCCESS)
ISOException.throwIt(ret);
|
private void | analyzeTransientResetMem()this method should be called after card was reset. It analyzes
if all persistent memory has been returned including the memory
used by objects in the transient reset array.
//by now card should have been reset
//verify objects pointed to by RESET array are gone
short ret=verifyTransientReset();
if(ret!=ST_ERROR_BAD_TRANSIENT_MEM_RESET_ELEMENT)
ISOException.throwIt(ST_ERROR_TRANSIENT_RESET_OBJECTS_EXIST);
//verify memory is collected for all objects
short tempMem=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
if(tempMem!=(short)((transientDeselectUninitializedMemUsage-transientDeselectMemUsage)+
(transientResetUninitializedMemUsage))){
//not all memory returned
ISOException.throwIt( ST_ERROR_MEM_MATCH_TRANSIENT_RESET_OBJECTS);
}
|
private void | captureInitialMem()method captures the current memory used by compareWithInitial()
to check if memis same.
initialMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
|
private void | compareWithInitial()method compares the current memory with initialMemUsage and throws exception
if not the same
short curr=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
if(curr!=initialMemUsage)
ISOException.throwIt( ST_ERROR_MEM_MATCH_INITIAL);
|
private void | getShareableRef()method gets a shareable reference to BApp1 (Applet B instance 1)
to verify that we cannot delete it
AID bApp1AID=JCSystem.lookupAID(BApp1AID,(short)0,(byte)BApp1AID.length);
if(bApp1AID==null)
ISOException.throwIt(ST_ERROR_APPLET_AID_NOT_FOUND);
//get the ref
BApp1Ref=(Shareable)(JCSystem.getAppletShareableInterfaceObject(bApp1AID,(byte)0));
if(BApp1Ref==null)
ISOException.throwIt(ST_ERROR_SHAREABLE_NOT_FOUND);
|
public static void | install(byte[] bArr, short bOffset, byte bLength)method instantiates aninstance of A
new A();
|
private void | loseBAppRef()method sets the BApp1 referenc to null
BApp1Ref=null;
JCSystem.requestObjectDeletion();
|
public void | process(APDU apdu)method processes the APDU commands passed to this applet instance.
It dispatches the request by calling the appropriate method and
returning appropriate result
byte buffer[]=apdu.getBuffer();
// check SELECT APDU command
if ((buffer[ISO7816.OFFSET_CLA] == 0) &&
(buffer[ISO7816.OFFSET_INS] == (byte)(0xA4))){
return;
}
short ret=0;
short tempMem=0;
switch (buffer[ISO7816.OFFSET_INS]){
case SETUP_TRANSIENT:
setupTransient();
break;
case SETUP_PERSISTENT:
setupPersistent();
break;
case REQUEST_OD:
requestOD();
break;
case REMOVE_TREES:
removeTrees();
break;
case ANALYZE_REMOVE_TREES:
analyzeRemoveTrees();
break;
case ANALYZE_TRANSIENT_DESELECT_MEM:
//this must be called after deselecting and selecting
analyzeTransientDeselectMem();
break;
case ANALYZE_TRANSIENT_RESET_MEM:
//called after applet reset
analyzeTransientResetMem();
break;
case REMOVE_ALL_ATTRIBUTES:
removeAllAttributes();
break;
case ANALYZE_REMOVE_ALL_ATTRIBUTES:
analyzeRemoveAllAttributes();
break;
case CAPTURE_INITIAL_MEM:
captureInitialMem();
break;
case COMPARE_INITIAL_MEM:
//Assumes captureInitialMem has been called
compareWithInitial();
break;
case GET_SHAREABLE_REF:
getShareableRef();
break;
case LOSE_REF_BAPP1:
loseBAppRef();
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
|
private void | removeAllAttributes()method sets attributes pointing to the two types of transient
arrays to null. This creates garbage objects to be deleted. Method also
requests for object deletion
//set all attributes to null
transientDeselectMem=null;
transientResetMem=null;
JCSystem.requestObjectDeletion();
|
private void | removeTrees()method sets the persistent object references to null
//remove the trees from both static and non-static trees
left=null;
right=null;
sleft=null;
sright=null;
|
private void | requestOD()request object deletion facility to delete objects that are not reachable
JCSystem.requestObjectDeletion();
|
private void | setupPersistent()method sets up the persistent objects by calling setupTrees()
and captures the memory available
//setup object references
setupTrees();
objectRefMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
|
private void | setupTransient()method sets up the transient objects and captures available memory
of different kinds at various stages.
//get initial memory available for persistent and transient memory
initialMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
initialTransientDeselectMem=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
initialTransientResetMem=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//setup CLEAR_ON_DESELECT memory
transientDeselectMem=JCSystem.makeTransientObjectArray(NUM_OBJECTS,JCSystem.CLEAR_ON_DESELECT);
transientDeselectUninitializedMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
for(short i=0;i<NUM_OBJECTS;i++)
transientDeselectMem[i]=new TransientArrayElement(i);
transientDeselectMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
//setup CL_ON_RESET memory
transientResetMem=JCSystem.makeTransientObjectArray(NUM_OBJECTS,JCSystem.CLEAR_ON_RESET);
transientResetUninitializedMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
for(short i=0;i<NUM_OBJECTS;i++)
transientResetMem[i]=new TransientArrayElement(i);
transientResetMemUsage=JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
|
private void | setupTrees()method sets up tree of objects. Two are statically referenced.
left=new ATreeNode((short)0,MAX_TREE_DEPTH);
right=new ATreeNode((short)0,MAX_TREE_DEPTH);
sleft=new ATreeNode((short)0,MAX_TREE_DEPTH);
sright=new ATreeNode((short)0,MAX_TREE_DEPTH);
|
private short | verifyTransientDeselect()verify the transient structures of type CLEAR_ON_DESELECT are intact
if(transientDeselectMem==null)
return ST_ERROR_BAD_TRANSIENT_MEM_DESELECT;
for(short i=0;i<transientDeselectMem.length;i++){
if(transientDeselectMem[i]==null ||
((TransientArrayElement)transientDeselectMem[i]).data!=i)
return ST_ERROR_BAD_TRANSIENT_MEM_DESELECT_ELEMENT;
}
return SUCCESS;
|
private short | verifyTransientReset()verify the transient structures of type CLEAR_ON_RESET are intact
if(transientResetMem==null)
return ST_ERROR_BAD_TRANSIENT_MEM_RESET;
for(short i=0;i<transientResetMem.length;i++){
if(transientResetMem[i]==null ||
((TransientArrayElement)transientResetMem[i]).data!=i)
return ST_ERROR_BAD_TRANSIENT_MEM_RESET_ELEMENT;
}
return SUCCESS;
|