Commits

Benoît Allard  committed 40583ac Merge

merged

  • Participants
  • Parent commits 38428c1, 46cb4f8
  • Tags 1.0

Comments (0)

Files changed (12)

File caprunner/capfile.py

         CPInfoClassTokenref.__init__(self, data)
         self.isPrivate = bool(self.token & 0x80)
         self.token &= 0x7f
+    def __str__(self):
+        return "<%s, token %d, %s>" % (self.__class__.__name__, self.token, CPInfoClassTokenref.__str__(self))
 class CPInfoSuperMethodref(CPInfoVirtualMethodref): pass
 
 class StaticBaseref(object):

File caprunner/interpreter/__init__.py

             self._invokespecialnative(method)
         elif isinstance(method, JavaCardStaticMethod):
             self._invokespecialjava(method)
+        elif isinstance(method, PythonVirtualMethod):
+            self._invokevirtualnative(method)
         elif isinstance(method, JavaCardVirtualMethod):
             self._invokevirtualjava(method)
         else:
-            raise NotImplementedError
+            raise ValueError("Something weird's going on", method)
 
     def _invokevirtualnative(self, method):
         params = self._popparams(method.paramsize)

File caprunner/interpreter/classes.py

     This is a class that is not in the CAP file. Thus likely to be implemented
     in Python.
     """
-    def __init__(self, cls):
+    def __init__(self, cls, aid, ref):
+        """ We store more than needed, we needs it during super method
+        invocation later"""
         self.cls = cls
+        self.pkg_aid = aid
+        self.ref = ref
 
     def __str__(self):
         return "<PythonClass: %s>" % str(self.cls)

File caprunner/refcollection.py

 
         def addVirtualMethod(self, token, name, type):
             if "<init>" in name:
+                # Arguably, constructors are statics ...
                 self.addStaticMethod(token, name, type)
             else:
                 assert not token in self.virtualmethods, self.virtualmethods[token]

File caprunner/resolver.py

             try:
                 # pythoncard begins with python ...
                 mod = __import__('python'+name[4:])
-            except ImportError:
-                mod = __import__(name)
+            except ImportError, ie:
+                try:
+                    # Try original package
+                    mod = __import__(name)
+                except ImportError:
+                    # replace exception with original one
+                    raise ie
         else:
             mod = __import__(name)
         for comp in name.split('.')[1:]:
         # get the module
         mod = self._getModule(pkg.name.replace('/', '.'))
         # get the class
-        return PythonClass(getattr(mod, clsname))
+        cls = getattr(mod, clsname)
+        return PythonClass(cls, aid, token)
 
     def resolveStaticMethod(self, cst, cap_file):
         if cst.isExternal:
             raise NotImplementedError("super call from python")
         else:
             cls = self.resolveClassRef(cst, cap_file)
-            if not isinstance(cls.super, JavaCardClass):
-                # also unlikely to happen ...
-                raise NotImplementedError("super call going into python")
-            class_ref = cls.super.class_descriptor_info.this_class_ref.class_ref
-            return JavaCardVirtualMethod(class_ref, cst.token, cst.isPrivate,
-                                         cap_file, self)
+            if isinstance(cls.super, JavaCardClass):
+                class_ref = cls.super.class_descriptor_info.this_class_ref.class_ref
+                return JavaCardVirtualMethod(class_ref, cst.token, cst.isPrivate,
+                                             cap_file, self)
+            # The trick is to use ref and AID we stored during creation of the
+            # class
+            pkg = self.refs[cls.super.pkg_aid]
+            (clsname, mtd) = pkg.getVirtualMethod(cls.super.ref, cst.token)
+            mtdname = mtd['name']
+            if mtdname[0] == '$':
+                # Call every variations of the function the same way
+                mtdname = mtdname[1:mtdname[1:].find('$') + 1]
+            return PythonVirtualMethod(mtdname, mtd['type'])
 
 # --- Below this line are the public methods. Don't use the other ones, 
 # as the result will not be cached.
         for cst, ref in altCP:
             if class_ref.isExternal == cst.isExternal:
                 if cst.isExternal:
-                    if ((this_ref.class_ref.package_token == CR.package_token) and 
+                    if ((cst.class_ref.package_token == CR.package_token) and 
                         (cst.class_ref.class_token == CR.class_token)):
                         return ref
                 else:

File caprunner/token.py

                         buf = [idx]
                         buf.extend(d2a('\x90\x00'))
                         return buf
-                return d2a(ISO7816.SW_WRONG_P1P2)
+                return d2a('\x6A\x86')
             elif bytes[1:3] == [112, -128]:
                 # close channel: 70 80
                 idx = bytes[3]
                 if self.channels[idx]:
                     self.channels[idx] = False
                     return d2a('\x90\x00')
-                return d2a(ISO7816.SW_WRONG_P1P2)
+                return d2a('\x6A\x86')
             elif bytes[1:4] == [-26, 12, 0]:
                 # install : E6 0C 00
                 self.install(bytes, 5)
         applet = self.selected[self.current_channel]
         if applet is None:
             # no applet selected on current channel
-            return d2a(ISO7816.SW_FILE_NOT_FOUND)
+            return d2a('\x6A\x82')
         # Make an APDU object
         apdu = APDU(bytes)
         # pass to the process method

File test/javatest/CAPEmu.java

+package javatest;
+
+import javacard.framework.Applet;
+import javacard.framework.ISO7816;
+import javacard.framework.Util;
+import javacard.framework.ISOException;
+import javacard.framework.APDU;
+import javacard.framework.JCSystem;
+
+/**
+ * Copyright Jean-Pierre Szikora and Philippe Teuwen - 2011                                     *
+ * Cette création est mise à disposition selon le Contrat Attribution-ShareAlike 2.0 Belgium    *
+ * disponible en ligne http://creativecommons.org/licenses/by-sa/2.0/be/ ou par courrier postal *
+ * à Creative Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA.      *
+ **/
+
+public class CAPEmu extends Applet
+{
+private final static byte[] responseToSelect =	{
+// Length 0x30 or 48
+(byte)0x6F, (byte)0x2E, (byte)0x84, (byte)0x07, (byte)0xA0,
+(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x80,
+(byte)0x02, (byte)0xA5, (byte)0x23, (byte)0x9F, (byte)0x38,
+(byte)0x03, (byte)0x9F, (byte)0x35, (byte)0x01, (byte)0x5F,
+(byte)0x2D, (byte)0x02, (byte)0x66, (byte)0x72, (byte)0xBF,
+(byte)0x0c, (byte)0x15, (byte)0x9F, (byte)0x55, (byte)0x01,
+(byte)0x00, (byte)0x5F, (byte)0x2C, (byte)0x02, (byte)0x00, 
+(byte)0x56, (byte)0xDF, (byte)0x07, (byte)0x09, (byte)0x42, 
+(byte)0x4B, (byte)0x53, (byte)0x30, (byte)0x35, (byte)0x36, 
+(byte)0x36, (byte)0x35, (byte)0x31
+};
+	
+private final static byte[] responseType =	{
+// Length 0x10 or 16
+(byte)0x77, (byte)0x0E, (byte)0x82, (byte)0x02, (byte)0x10, 
+(byte)0x00, (byte)0x94, (byte)0x08, (byte)0x08, (byte)0x01, 
+(byte)0x01, (byte)0x00, (byte)0x08, (byte)0x04, (byte)0x04, 
+(byte)0x00
+};
+
+private final static byte[] Record1 =	{
+// Length Ox40 or 64
+(byte)0x70, (byte)0x3E, (byte)0x5A, (byte)0x09, (byte)0x67,
+(byte)0x03, (byte)0x12, (byte)0x34, (byte)0x56, (byte)0x78,
+(byte)0x90, (byte)0x12, (byte)0x3F, (byte)0x5F, (byte)0x34,
+(byte)0x01, (byte)0x01, (byte)0x5F, (byte)0x25, (byte)0x03,
+(byte)0x09, (byte)0x02, (byte)0x01, (byte)0x5F, (byte)0x24,
+(byte)0x03, (byte)0x13, (byte)0x05, (byte)0x31, (byte)0x57,
+(byte)0x13, (byte)0x67, (byte)0x03, (byte)0x12, (byte)0x34,
+(byte)0x56, (byte)0x78, (byte)0x90, (byte)0x12, (byte)0x3D,
+(byte)0x13, (byte)0x05, (byte)0x22, (byte)0x10, (byte)0x00,
+(byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x9F,
+(byte)0x5F, (byte)0x28, (byte)0x02, (byte)0x00, (byte)0x56,
+(byte)0x9F, (byte)0x42, (byte)0x02, (byte)0x09, (byte)0x78,
+(byte)0x9F, (byte)0x44, (byte)0x01, (byte)0x02
+};
+
+private final static byte[] Record2 =	{
+// Length 0x5A or 90
+(byte)0x70, (byte)0x58, (byte)0x9F, (byte)0x56, (byte)0x0B,
+(byte)0x00, (byte)0x00, (byte)0xFF, (byte)0x00, (byte)0x00,
+(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x03, (byte)0xFF,
+(byte)0xFF, (byte)0x8E, (byte)0x0A, (byte)0x00, (byte)0x00,
+(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+(byte)0x00, (byte)0x01, (byte)0x00, (byte)0x8C, (byte)0x1B,
+(byte)0x9F, (byte)0x02, (byte)0x06, (byte)0x9F, (byte)0x03,
+(byte)0x06, (byte)0x9F, (byte)0x1A, (byte)0x02, (byte)0x95,
+(byte)0x05, (byte)0x5F, (byte)0x2A, (byte)0x02, (byte)0x9A,
+(byte)0x03, (byte)0x9C, (byte)0x01, (byte)0x9F, (byte)0x37,
+(byte)0x04, (byte)0x9F, (byte)0x4C, (byte)0x02, (byte)0x9F,
+(byte)0x34, (byte)0x03, (byte)0x8D, (byte)0x1F, (byte)0x8A,
+(byte)0x02, (byte)0x9F, (byte)0x02, (byte)0x06, (byte)0x9F,
+(byte)0x03, (byte)0x06, (byte)0x9F, (byte)0x1A, (byte)0x02,
+(byte)0x95, (byte)0x05, (byte)0x5F, (byte)0x2A, (byte)0x02,
+(byte)0x9A, (byte)0x03, (byte)0x9C, (byte)0x01, (byte)0x9F,
+(byte)0x37, (byte)0x04, (byte)0x9F, (byte)0x4C, (byte)0x02,
+(byte)0x9F, (byte)0x34, (byte)0x03, (byte)0x91, (byte)0x0A
+};
+
+private final static byte[] Crypto1 =	{
+// Length 0x28 or 40
+(byte)0x77, (byte)0x26, (byte)0x9F, (byte)0x27, (byte)0x01,
+(byte)0x80, (byte)0x9F, (byte)0x36, (byte)0x02, (byte)0x00,
+(byte)0x00, (byte)0x9F, (byte)0x26, (byte)0x08, (byte)0x00,
+(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+(byte)0x00, (byte)0x00, (byte)0x9F, (byte)0x10, (byte)0x0F,
+(byte)0x06, (byte)0x01, (byte)0x56, (byte)0x03, (byte)0xA4,
+(byte)0x00, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x03,
+(byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x02
+};
+
+private final static byte[] Crypto2 =	{
+// Length 0x28 or 40
+(byte)0x77, (byte)0x26, (byte)0x9F, (byte)0x27, (byte)0x01,
+(byte)0x00, (byte)0x9F, (byte)0x36, (byte)0x02, (byte)0x00,
+(byte)0x00, (byte)0x9F, (byte)0x26, (byte)0x08, (byte)0x00,
+(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+(byte)0x00, (byte)0x00, (byte)0x9F, (byte)0x10, (byte)0x0F,
+(byte)0x06, (byte)0x01, (byte)0x56, (byte)0x03, (byte)0x25,
+(byte)0xB0, (byte)0x40, (byte)0x07, (byte)0x01, (byte)0x03,
+(byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x02
+};
+
+private final static byte[] RetryLeft = {
+(byte)0x9F, (byte)0x17, (byte)0x01, (byte)0x03
+};
+
+private byte[] pin = JCSystem.makeTransientByteArray((short)2, JCSystem.CLEAR_ON_DESELECT); 
+
+  /** Basic Java Card applet registration */
+  public static void install(byte[] bArray, short bOffset, byte bLength) {
+	new CAPEmu().register();
+	}
+
+  public void process(APDU apdu) {
+	short bytesP1;
+	short readCount;
+	short bytesLeft;
+	byte[] buf = apdu.getBuffer();
+	if (selectingApplet()) {
+		Util.arrayCopyNonAtomic(responseToSelect,(byte)0,buf,ISO7816.OFFSET_CDATA,(short)responseToSelect.length);
+		apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA,(short)responseToSelect.length);
+		return;
+		}
+
+  switch (buf[ISO7816.OFFSET_INS]) {
+	case (byte) 0xA8:
+		readCount = apdu.setIncomingAndReceive();
+		Util.arrayCopyNonAtomic(responseType,(byte)0,buf,ISO7816.OFFSET_CDATA,(short)responseType.length);
+		apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA,(short)responseType.length);
+		break;
+	case (byte) 0xB2:
+		switch (buf[ISO7816.OFFSET_P1])	{
+		case (byte) 0x01:
+			bytesLeft = apdu.setOutgoing();
+			if (bytesLeft == (short) 0)	{
+				apdu.setOutgoingLength((short) 0);
+				apdu.sendBytesLong (Record1,(short)0,(short)0);
+				}
+			else	{
+				apdu.setOutgoingLength((short)Record1.length);
+				apdu.sendBytesLong (Record1,(short)0,(short)Record1.length);
+				}
+			break;
+		case (short) 0x04:
+			bytesLeft = apdu.setOutgoing();
+			if (bytesLeft == (short) 0)	{
+				apdu.setOutgoingLength((short) 0);
+				apdu.sendBytesLong (Record2,(short)0,(short)0);
+				}
+			else	{
+				apdu.setOutgoingLength((short)Record2.length);
+				apdu.sendBytesLong (Record2,(short)0,(short)Record2.length);
+				}
+			break;
+		default:
+			ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
+			}		
+		break;
+	case (byte) 0xCA:
+		bytesLeft = apdu.setOutgoing();
+		if (bytesLeft == (short) 0)	{
+			apdu.setOutgoingLength((short) 0);
+			apdu.sendBytesLong (RetryLeft,(short)0,(short)0);
+			}
+		else	{
+			apdu.setOutgoingLength((short)RetryLeft.length);
+			apdu.sendBytesLong (RetryLeft,(short)0,(short)RetryLeft.length);
+			}
+		break;
+	case (byte) 0x20:
+		readCount = apdu.setIncomingAndReceive();
+		Util.arrayCopyNonAtomic(buf,(byte)(ISO7816.OFFSET_CDATA + 1),pin,(byte)0,(short)pin.length);
+		break;
+	case (byte) 0xAE:
+		switch (buf[ISO7816.OFFSET_P1])	{
+		case (byte) 0x80:
+			readCount = apdu.setIncomingAndReceive();
+			Util.arrayCopyNonAtomic(Crypto1,(byte)0,buf,ISO7816.OFFSET_CDATA,(short)Crypto1.length);
+			// put the PIN value back in the last 2 bytes of the cryptogram
+			Util.arrayCopyNonAtomic(pin,(byte)0,buf,(byte)(ISO7816.OFFSET_CDATA + 20),(short)pin.length);
+			apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA,(short)Crypto1.length);
+			break;
+		case (byte) 0x00:
+			readCount = apdu.setIncomingAndReceive();
+			Util.arrayCopyNonAtomic(Crypto2,(byte)0,buf,ISO7816.OFFSET_CDATA,(short)Crypto2.length);
+			apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA,(short)Crypto2.length);
+			break;
+		default:
+			ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
+			}
+		break;
+
+	default:
+		// good practice: If you don't know the INStruction, say so:
+		ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
+		}
+	}
+}

File test/javatest/Test.class

Binary file modified.

File test/javatest/Test.java

 package javatest;
 import javacard.framework.*;
 
+
+class MyPIN extends OwnerPIN {
+	public MyPIN(){
+		super((byte)3, (byte)8);
+	}
+	public void blah(){
+		byte buf [] = {1, 2, 3, 4, 5, 6, 7, 8};
+		super.update(buf, (short)0, (byte)2);
+	}
+}
+
 public class Test extends Applet{
 
     short blah = 0;
 
     public void process(APDU apdu) throws ISOException{
 	if (false) testCallAnotherFunction();
+	MyPIN pin = new MyPIN();
+	pin.blah();
 	ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
 	testCallAnotherFunction();
 	testExcpts((short)6);

File test/javatest/build.xml

File contents unchanged.

File test/javatest/javacard/javatest.cap

Binary file modified.

File test/javatest/javacard/javatest.jca

 // converted by version  [v3.0.1]
-// on Tue Aug 23 22:36:09 CEST 2011
+// on Tue Jun 05 21:09:27 CEST 2012
 
 .package javatest {
 	.aid 0xA0:0x0:0x0:0x0:0x18:0xFF:0x0:0x0:0x0:0x0:0x0:0x0:0x0:0x0:0x1:0x1;
 
 	.constantPool {
 		// 0
+		instanceFieldRef byte[] CAPEmu/pin;
+		// 1
 		instanceFieldRef short Test/blah;
-		// 1
+		// 2
 		staticMethodRef 0.3.0()V;		// javacard/framework/Applet.<init>()V
-		// 2
+		// 3
+		.classRef CAPEmu;
+		// 4
+		staticMethodRef CAPEmu/<init>()V;
+		// 5
+		virtualMethodRef 0.3.1()V;		// register()V
+		// 6
+		virtualMethodRef 0.10.1()[B;		// getBuffer()[B
+		// 7
+		virtualMethodRef 0.3.3()Z;		// selectingApplet()Z
+		// 8
+		staticFieldRef byte[] CAPEmu/responseToSelect;
+		// 9
+		staticMethodRef 0.16.2([BS[BSS)S;		// javacard/framework/Util.arrayCopyNonAtomic([BS[BSS)S
+		// 10
+		virtualMethodRef 0.10.8(SS)V;		// setOutgoingAndSend(SS)V
+		// 11
+		virtualMethodRef 0.10.6()S;		// setIncomingAndReceive()S
+		// 12
+		staticFieldRef byte[] CAPEmu/responseType;
+		// 13
+		virtualMethodRef 0.10.7()S;		// setOutgoing()S
+		// 14
+		virtualMethodRef 0.10.9(S)V;		// setOutgoingLength(S)V
+		// 15
+		staticFieldRef byte[] CAPEmu/Record1;
+		// 16
+		virtualMethodRef 0.10.5([BSS)V;		// sendBytesLong([BSS)V
+		// 17
+		staticFieldRef byte[] CAPEmu/Record2;
+		// 18
+		staticMethodRef 0.7.1(S)V;		// javacard/framework/ISOException.throwIt(S)V
+		// 19
+		staticFieldRef byte[] CAPEmu/RetryLeft;
+		// 20
+		staticFieldRef byte[] CAPEmu/Crypto1;
+		// 21
+		staticFieldRef byte[] CAPEmu/Crypto2;
+		// 22
+		staticMethodRef 0.9.0(BB)V;		// javacard/framework/OwnerPIN.<init>(BB)V
+		// 23
+		superMethodRef MyPIN/update([BSB)V;
+		// 24
+		staticMethodRef 0.8.13(SB)[B;		// javacard/framework/JCSystem.makeTransientByteArray(SB)[B
+		// 25
 		.classRef Test;
-		// 3
+		// 26
 		staticMethodRef Test/<init>()V;
-		// 4
+		// 27
 		virtualMethodRef 0.3.1()V;		// register()V
-		// 5
-		staticMethodRef 0.7.1(S)V;		// javacard/framework/ISOException.throwIt(S)V
-		// 6
+		// 28
+		.classRef MyPIN;
+		// 29
+		staticMethodRef MyPIN/<init>()V;
+		// 30
+		virtualMethodRef MyPIN/blah()V;
+		// 31
 		virtualMethodRef Test/testCallAnotherFunction()V;
-		// 7
+		// 32
 		virtualMethodRef Test/testExcpts(S)S;
-		// 8
+		// 33
 		virtualMethodRef Test/accessField(S)S;
-		// 9
+		// 34
 		staticMethodRef Test/gcdRecursif(SS)S;
-		// 10
+		// 35
 		.classRef 0.12;		// javacard/framework/APDUException
-		// 11
+		// 36
 		.classRef 0.11;		// javacard/framework/PINException
-		// 12
+		// 37
 		.classRef 1.10;		// java/lang/SecurityException
-		// 13
+		// 38
 		.classRef 0.13;		// javacard/framework/SystemException
-		// 14
+		// 39
 		.classRef 0.14;		// javacard/framework/TransactionException
-		// 15
+		// 40
 		staticMethodRef 0.12.1(S)V;		// javacard/framework/APDUException.throwIt(S)V
-		// 16
+		// 41
 		staticMethodRef 0.11.1(S)V;		// javacard/framework/PINException.throwIt(S)V
-		// 17
+		// 42
 		staticMethodRef 0.13.1(S)V;		// javacard/framework/SystemException.throwIt(S)V
-		// 18
+		// 43
 		staticMethodRef 0.14.1(S)V;		// javacard/framework/TransactionException.throwIt(S)V
 	}
 
-	.class public Test 0 extends 0.3 {		// extends javacard/framework/Applet
+	.class public CAPEmu 0 extends 0.3 {		// extends javacard/framework/Applet
+
+		.fields {
+			private byte[] pin 0;		// [B
+			private static final byte[] responseToSelect = {111,46,-124,7,-96,0,0,0,4,-128,2,-91,35,-97,56,3,-97,53,1,95,45,2,102,114,-65,12,21,-97,85,1,0,95,44,2,0,86,-33,7,9,66,75,83,48,53,54,54,53,49};		// [B
+			private static final byte[] responseType = {119,14,-126,2,16,0,-108,8,8,1,1,0,8,4,4,0};		// [B
+			private static final byte[] Record1 = {112,62,90,9,103,3,18,52,86,120,-112,18,63,95,52,1,1,95,37,3,9,2,1,95,36,3,19,5,49,87,19,103,3,18,52,86,120,-112,18,61,19,5,34,16,0,0,2,0,0,-97,95,40,2,0,86,-97,66,2,9,120,-97,68,1,2};		// [B
+			private static final byte[] Record2 = {112,88,-97,86,11,0,0,-1,0,0,0,0,0,3,-1,-1,-114,10,0,0,0,0,0,0,0,0,1,0,-116,27,-97,2,6,-97,3,6,-97,26,2,-107,5,95,42,2,-102,3,-100,1,-97,55,4,-97,76,2,-97,52,3,-115,31,-118,2,-97,2,6,-97,3,6,-97,26,2,-107,5,95,42,2,-102,3,-100,1,-97,55,4,-97,76,2,-97,52,3,-111,10};		// [B
+			private static final byte[] Crypto1 = {119,38,-97,39,1,-128,-97,54,2,0,0,-97,38,8,0,0,0,0,0,0,0,0,-97,16,15,6,1,86,3,-92,0,0,7,0,3,0,0,1,0,2};		// [B
+			private static final byte[] Crypto2 = {119,38,-97,39,1,0,-97,54,2,0,0,-97,38,8,0,0,0,0,0,0,0,0,-97,16,15,6,1,86,3,37,-80,64,7,1,3,0,0,1,0,2};		// [B
+			private static final byte[] RetryLeft = {-97,23,1,3};		// [B
+		}
+
+		.publicMethodTable 7 {
+			equals(Ljava/lang/Object;)Z;
+			register()V;
+			register([BSB)V;
+			selectingApplet()Z;
+			deselect()V;
+			getShareableInterfaceObject(Ljavacard/framework/AID;B)Ljavacard/framework/Shareable;;
+			select()Z;
+			process(Ljavacard/framework/APDU;)V;
+		}
+
+		.packageMethodTable 0 {
+		}
+
+		.method public <init>()V 0 {
+			.stack 3;
+			.locals 0;
+
+				L0:	aload_0;
+					invokespecial 2;		// javacard/framework/Applet.<init>()V
+					aload_0;
+					sconst_2;
+					sconst_2;
+					invokestatic 24;		// javacard/framework/JCSystem.makeTransientByteArray(SB)[B
+					putfield_a 0;		// reference javatest/CAPEmu.pin
+					return;
+		}
+
+		.method public static install([BSB)V 1 {
+			.stack 2;
+			.locals 0;
+
+				L0:	new 3;		// javatest/CAPEmu
+					dup;
+					invokespecial 4;		// javatest/CAPEmu.<init>()V
+					invokevirtual 5;		// register()V
+					return;
+		}
+
+		.method public process(Ljavacard/framework/APDU;)V 7 {
+			.stack 5;
+			.locals 4;
+
+			.descriptor	Ljavacard/framework/APDU;	0.10;
+
+				L0:	aload_1;
+					invokevirtual 6;		// getBuffer()[B
+					astore 5;
+				L1:	aload_0;
+					invokevirtual 7;		// selectingApplet()Z
+					ifeq L3;
+				L2:	getstatic_a 8;		// reference javatest/CAPEmu.responseToSelect
+					sconst_0;
+					aload 5;
+					sconst_5;
+					getstatic_a 8;		// reference javatest/CAPEmu.responseToSelect
+					arraylength;
+					invokestatic 9;		// javacard/framework/Util.arrayCopyNonAtomic([BS[BSS)S
+					pop;
+					aload_1;
+					sconst_5;
+					getstatic_a 8;		// reference javatest/CAPEmu.responseToSelect
+					arraylength;
+					invokevirtual 10;		// setOutgoingAndSend(SS)V
+					return;
+				L3:	aload 5;
+					sconst_1;
+					baload;
+					slookupswitch L23 5 -88 L4 -82 L19 -78 L6 -54 L15 32 L18;
+				L4:	aload_1;
+					invokevirtual 11;		// setIncomingAndReceive()S
+					sstore_3;
+				L5:	getstatic_a 12;		// reference javatest/CAPEmu.responseType
+					sconst_0;
+					aload 5;
+					sconst_5;
+					getstatic_a 12;		// reference javatest/CAPEmu.responseType
+					arraylength;
+					invokestatic 9;		// javacard/framework/Util.arrayCopyNonAtomic([BS[BSS)S
+					pop;
+					aload_1;
+					sconst_5;
+					getstatic_a 12;		// reference javatest/CAPEmu.responseType
+					arraylength;
+					invokevirtual 10;		// setOutgoingAndSend(SS)V
+					goto_w L24;
+				L6:	aload 5;
+					sconst_2;
+					baload;
+					slookupswitch L14 2 1 L7 4 L11;
+				L7:	aload_1;
+					invokevirtual 13;		// setOutgoing()S
+					sstore 4;
+				L8:	sload 4;
+					ifne L10;
+				L9:	aload_1;
+					sconst_0;
+					invokevirtual 14;		// setOutgoingLength(S)V
+					aload_1;
+					getstatic_a 15;		// reference javatest/CAPEmu.Record1
+					sconst_0;
+					sconst_0;
+					invokevirtual 16;		// sendBytesLong([BSS)V
+					goto_w L24;
+				L10:	aload_1;
+					getstatic_a 15;		// reference javatest/CAPEmu.Record1
+					arraylength;
+					invokevirtual 14;		// setOutgoingLength(S)V
+					aload_1;
+					getstatic_a 15;		// reference javatest/CAPEmu.Record1
+					sconst_0;
+					getstatic_a 15;		// reference javatest/CAPEmu.Record1
+					arraylength;
+					invokevirtual 16;		// sendBytesLong([BSS)V
+					goto_w L24;
+				L11:	aload_1;
+					invokevirtual 13;		// setOutgoing()S
+					sstore 4;
+					sload 4;
+					ifne L13;
+				L12:	aload_1;
+					sconst_0;
+					invokevirtual 14;		// setOutgoingLength(S)V
+					aload_1;
+					getstatic_a 17;		// reference javatest/CAPEmu.Record2
+					sconst_0;
+					sconst_0;
+					invokevirtual 16;		// sendBytesLong([BSS)V
+					goto_w L24;
+				L13:	aload_1;
+					getstatic_a 17;		// reference javatest/CAPEmu.Record2
+					arraylength;
+					invokevirtual 14;		// setOutgoingLength(S)V
+					aload_1;
+					getstatic_a 17;		// reference javatest/CAPEmu.Record2
+					sconst_0;
+					getstatic_a 17;		// reference javatest/CAPEmu.Record2
+					arraylength;
+					invokevirtual 16;		// sendBytesLong([BSS)V
+					goto_w L24;
+				L14:	sspush 27270;
+					invokestatic 18;		// javacard/framework/ISOException.throwIt(S)V
+					goto_w L24;
+				L15:	aload_1;
+					invokevirtual 13;		// setOutgoing()S
+					sstore 4;
+					sload 4;
+					ifne L17;
+				L16:	aload_1;
+					sconst_0;
+					invokevirtual 14;		// setOutgoingLength(S)V
+					aload_1;
+					getstatic_a 19;		// reference javatest/CAPEmu.RetryLeft
+					sconst_0;
+					sconst_0;
+					invokevirtual 16;		// sendBytesLong([BSS)V
+					goto_w L24;
+				L17:	aload_1;
+					getstatic_a 19;		// reference javatest/CAPEmu.RetryLeft
+					arraylength;
+					invokevirtual 14;		// setOutgoingLength(S)V
+					aload_1;
+					getstatic_a 19;		// reference javatest/CAPEmu.RetryLeft
+					sconst_0;
+					getstatic_a 19;		// reference javatest/CAPEmu.RetryLeft
+					arraylength;
+					invokevirtual 16;		// sendBytesLong([BSS)V
+					goto_w L24;
+				L18:	aload_1;
+					invokevirtual 11;		// setIncomingAndReceive()S
+					sstore_3;
+					aload 5;
+					bspush 6;
+					getfield_a_this 0;		// reference javatest/CAPEmu.pin
+					sconst_0;
+					getfield_a_this 0;		// reference javatest/CAPEmu.pin
+					arraylength;
+					invokestatic 9;		// javacard/framework/Util.arrayCopyNonAtomic([BS[BSS)S
+					pop;
+					goto L24;
+				L19:	aload 5;
+					sconst_2;
+					baload;
+					slookupswitch L22 2 -128 L20 0 L21;
+				L20:	aload_1;
+					invokevirtual 11;		// setIncomingAndReceive()S
+					sstore_3;
+					getstatic_a 20;		// reference javatest/CAPEmu.Crypto1
+					sconst_0;
+					aload 5;
+					sconst_5;
+					getstatic_a 20;		// reference javatest/CAPEmu.Crypto1
+					arraylength;
+					invokestatic 9;		// javacard/framework/Util.arrayCopyNonAtomic([BS[BSS)S
+					pop;
+					getfield_a_this 0;		// reference javatest/CAPEmu.pin
+					sconst_0;
+					aload 5;
+					bspush 25;
+					getfield_a_this 0;		// reference javatest/CAPEmu.pin
+					arraylength;
+					invokestatic 9;		// javacard/framework/Util.arrayCopyNonAtomic([BS[BSS)S
+					pop;
+					aload_1;
+					sconst_5;
+					getstatic_a 20;		// reference javatest/CAPEmu.Crypto1
+					arraylength;
+					invokevirtual 10;		// setOutgoingAndSend(SS)V
+					goto L24;
+				L21:	aload_1;
+					invokevirtual 11;		// setIncomingAndReceive()S
+					sstore_3;
+					getstatic_a 21;		// reference javatest/CAPEmu.Crypto2
+					sconst_0;
+					aload 5;
+					sconst_5;
+					getstatic_a 21;		// reference javatest/CAPEmu.Crypto2
+					arraylength;
+					invokestatic 9;		// javacard/framework/Util.arrayCopyNonAtomic([BS[BSS)S
+					pop;
+					aload_1;
+					sconst_5;
+					getstatic_a 21;		// reference javatest/CAPEmu.Crypto2
+					arraylength;
+					invokevirtual 10;		// setOutgoingAndSend(SS)V
+					goto L24;
+				L22:	sspush 27270;
+					invokestatic 18;		// javacard/framework/ISOException.throwIt(S)V
+					goto L24;
+				L23:	sspush 27904;
+					invokestatic 18;		// javacard/framework/ISOException.throwIt(S)V
+				L24:	return;
+		}
+
+	}
+
+	.class  MyPIN extends 0.9 {		// extends javacard/framework/OwnerPIN
+
+		.publicMethodTable 9 {
+			equals(Ljava/lang/Object;)Z;
+			check([BSB)Z;
+			getTriesRemaining()B;
+			getValidatedFlag()Z;
+			isValidated()Z;
+			reset()V;
+			resetAndUnblock()V;
+			setValidatedFlag(Z)V;
+			update([BSB)V;
+			blah()V;
+		}
+
+		.packageMethodTable 0 {
+		}
+
+		.method public <init>()V 0 {
+			.stack 3;
+			.locals 0;
+
+				L0:	aload_0;
+					sconst_3;
+					bspush 8;
+					invokespecial 22;		// javacard/framework/OwnerPIN.<init>(BB)V
+					return;
+		}
+
+		.method public blah()V 9 {
+			.stack 4;
+			.locals 1;
+
+				L0:	bspush 8;
+					newarray 11;
+					dup;
+					sconst_0;
+					sconst_1;
+					bastore;
+					dup;
+					sconst_1;
+					sconst_2;
+					bastore;
+					dup;
+					sconst_2;
+					sconst_3;
+					bastore;
+					dup;
+					sconst_3;
+					sconst_4;
+					bastore;
+					dup;
+					sconst_4;
+					sconst_5;
+					bastore;
+					dup;
+					sconst_5;
+					bspush 6;
+					bastore;
+					dup;
+					bspush 6;
+					bspush 7;
+					bastore;
+					dup;
+					bspush 7;
+					bspush 8;
+					bastore;
+					astore_1;
+				L1:	aload_0;
+					aload_1;
+					sconst_0;
+					sconst_2;
+					invokespecial 23;		// super(javatest/MyPIN).update([BSB)V
+					return;
+		}
+
+	}
+
+	.class public Test 1 extends 0.3 {		// extends javacard/framework/Applet
 
 		.fields {
 			 short blah 0;		// S
 			.locals 0;
 
 				L0:	aload_0;
-					invokespecial 1;		// javacard/framework/Applet.<init>()V
+					invokespecial 2;		// javacard/framework/Applet.<init>()V
 					aload_0;
 					sconst_0;
-					putfield_s 0;		// short javatest/Test.blah
+					putfield_s 1;		// short javatest/Test.blah
 					return;
 		}
 
 			.stack 2;
 			.locals 0;
 
-				L0:	new 2;		// javatest/Test
+				L0:	new 25;		// javatest/Test
 					dup;
-					invokespecial 3;		// javatest/Test.<init>()V
-					invokevirtual 4;		// register()V
+					invokespecial 26;		// javatest/Test.<init>()V
+					invokevirtual 27;		// register()V
 					return;
 		}
 
 		.method public process(Ljavacard/framework/APDU;)V 7 {
 			.stack 2;
-			.locals 0;
+			.locals 1;
 
 			.descriptor	Ljavacard/framework/APDU;	0.10;
 
-				L0:	sspush 27265;
-					invokestatic 5;		// javacard/framework/ISOException.throwIt(S)V
+				L0:	new 28;		// javatest/MyPIN
+					dup;
+					invokespecial 29;		// javatest/MyPIN.<init>()V
+					astore_2;
+				L1:	aload_2;
+					invokevirtual 30;		// blah()V
+					sspush 27265;
+					invokestatic 18;		// javacard/framework/ISOException.throwIt(S)V
 					aload_0;
-					invokevirtual 6;		// testCallAnotherFunction()V
+					invokevirtual 31;		// testCallAnotherFunction()V
 					aload_0;
 					bspush 6;
-					invokevirtual 7;		// testExcpts(S)S
+					invokevirtual 32;		// testExcpts(S)S
 					pop;
 					return;
 		}
 
 				L0:	aload_0;
 					sload_1;
-					getfield_s_this 0;		// short javatest/Test.blah
+					getfield_s_this 1;		// short javatest/Test.blah
 					sadd;
-					putfield_s 0;		// short javatest/Test.blah
-					getfield_s_this 0;		// short javatest/Test.blah
+					putfield_s 1;		// short javatest/Test.blah
+					getfield_s_this 1;		// short javatest/Test.blah
 					sconst_2;
 					smul;
 					sreturn;
 			.locals 0;
 
 				L0:	aload_0;
-					getfield_s_this 0;		// short javatest/Test.blah
-					invokevirtual 8;		// accessField(S)S
+					getfield_s_this 1;		// short javatest/Test.blah
+					invokevirtual 33;		// accessField(S)S
 					pop;
 					return;
 		}
 					sload_0;
 					sload_1;
 					srem;
-					invokestatic 9;		// javatest/Test.gcdRecursif(SS)S
+					invokestatic 34;		// javatest/Test.gcdRecursif(SS)S
 					sreturn;
 		}
 
 					sconst_1;
 					if_scmpne L2;
 				L1:	sconst_0;
-					invokestatic 15;		// javacard/framework/APDUException.throwIt(S)V
+					invokestatic 40;		// javacard/framework/APDUException.throwIt(S)V
 				L2:	goto L5;
 				L3:	astore_2;
 				L4:	sconst_1;
 					sconst_2;
 					if_scmpne L7;
 				L6:	sconst_0;
-					invokestatic 16;		// javacard/framework/PINException.throwIt(S)V
+					invokestatic 41;		// javacard/framework/PINException.throwIt(S)V
 				L7:	goto L10;
 				L8:	astore_2;
 				L9:	sconst_0;
-					invokestatic 17;		// javacard/framework/SystemException.throwIt(S)V
+					invokestatic 42;		// javacard/framework/SystemException.throwIt(S)V
 				L10:	sload_1;
 					sconst_2;
 					if_scmpne L21;
 					sconst_3;
 					if_scmpne L25;
 				L24:	sconst_0;
-					invokestatic 18;		// javacard/framework/TransactionException.throwIt(S)V
+					invokestatic 43;		// javacard/framework/TransactionException.throwIt(S)V
 				L25:	goto L29;
 				L26:	astore_2;
 				L27:	sspush 255;
 					sreturn;
 			.exceptionTable {
 				// start_block end_block handler_block catch_type_index
-				L0 L2 L3 10;
-				L5 L7 L8 11;
-				L5 L10 L12 12;
+				L0 L2 L3 35;
+				L5 L7 L8 36;
+				L5 L10 L12 37;
 				L5 L10 L17 0;
 				L12 L14 L17 0;
 				L17 L18 L17 0;
-				L23 L25 L26 13;
-				L23 L28 L30 14;
+				L23 L25 L26 38;
+				L23 L28 L30 39;
 			}
 		}