Example #1
0
 /**
  * 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);
 }
Example #2
0
  /** 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);
  }