Advertisement
Guest User

Untitled

a guest
Mar 30th, 2020
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.72 KB | None | 0 0
  1. /**
  2. * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
  3. *
  4. */
  5.  
  6.  
  7. //Modificat MAX TRANSACTION AMOUNT
  8. //Modificat din byte in short in functia credit si facut
  9. //Modificat scriptul scr
  10. /*
  11. * @(#)Wallet.java 1.11 06/01/03
  12. */
  13.  
  14. package com.oracle.jcclassic.samples.wallet;
  15.  
  16. import javacard.framework.APDU;
  17. import javacard.framework.Applet;
  18. import javacard.framework.ISO7816;
  19. import javacard.framework.ISOException;
  20. import javacard.framework.OwnerPIN;
  21.  
  22. public class Wallet extends Applet {
  23.  
  24. /* constants declaration */
  25.  
  26. // code of CLA byte in the command APDU header
  27. final static byte Wallet_CLA = (byte) 0x80;
  28.  
  29. // codes of INS byte in the command APDU header
  30. final static byte VERIFY = (byte) 0x20;
  31. final static byte CREDIT = (byte) 0x30;
  32. final static byte DEBIT = (byte) 0x40;
  33. final static byte GET_BALANCE = (byte) 0x50;
  34.  
  35. // maximum balance
  36. final static short MAX_BALANCE = 0x7FFF;
  37. // maximum transaction amount
  38. final static short MAX_TRANSACTION_AMOUNT = 600;
  39.  
  40. // maximum number of incorrect tries before the
  41. // PIN is blocked
  42. final static byte PIN_TRY_LIMIT = (byte) 0x03;
  43. // maximum size PIN
  44. final static byte MAX_PIN_SIZE = (byte) 0x08;
  45.  
  46. // signal that the PIN verification failed
  47. final static short SW_VERIFICATION_FAILED = 0x6300;
  48. // signal the the PIN validation is required
  49. // for a credit or a debit transaction
  50. final static short SW_PIN_VERIFICATION_REQUIRED = 0x6301;
  51. // signal invalid transaction amount
  52. // amount > MAX_TRANSACTION_AMOUNT or amount < 0
  53. final static short SW_INVALID_TRANSACTION_AMOUNT = 0x6A83;
  54.  
  55. // signal that the balance exceed the maximum
  56. final static short SW_EXCEED_MAXIMUM_BALANCE = 0x6A84;
  57. // signal the the balance becomes negative
  58. final static short SW_NEGATIVE_BALANCE = 0x6A85;
  59.  
  60. /* instance variables declaration */
  61. OwnerPIN pin;
  62. short balance;
  63.  
  64. private Wallet(byte[] bArray, short bOffset, byte bLength) {
  65.  
  66. // It is good programming practice to allocate
  67. // all the memory that an applet needs during
  68. // its lifetime inside the constructor
  69. pin = new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE);
  70.  
  71. byte iLen = bArray[bOffset]; // aid length
  72. bOffset = (short) (bOffset + iLen + 1);
  73. byte cLen = bArray[bOffset]; // info length
  74. bOffset = (short) (bOffset + cLen + 1);
  75. byte aLen = bArray[bOffset]; // applet data length
  76.  
  77. // The installation parameters contain the PIN
  78. // initialization value
  79. pin.update(bArray, (short) (bOffset + 1), aLen);
  80. register();
  81.  
  82. } // end of the constructor
  83.  
  84. public static void install(byte[] bArray, short bOffset, byte bLength) {
  85. // create a Wallet applet instance
  86. new Wallet(bArray, bOffset, bLength);
  87. } // end of install method
  88.  
  89. @Override
  90. public boolean select() {
  91.  
  92. // The applet declines to be selected
  93. // if the pin is blocked.
  94. if (pin.getTriesRemaining() == 0) {
  95. return false;
  96. }
  97.  
  98. return true;
  99.  
  100. }// end of select method
  101.  
  102. @Override
  103. public void deselect() {
  104.  
  105. // reset the pin value
  106. pin.reset();
  107.  
  108. }
  109.  
  110. @Override
  111. public void process(APDU apdu) {
  112.  
  113. // APDU object carries a byte array (buffer) to
  114. // transfer incoming and outgoing APDU header
  115. // and data bytes between card and CAD
  116.  
  117. // At this point, only the first header bytes
  118. // [CLA, INS, P1, P2, P3] are available in
  119. // the APDU buffer.
  120. // The interface javacard.framework.ISO7816
  121. // declares constants to denote the offset of
  122. // these bytes in the APDU buffer
  123.  
  124. byte[] buffer = apdu.getBuffer();
  125. // check SELECT APDU command
  126.  
  127. if (apdu.isISOInterindustryCLA()) {
  128. if (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4)) {
  129. return;
  130. }
  131. ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
  132. }
  133.  
  134. // verify the reset of commands have the
  135. // correct CLA byte, which specifies the
  136. // command structure
  137. if (buffer[ISO7816.OFFSET_CLA] != Wallet_CLA) {
  138. ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
  139. }
  140.  
  141. switch (buffer[ISO7816.OFFSET_INS]) {
  142. case GET_BALANCE:
  143. getBalance(apdu);
  144. return;
  145. case DEBIT:
  146. debit(apdu);
  147. return;
  148. case CREDIT:
  149. credit(apdu);
  150. return;
  151. case VERIFY:
  152. verify(apdu);
  153. return;
  154. default:
  155. ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
  156. }
  157.  
  158. } // end of process method
  159.  
  160. private void credit(APDU apdu) {
  161.  
  162. // access authentication
  163. if (!pin.isValidated()) {
  164. ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
  165. }
  166.  
  167. byte[] buffer = apdu.getBuffer();
  168.  
  169. // Lc byte denotes the number of bytes in the
  170. // data field of the command APDU
  171. byte numBytes = buffer[ISO7816.OFFSET_LC];
  172.  
  173. // indicate that this APDU has incoming data
  174. // and receive data starting from the offset
  175. // ISO7816.OFFSET_CDATA following the 5 header
  176. // bytes.
  177. byte byteRead = (byte) (apdu.setIncomingAndReceive());
  178.  
  179. // it is an error if the number of data bytes
  180. // read does not match the number in Lc byte
  181. if ((numBytes != 2) || (byteRead != 2)) {
  182. ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  183. }
  184.  
  185. // get the credit amount
  186. short creditAmount = (short) ((buffer[ISO7816.OFFSET_CDATA] << 8) | buffer[ISO7816.OFFSET_CDATA+1]);
  187.  
  188. // check the credit amount
  189. if ((creditAmount > MAX_TRANSACTION_AMOUNT) || (creditAmount < 0)) {
  190. ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
  191. }
  192.  
  193. // check the new balance
  194. if ((short) (balance + creditAmount) > MAX_BALANCE) {
  195. ISOException.throwIt(SW_EXCEED_MAXIMUM_BALANCE);
  196. }
  197.  
  198. // credit the amount
  199. balance = (short) (balance + creditAmount);
  200.  
  201. } // end of deposit method
  202.  
  203. private void debit(APDU apdu) {
  204.  
  205. // access authentication
  206. if (!pin.isValidated()) {
  207. ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
  208. }
  209.  
  210. byte[] buffer = apdu.getBuffer();
  211.  
  212. byte numBytes = (buffer[ISO7816.OFFSET_LC]);
  213.  
  214. byte byteRead = (byte) (apdu.setIncomingAndReceive());
  215.  
  216. if ((numBytes != 1) || (byteRead != 1)) {
  217. ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  218. }
  219.  
  220. // get debit amount
  221. byte debitAmount = buffer[ISO7816.OFFSET_CDATA];
  222.  
  223. // check debit amount
  224. if ((debitAmount > MAX_TRANSACTION_AMOUNT) || (debitAmount < 0)) {
  225. ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
  226. }
  227.  
  228. // check the new balance
  229. if ((short) (balance - debitAmount) < (short) 0) {
  230. ISOException.throwIt(SW_NEGATIVE_BALANCE);
  231. }
  232.  
  233. balance = (short) (balance - debitAmount);
  234.  
  235. } // end of debit method
  236.  
  237. private void getBalance(APDU apdu) {
  238.  
  239. byte[] buffer = apdu.getBuffer();
  240.  
  241. // inform system that the applet has finished
  242. // processing the command and the system should
  243. // now prepare to construct a response APDU
  244. // which contains data field
  245. short le = apdu.setOutgoing();
  246.  
  247. if (le < 2) {
  248. ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  249. }
  250.  
  251. // informs the CAD the actual number of bytes
  252. // returned
  253. apdu.setOutgoingLength((byte) 2);
  254.  
  255. // move the balance data into the APDU buffer
  256. // starting at the offset 0
  257. buffer[0] = (byte) (balance >> 8);
  258. buffer[1] = (byte) (balance & 0xFF);
  259.  
  260. // send the 2-byte balance at the offset
  261. // 0 in the apdu buffer
  262. apdu.sendBytes((short) 0, (short) 2);
  263.  
  264. } // end of getBalance method
  265.  
  266. private void verify(APDU apdu) {
  267.  
  268. byte[] buffer = apdu.getBuffer();
  269. // retrieve the PIN data for validation.
  270. byte byteRead = (byte) (apdu.setIncomingAndReceive());
  271.  
  272. // check pin
  273. // the PIN data is read into the APDU buffer
  274. // at the offset ISO7816.OFFSET_CDATA
  275. // the PIN data length = byteRead
  276. if (pin.check(buffer, ISO7816.OFFSET_CDATA, byteRead) == false) {
  277. ISOException.throwIt(SW_VERIFICATION_FAILED);
  278. }
  279.  
  280. } // end of validate method
  281. } // end of class Wallet
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement