/** * Generate an assymetric RSA key pair according to ISO7816-8, Section 5.1. We only support RSA * 1024 bit at the moment, and return data in simple TLV data objects, tags 81 and 82. * * <p>Successful MSE command has to be performed prior to this one. */ private void processGenerateAssymetricKeyPair(APDU apdu) { // This is only valid in state initial (at the moment) if (state != STATE_INITIAL) { ISOException.throwIt(SW_INS_NOT_SUPPORTED); } byte[] buf = apdu.getBuffer(); byte p1 = buf[OFFSET_P1]; byte p2 = buf[OFFSET_P2]; if (p1 != (byte) 0x80 || p2 != (byte) 0x00) { ISOException.throwIt(SW_INCORRECT_P1P2); } if (currentPrivateKey[0] == null) { ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED); } KeyPair pair = new KeyPair(tempKeyPublic, (RSAPrivateCrtKey) currentPrivateKey[0]); pair.genKeyPair(); // Sanity check, the KeyPair class should regenerate the keys "in place". if (pair.getPrivate() != currentPrivateKey[0] || pair.getPublic() != tempKeyPublic) { ISOException.throwIt(SW_DATA_INVALID); } apdu.setOutgoing(); short len = (short) 0; short offset = 0; buf[offset++] = (byte) 0x81; len = tempKeyPublic.getModulus(buf, (short) (offset + 2)); buf[offset++] = (byte) 0x81; buf[offset++] = (byte) len; offset += len; buf[offset++] = (byte) 0x82; len = tempKeyPublic.getExponent(buf, (short) (offset + 1)); buf[offset++] = (byte) len; offset += len; apdu.setOutgoingLength(offset); apdu.sendBytes((short) 0, offset); }
/** Process the GET CHALLENGE instruction (0x84) ISO 7816-4, Section 7.5.3 */ private void processGetChallenge(APDU apdu) { if (state != STATE_PERSONALISED) { ISOException.throwIt(SW_INS_NOT_SUPPORTED); } byte[] buf = apdu.getBuffer(); if (buf[OFFSET_P1] != 0x00 || buf[OFFSET_P2] != 0x00) { ISOException.throwIt(SW_INCORRECT_P1P2); } short le = apdu.setOutgoing(); if (le == 0) { ISOException.throwIt(SW_WRONG_LENGTH); } apdu.setOutgoingLength(le); rd.generateData(buf, (short) 0, le); apdu.sendBytes((short) 0, le); }
/** * 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); }