java card平台詳解(三)

來源:互聯網
上載者:User

本章主要從代碼級的角度來看java卡的執行流程。

########################################################################################################

先看一個簡單的java卡的applet代碼(HelloWord):

從下面的代碼可以看出一個java卡應用的簡單構成,install函數和process函數。其它可選介面如select、deselect和uninstall函數這裡沒有。

install函數負責安裝這個應用,進行一些對象的初始化和註冊,告訴jcre這個應用已經被成功安裝,接下來就可以對這個應用進行選擇和其它命令執行。

process函數是應用的最重要的命令處理函數,這裡解析apdu的ins,進行命令指派,相當於native cos的commandDispatcher函數。當然這個樣本比較簡單,僅僅是返回一個helloword字串。

package com.sun.javacard.samples.HelloWorld;import javacard.framework.*;public class HelloWorld extends Applet{    private byte[] echoBytes;    private static final short LENGTH_ECHO_BYTES = 256;    //private test testobj;    /**     * Only this class's install method should create the applet object.     */    protected HelloWorld()    {     //testobj = new test();                //testobj.setsvalue((short)10);        //testobj.setivalue((int)20);        echoBytes = new byte[LENGTH_ECHO_BYTES];        register();    }    /**     * Installs this applet.     * @param bArray the array containing installation parameters     * @param bOffset the starting offset in bArray     * @param bLength the length in bytes of the parameter data in bArray     */    public static void install(byte[] bArray, short bOffset, byte bLength)    {        new HelloWorld();    }    /**     * Processes an incoming APDU.     * @see APDU     * @param apdu the incoming APDU     * @exception ISOException with the response bytes per ISO 7816-4     */    public void process(APDU apdu)    {        byte buffer[] = apdu.getBuffer();  short bytesRead = apdu.setIncomingAndReceive();  short echoOffset = (short)0;  while ( bytesRead > 0 ) {            Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echoBytes, echoOffset, bytesRead);            echoOffset += bytesRead;            bytesRead = apdu.receiveBytes(ISO7816.OFFSET_CDATA);        }        apdu.setOutgoing();        apdu.setOutgoingLength( (short) (echoOffset + 5) );        // echo header        apdu.sendBytes( (short)0, (short) 5);        // echo data        apdu.sendBytesLong( echoBytes, (short) 0, echoOffset );    }}

########################################################################################################

上面我們簡單看了一下一個java卡應用的簡單樣本,下面我們將看一下java卡運行時的主函數。

下面這個函數就是java卡的入口main函數,在javacard\framework\Dispatcher.java檔案中。

晶片在做了一些初始化之後,載入這個main函數,交給java虛擬機器進行執行,進入java卡執行流程。

static void main()
 {
  if (!NativeMethods.isCardInitialized())
   cardInit();

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~判斷卡片是否已經“個人化”了,這裡的nativemethods是調用的c介面,庫進行了一層封裝,提供java代碼調用c代碼的一個機制。

  cardReset();

~~~~~~~~~~卡片重新複位

  short sw = 0;
  do
  {
   do
   {
    PrivAccess.resetSelectingAppletFlag();
    PrivAccess.resetProcessMethodFlag();

    theAPDU.complete(sw);

~~~~~~~~~~~~~~~這是APDU介面,負責接收APDU和發送傳回值和錯誤碼,如果卡機沒有下發apdu,則卡片在這裡一直等待接收。對應於native cos的receiveApduHeader

    byte activeInterface = NativeMethods.getActiveInterface();
    try
    {
     theAPDU.verifyLe();
     if (processAndForward())

~~~~~~~~~~~~~~~~~~~~~~該函數進行一些預先處理,如果是開啟通道命令,則開啟相應通道回到接收apdu位置等待接收下一條命令。如果是其它命令,則繼續往下執行
     {
      byte commandChannel = NativeMethods.getCurrentlySelectedChannel();
      if (PrivAccess.getSelectedAppID(commandChannel, activeInterface) == -1)
       ISOException.throwIt((short)27033);
      PrivAccess.setProcessMethodFlag();
      Applet selectedApplet = PrivAccess.getSelectedApplet(commandChannel, activeInterface);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~此函數是擷取當前被選擇的應用
      if (selectedApplet instanceof ExtendedLength)
       theAPDU.markExtendedSupport(true);
      else
       theAPDU.markExtendedSupport(false);
      selectedApplet.process(theAPDU);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~調用被選擇應用的process函數,進行命令處理。相當於native cos的命令指派和處理函數
      if (JCSystem.getTransactionDepth() != 0)
       TransactionException.throwIt((short)1);
     }
     sw = -28672;
    }
    catch (ISOException ex)
    {
     sw = ex.getReason();
    }
    catch (Throwable e)
    {
     sw = 28416;
    }
    if (JCSystem.getTransactionDepth() != 0)
     JCSystem.abortTransaction();
   } while (!thePrivAccess.isGarbageCollectionRequested());
   GarbageCollector.startGC();

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~這裡執行記憶體回收,如果前面執行的代碼有佈建要求記憶體回收位。
  } while (true);
 }

 

 private static boolean processAndForward()
  throws ISOException
 {
  if (theAPDU.isISOInterindustryCLA())
  {
   setAPDUChannel();
   switch (theAPDUBuffer[1])
   {
   default:
    break;

   case -92: 
    if (!theAPDU.isSecureMessagingCLA())
    {
     theDispatcher.selectAPDU(theAPDU);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~選擇應用程式命令,根據aid找到應用,然後執行該應用的select介面。
     return true;
    }
    break;

   case 112: // 'p'
    if (theAPDU.isSecureMessagingCLA())
     ISOException.throwIt((short)26754);
    theDispatcher.manageChannelAPDU(theAPDU);
    return false;
   }
  }
  setAPDUChannel();
  return true;
 }

 

########################################################################################################

從上面可以看出一個java卡應用是如何被成功調用的,可以從中看出java卡和native卡的區別。

 

 

 

 

 

 

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.