private cardTest() { // Instantiate all object the applet will ever need // pin= new OwnerPIN(MAX_LENGTH, MAX_ATTEMPTS); // if(bArray==null){//check // If no pin is passed as parameter at installation time use default 0000 // pin.update(new byte[] {0x00,0x00,0x00,0x00}, (short) 0, (byte) 0x04); // } // else { // pin.update(bArray, bOffset, bLength); // } try { // Set signature algorithm sig = Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1, false); // Generate the card keys keys.genKeyPair(); // Get the public key k = (RSAPublicKey) keys.getPublic(); // Get the private key k2 = (RSAPrivateKey) keys.getPrivate(); // Initialize the signature object with card private key sig.init(k2, Signature.MODE_SIGN); } catch (CryptoException ex) { ISOException.throwIt((short) (ex.getReason())); } catch (SecurityException ex) { ISOException.throwIt((short) (0x6F10)); } catch (Exception ex) { ISOException.throwIt((short) (0x6F20)); } }
public void process(APDU apdu) { // Good practice: Return 9000 on SELECT if (selectingApplet()) { return; } byte[] buff = apdu.getBuffer(); // Get the incoming APDU // Util.arrayCopy(apdu.getBuffer(),(short) 0, buff,(short) 0,(short) apdu.getBuffer().length);// // apdu.getBuffer(); // Check the CLA /* if(buff[ISO7816.OFFSET_CLA]!=CLA){ ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); } */ // Switch on the instruction code INS switch (buff[ISO7816.OFFSET_INS]) { // Create a test signature using test case SEND_TEST_SIGNATURE: // Sign the test byte and get the signature size size = sig.sign(test, (short) 0, (short) test.length, output, (short) 0); break; // return modulus of public key case SEND_PUB_MOD: // Retrieve the modulus, store it in the output byte array and set the output length size = k.getModulus(output, (short) 0); break; // return exponent of public key case SEND_PUB_EXP: // Retrieve the public exponent, store it in the output byte array and set the output // length size = k.getExponent(output, (short) 0); break; // return exponent of private key given correct pin authentication case SEND_PRV_EXP: // Check that the user is authenticated (correct command 0x80 0x03 0x01 0x00 0x04 0x00 0x00 // 0x00 0x00 0x00) if (buff[ISO7816.OFFSET_P1] == ((byte) 0x01)) { if (buff[ISO7816.OFFSET_LC] != (byte) 0x00) { if (pin.check(buff, (short) (ISO7816.OFFSET_LC + 1), buff[ISO7816.OFFSET_LC])) { size = k2.getExponent(output, (short) 0); pin.reset(); } else { // wrong pin (system should have taken care of decrementing the counter and checking // boundary conditions) ISOException.throwIt(ISO7816.SW_WRONG_DATA); } } else { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); // no pin was sent } } else { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); // wrong command code } // Retrieve the private exponent, store it in the output byte array and set the output // length size = k2.getExponent(output, (short) 0); break; // return size of signature and modulus for testing purposes (they should be the same) case (byte) SEND_KEY_LENGTH: shortToByteArray(keysize); size = (short) 2; Util.arrayCopy(buff, (short) 0, output, (short) 0, size); break; // Sign arbitrary text sent to card case (byte) SIGN_INPUT_DATA: size = (short) buff[ISO7816.OFFSET_LC]; size = sig.sign(buff, (short) (ISO7816.OFFSET_LC + 1), size, output, (short) 0); break; // return the modulus of public keywith a random value sent from the host case (byte) SEND_AUTHENTICATED_PUB_EXP: // Find the size of the random value size = (short) buff[ISO7816.OFFSET_LC]; // If the current key is 2048 bit =256 bytes we need a big array to store all data to sign // TODO limit the size of the input value and do some checks on it bigArray = JCSystem.makeTransientByteArray((short) (size + keysize), JCSystem.CLEAR_ON_RESET); // Update the signature object with that value Util.arrayCopy(buff, (short) (ISO7816.OFFSET_LC + 1), bigArray, (short) 0, size); k.getModulus(bigArray, (short) (size)); // Util.arrayCopy(buff, (short) 0, bigArray, (short) (ISO7816.OFFSET_LC+size+1), len); size = sig.sign(bigArray, (short) 0, (short) bigArray.length, output, (short) 0); break; case (byte) 0x07: size = (short) 2; output[0] = (byte) 0x09; output[1] = (byte) 0x08; break; case (byte) 0x08: short length = 256; // short length = (short) buff.length; size = (short) length; // output[0]=(byte) 0x08; // output[1]=(byte) 0x08; for (short i = 0; i < length; i++) { output[i] = (byte) buff[i]; } break; default: // good practice: If you don't know the INStruction, say so: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } send(apdu); }