Java Code Examples for javacard.framework.APDU#getBuffer()

The following examples show how to use javacard.framework.APDU#getBuffer() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Gpg.java    From OpenPGP-Card with GNU General Public License v3.0 7 votes vote down vote up
private void internalAuthenticate(APDU apdu) {
  byte[] buffer = apdu.getBuffer();
  // PW1 with 0x82
  if (!pins[PIN_INDEX_PW1].isValidated() || !pinSubmitted[1]) {
    ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
  }
  short len = apdu.setIncomingAndReceive();
  if (len > (short) 102 || len != (buffer[ISO7816.OFFSET_LC] & 0xFF)) {
    ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  }
  if (!authenticationKey.getPrivate().isInitialized()) {
    ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
  }
  cipherRSA.init(authenticationKey.getPrivate(), Cipher.MODE_ENCRYPT);
  cipherRSA.doFinal(buffer, ISO7816.OFFSET_CDATA, len, buffer, (short) 0);
  apdu.setOutgoingAndSend((short) 0, RSA_KEY_LENGTH_BYTES);
}
 
Example 2
Source File: IsoApplet.java    From IsoApplet with GNU General Public License v3.0 6 votes vote down vote up
/**
 * \brief Process the PERFORM SECURITY OPERATION apdu (INS=2A).
 *
 * This operation is used for cryptographic operations
 * (Computation of digital signatures, decrypting.).
 *
 * \param apdu The PERFORM SECURITY OPERATION apdu.
 *
 * \throw ISOException SW_SECURITY_STATUS_NOT_SATISFIED, SW_INCORRECT_P1P2 and
 * 			the ones from computeDigitalSignature() and decipher().
 */
private void processPerformSecurityOperation(APDU apdu) throws ISOException {
    byte[] buf = apdu.getBuffer();
    byte p1 = buf[ISO7816.OFFSET_P1];
    byte p2 = buf[ISO7816.OFFSET_P2];

    if( ! pin.isValidated() ) {
        ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
    }

    if(p1 == (byte) 0x9E && p2 == (byte) 0x9A) {
        computeDigitalSignature(apdu);
    } else if(p1 == (byte) 0x80 && p2 == (byte) 0x86) {
        decipher(apdu);
    } else {
        ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
    }

}
 
Example 3
Source File: OCUnitTests.java    From JCMathLib with MIT License 6 votes vote down vote up
void test_BN_ADD_MOD(APDU apdu, short dataLen) {
    byte[] apdubuf = apdu.getBuffer();
    short p1 = (short) (apdubuf[ISO7816.OFFSET_P1] & 0x00FF);
    short p2 = (short) (apdubuf[ISO7816.OFFSET_P2] & 0x00FF);

    PM.check(PM.TRAP_BN_ADD_MOD_1);    
    Bignat num1 = m_testBN1;
    num1.set_size(p1);
    PM.check(PM.TRAP_BN_ADD_MOD_2);
    Bignat num2 = m_testBN2;
    num2.set_size(p2);
    PM.check(PM.TRAP_BN_ADD_MOD_3);
    Bignat mod = m_testBN3;
    mod.set_size((short) (dataLen - p1 - p2));
    PM.check(PM.TRAP_BN_ADD_MOD_4);
    num1.from_byte_array(p1, (short)0, apdubuf, ISO7816.OFFSET_CDATA);
    num2.from_byte_array(p2, (short)0, apdubuf, (short)(ISO7816.OFFSET_CDATA+p1));
    PM.check(PM.TRAP_BN_ADD_MOD_5);
    mod.from_byte_array((short)(dataLen-p1-p2), (short)0, apdubuf, (short)(ISO7816.OFFSET_CDATA+p1+p2));
    PM.check(PM.TRAP_BN_ADD_MOD_6);
    num1.mod_add(num2, mod);
    PM.check(PM.TRAP_BN_ADD_MOD_7);
    short len = num1.copy_to_buffer(apdubuf, (short) 0);
    apdu.setOutgoingAndSend((short) 0, len);
}
 
Example 4
Source File: OCUnitTests.java    From JCMathLib with MIT License 6 votes vote down vote up
void test_BN_MOD(APDU apdu, short dataLen) {
    byte[] apdubuf = apdu.getBuffer();
    short p1 = (short) (apdubuf[ISO7816.OFFSET_P1] & 0x00FF);

    PM.check(PM.TRAP_BN_MOD_1);
    Bignat num = m_testBN1;
    num.set_size(p1);
    PM.check(PM.TRAP_BN_MOD_2);
    Bignat mod = m_testBN2;
    mod.set_size((short) (dataLen - p1));
    PM.check(PM.TRAP_BN_MOD_3);
    num.from_byte_array(p1, (short)0, apdubuf, ISO7816.OFFSET_CDATA);
    mod.from_byte_array((short)(dataLen-p1), (short)0, apdubuf, (short)(ISO7816.OFFSET_CDATA+p1));
    PM.check(PM.TRAP_BN_MOD_4);
    num.mod(mod);
    PM.check(PM.TRAP_BN_MOD_5);
    short len = num.copy_to_buffer(apdubuf, (short) 0);
    apdu.setOutgoingAndSend((short) 0, len);
}
 
Example 5
Source File: OCUnitTests.java    From JCMathLib with MIT License 6 votes vote down vote up
void test_BN_EXP(APDU apdu, short dataLen) {
    byte[] apdubuf = apdu.getBuffer();
    short p1 = (short) (apdubuf[ISO7816.OFFSET_P1] & 0x00FF);
    short p2 = (short) (apdubuf[ISO7816.OFFSET_P2] & 0x00FF);

    PM.check(PM.TRAP_BN_EXP_1);    
    Bignat base = m_testBN1;
    base.set_size(p1);
    PM.check(PM.TRAP_BN_EXP_2);
    Bignat exp = m_testBN2;
    exp.set_size((short) (dataLen - p1));
    PM.check(PM.TRAP_BN_EXP_3);
    Bignat res = m_testBN3;
    res.set_size((short) (m_ecc.MAX_BIGNAT_SIZE / 2));
    PM.check(PM.TRAP_BN_EXP_4);
    base.from_byte_array(p1, (short) 0, apdubuf, ISO7816.OFFSET_CDATA);
    exp.from_byte_array((short) (dataLen - p1), (short) 0, apdubuf, (short)(ISO7816.OFFSET_CDATA+p1));
    PM.check(PM.TRAP_BN_EXP_5);
    res.exponentiation(base, exp);
    PM.check(PM.TRAP_BN_EXP_6);
    short len = res.copy_to_buffer(apdubuf, (short) 0);
    apdu.setOutgoingAndSend((short) 0, len);
}
 
Example 6
Source File: OCUnitTests.java    From JCMathLib with MIT License 6 votes vote down vote up
void test_BN_MUL_MOD(APDU apdu, short dataLen) {
    byte[] apdubuf = apdu.getBuffer();
    short p1 = (short) (apdubuf[ISO7816.OFFSET_P1] & 0x00FF);
    short p2 = (short) (apdubuf[ISO7816.OFFSET_P2] & 0x00FF);

    PM.check(PM.TRAP_BN_MUL_MOD_1);    
    Bignat num1 = m_testBN1;
    num1.set_size(p1);
    PM.check(PM.TRAP_BN_MUL_MOD_2);
    Bignat num2 = m_testBN2;
    num2.set_size(p2);
    PM.check(PM.TRAP_BN_MUL_MOD_3);
    Bignat mod = m_testBN3;
    mod.set_size((short) (dataLen - p1 - p2));
    PM.check(PM.TRAP_BN_MUL_MOD_4);
    num1.from_byte_array(p1, (short)0, apdubuf, ISO7816.OFFSET_CDATA);
    num2.from_byte_array(p2, (short)0, apdubuf, (short)(ISO7816.OFFSET_CDATA+p1));
    mod.from_byte_array((short)(dataLen-p1-p2), (short)0, apdubuf, (short)(ISO7816.OFFSET_CDATA+p1+p2));
    PM.check(PM.TRAP_BN_MUL_MOD_5);
    num1.mod_mult(num1, num2, mod);
    PM.check(PM.TRAP_BN_MUL_MOD_6);
    short len = num1.copy_to_buffer(apdubuf, (short) 0);
    apdu.setOutgoingAndSend((short) 0, len);
}
 
Example 7
Source File: TransmitManager.java    From GidsApplet with GNU General Public License v3.0 5 votes vote down vote up
private short doChainingOrExtAPDUWithBuffer(APDU apdu, byte[] databuffer, short bufferlen) throws ISOException {
    
    short recvLen = apdu.setIncomingAndReceive();
    byte[] buf = apdu.getBuffer();
    // Receive data (short or extended).
    while (recvLen > 0) {
        if((short)(chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS] + recvLen) > bufferlen) {
            ISOException.throwIt(ISO7816.SW_FILE_FULL);
        }
        Util.arrayCopyNonAtomic(buf, ISO7816.OFFSET_CDATA, databuffer, chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS], recvLen);
        chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS] += recvLen;
        recvLen = apdu.receiveBytes(ISO7816.OFFSET_CDATA);
    }

    if(isCommandChainingCLA(apdu)) {
        // We are still in the middle of a chain, otherwise there would not have been a chaining CLA.
        // Make sure the caller does not forget to return as the data should only be interpreted
        // when the chain is completed (when using this method).
        ISOException.throwIt(ISO7816.SW_NO_ERROR);
        return (short)0;
    } else {
        // Chain has ended or no chaining.
        // We did receive the data, everything is fine.
        // Reset the current position in ram_buf.
        recvLen = (short) (recvLen + chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS]);
        chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS] = 0;
        return recvLen;
    }
}
 
Example 8
Source File: IsoApplet.java    From IsoApplet with GNU General Public License v3.0 5 votes vote down vote up
/**
 * \brief Receive the data sent by chaining or extended apdus and store it in ram_buf.
 *
 * This is a convienience method if large data has to be accumulated using command chaining
 * or extended apdus. The apdu must be in the INITIAL state, i.e. setIncomingAndReceive()
 * might not have been called already.
 *
 * \param apdu The apdu object in the initial state.
 *
 * \throw ISOException SW_WRONG_LENGTH
 */
private short doChainingOrExtAPDU(APDU apdu) throws ISOException {
    byte[] buf = apdu.getBuffer();
    short recvLen = apdu.setIncomingAndReceive();
    short offset_cdata = apdu.getOffsetCdata();

    // Receive data (short or extended).
    while (recvLen > 0) {
        if((short)(ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS] + recvLen) > RAM_BUF_SIZE) {
            ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        }
        Util.arrayCopyNonAtomic(buf, offset_cdata, ram_buf, ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS], recvLen);
        ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS] += recvLen;
        recvLen = apdu.receiveBytes(offset_cdata);
    }

    if(isCommandChainingCLA(apdu)) {
        // We are still in the middle of a chain, otherwise there would not have been a chaining CLA.
        // Make sure the caller does not forget to return as the data should only be interpreted
        // when the chain is completed (when using this method).
        ISOException.throwIt(ISO7816.SW_NO_ERROR);
        return (short)0;
    } else {
        // Chain has ended or no chaining.
        // We did receive the data, everything is fine.
        // Reset the current position in ram_buf.
        recvLen = (short) (recvLen + ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS]);
        ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS] = 0;
        return recvLen;
    }
}
 
Example 9
Source File: GidsApplet.java    From GidsApplet with GNU General Public License v3.0 5 votes vote down vote up
/**
 * \brief Process the PERFORM SECURITY OPERATION apdu (INS=2A).
 *
 * This operation is used for cryptographic operations
 * (Computation of digital signatures, decrypting.).
 *
 * \param apdu The PERFORM SECURITY OPERATION apdu.
 *
 * \throw ISOException SW_SECURITY_STATUS_NOT_SATISFIED, SW_INCORRECT_P1P2 and
 * 			the ones from computeDigitalSignature() and decipher().
 */
private void processPerformSecurityOperation(APDU apdu) throws ISOException {
    byte[] buf = apdu.getBuffer();
    byte p1 = buf[ISO7816.OFFSET_P1];
    byte p2 = buf[ISO7816.OFFSET_P2];

    if(p1 == (byte) 0x9E && p2 == (byte) 0x9A) {
        computeDigitalSignature(apdu);
    } else if(p1 == (byte) 0x80 && p2 == (byte) 0x86) {
        decipher(apdu);
    } else {
        ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
    }

}
 
Example 10
Source File: Gpg.java    From OpenPGP-Card with GNU General Public License v3.0 5 votes vote down vote up
private void computeSignature(APDU apdu) {
  byte[] buffer = apdu.getBuffer();
  short length = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);
  // Make sure that DigestInfo is <= 40% of the RSA key length.
  if ((short) (length * 4) > (short) (RSA_KEY_LENGTH_BYTES * 10) ||
      apdu.setIncomingAndReceive() != length) {
    ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  }
  if (!pinSubmitted[PIN_INDEX_PW1] || !pins[PIN_INDEX_PW1].isValidated()) {
    ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
  }
  if (!signatureKey.getPrivate().isInitialized()) {
    ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
  }
  if (pinValidForMultipleSignatures == (byte) 0) {
    pinSubmitted[PIN_INDEX_PW1] = false;
  }

  cipherRSA.init(signatureKey.getPrivate(), Cipher.MODE_ENCRYPT);
  cipherRSA.doFinal(buffer, ISO7816.OFFSET_CDATA, length, buffer, (short) 0);
  JCSystem.beginTransaction();
  if (signatureCounter[2] != (byte) 0xFF) {
    signatureCounter[2] = (byte) ((signatureCounter[2] & 0xFF) + 1);
  } else {
    signatureCounter[2] = 0;
    if (signatureCounter[1] != (byte) 0xFF) {
      signatureCounter[1] = (byte) ((signatureCounter[1] & 0xFF) + 1);
    } else if (signatureCounter[0] != (byte) 0xFF) {
      signatureCounter[1] = 0;
      signatureCounter[0] = (byte) ((signatureCounter[0] & 0xFF) + 1);
    } else {
      JCSystem.abortTransaction();
      ISOException.throwIt(ISO7816.SW_FILE_FULL);
    }
  }
  JCSystem.commitTransaction();
  apdu.setOutgoingAndSend((short) 0, RSA_KEY_LENGTH_BYTES);
}
 
Example 11
Source File: GaussKeyCard.java    From gauss-key-card with Apache License 2.0 5 votes vote down vote up
public void
process(APDU apdu)
{
	final byte[] buffer = apdu.getBuffer();

	if (selectingApplet()) {
		return;
	}

	// We only support the proprietary class.
	if ((buffer[ISO7816.OFFSET_CLA] & (byte)0x80) != (byte)0x80) {
		ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
		return;
	}

	switch (buffer[ISO7816.OFFSET_INS]) {
	case INS_GET_PUBLIC_KEY:
		processGetPublicKey(apdu);
		break;

	case INS_AUTHENTICATE:
		processAuthenticate(apdu);
		break;

	case INS_GET_CARD_INFO:
		processGetCardInfo(apdu);
		break;

	default:
		ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
	}
}
 
Example 12
Source File: LedgerWalletApplet.java    From ledger-javacard with GNU Affero General Public License v3.0 5 votes vote down vote up
private static void handleAirgapKeyAgreement(APDU apdu) throws ISOException {
    short offset = (short)0;
    byte[] buffer = apdu.getBuffer();
    apdu.setIncomingAndReceive();
    checkAirgapPersonalizationAvailable();
    if (buffer[ISO7816.OFFSET_P1] == P1_INITIATE_PAIRING) {
        if (buffer[ISO7816.OFFSET_LC] != (byte)65) {
            ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        }
        pairingDone = false;
        Crypto.keyPair.genKeyPair();
        Crypto.keyAgreement.init((ECPrivateKey)Crypto.keyPair.getPrivate());
        Crypto.keyAgreement.generateSecret(buffer, ISO7816.OFFSET_CDATA, (short)65, scratch256, (short)0);
        pairingKey.setKey(scratch256, (short)0);
        ((ECPublicKey)Crypto.keyPair.getPublic()).getW(buffer, offset);
        offset += (short)65;
        Crypto.signature.init(attestationPrivate, Signature.MODE_SIGN);
        Crypto.signature.sign(buffer, (short)0, (short)65, buffer, offset);
        offset += (short)(buffer[(short)(offset + 1)] + 2);
        apdu.setOutgoingAndSend((short)0, offset);
    }
    else
    if (buffer[ISO7816.OFFSET_P1] == P1_CONFIRM_PAIRING) {
        if (buffer[ISO7816.OFFSET_LC] != (byte)32) {
            ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        }
        Crypto.initCipherAES(pairingKey, false);
        Crypto.blobEncryptDecryptAES.doFinal(buffer, ISO7816.OFFSET_CDATA, (short)32, scratch256, (short)0);
        pairingKey.setKey(scratch256, (short)0);
        pairingDone = true;
    }
    else {
        ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
    }
}
 
Example 13
Source File: Gpg.java    From OpenPGP-Card with GNU General Public License v3.0 5 votes vote down vote up
/**
 * GET CHALLENGE APDU implementation.
 */
private void getChallenge(APDU apdu) {
  byte[] buffer = apdu.getBuffer();
  short length = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);
  if (length == (short) 0) {
    length = (short) 256;
  }
  randomData.generateData(buffer, (short) 0, length);
  apdu.setOutgoingAndSend((short) 0, length);
}
 
Example 14
Source File: NdefApplet.java    From openjavacard-ndef with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Process a SELECT command
 *
 * This handles only the one case mandated by the NDEF
 * specification: SELECT FIRST-OR-ONLY BY-FILE-ID.
 *
 * The file ID is specified in the APDU contents. It
 * must be exactly two bytes long and also valid.
 *
 * @param apdu to process
 * @throws ISOException on error
 */
private void processSelect(APDU apdu) throws ISOException {
    byte[] buffer = apdu.getBuffer();
    byte p1 = buffer[ISO7816.OFFSET_P1];
    byte p2 = buffer[ISO7816.OFFSET_P2];

    // we only support what the NDEF spec prescribes
    if(p1 != SELECT_P1_BY_FILEID || p2 != SELECT_P2_FIRST_OR_ONLY) {
        ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
    }

    // receive data
    short lc = apdu.setIncomingAndReceive();

    // check length, must be for a file ID
    if(lc != 2) {
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    }

    // retrieve the file ID
    short fileId = Util.getShort(buffer, ISO7816.OFFSET_CDATA);

    // perform selection if the ID is valid
    if(fileId == FILEID_NDEF_CAPABILITIES || fileId == FILEID_NDEF_DATA) {
        vars[VAR_SELECTED_FILE] = fileId;
    } else {
        ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
    }
}
 
Example 15
Source File: GaussKeyCard.java    From gauss-key-card with Apache License 2.0 5 votes vote down vote up
private void
processGetPublicKey(APDU apdu)
{
	final byte[] buffer = apdu.getBuffer();

	final short le = apdu.setOutgoing();

	final ECPublicKey epubk = (ECPublicKey)key1.getPublic();

	short len = epubk.getW(buffer, (short)0);

	len = le > 0 ? (le > len ? len : le) : len;
	apdu.setOutgoingLength(len);
	apdu.sendBytes((short)0, len);
}
 
Example 16
Source File: LedgerWalletApplet.java    From ledger-javacard with GNU Affero General Public License v3.0 4 votes vote down vote up
private static void handleSignMessage(APDU apdu) throws ISOException {
    byte[] buffer = apdu.getBuffer();
    short offset = ISO7816.OFFSET_CDATA;
    if (buffer[ISO7816.OFFSET_P1] == P1_PREPARE_MESSAGE) {
        byte derivationSize = buffer[offset++];
        boolean addressVerified = false;
        if (Util.arrayCompare(buffer, offset, SLIP13_HEAD, (short)0, (short)SLIP13_HEAD.length) == (short)0) {
            addressVerified = true;
        }
        else {
            for (byte i=0; i<derivationSize; i++) {
                if ((Util.arrayCompare(buffer, (short)(offset + 2), BITID_DERIVE, (short)0, (short)BITID_DERIVE.length) == (short)0) ||
                    (Util.arrayCompare(buffer, (short)(offset + 2), BITID_DERIVE_MULTIPLE, (short)0, (short)BITID_DERIVE_MULTIPLE.length) == (short)0)) {
                    addressVerified = true;
                    break;
                }
                offset += 4;
            }
        }
        if (!addressVerified) {
            ISOException.throwIt(ISO7816.SW_WRONG_DATA);
        }
        offset = (short)(ISO7816.OFFSET_CDATA + 1 + 4 * derivationSize);
        short messageLength = (short)(buffer[offset++] & 0xff);
        Crypto.digestFull.reset();
        Crypto.digestFull.update(SIGNMAGIC, (short)0, (short)SIGNMAGIC.length);
        scratch256[(short)100] = (byte)messageLength;
        Crypto.digestFull.update(scratch256, (short)100, (short)1);
        Crypto.digestFull.doFinal(buffer, offset, messageLength, scratch256, (short)32);
        signTransientPrivate(scratch256, (short)0, scratch256, (short)32, scratch256, (short)100);
        Util.arrayFillNonAtomic(scratch256, (short)0, (short)64, (byte)0x00);
        buffer[(short)0] = (byte)0x00;
        TC.ctx[TC.TX_B_MESSAGE_SIGN_READY] = (byte)0x01;
        apdu.setOutgoingAndSend((short)0, (short)1);
    }
    else
    if (buffer[ISO7816.OFFSET_P1] == P1_SIGN_MESSAGE) {
        if (TC.ctx[TC.TX_B_MESSAGE_SIGN_READY] != (byte)0x01) {
            ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
        }
        TC.ctx[TC.TX_B_MESSAGE_SIGN_READY] = (byte)0x00;
        short signatureSize = (short)((short)(scratch256[(short)101] & 0xff) + 2);
        Util.arrayCopyNonAtomic(scratch256, (short)100, buffer, (short)0, signatureSize);
        apdu.setOutgoingAndSend((short)0, signatureSize);
    }
    else {
        ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
    }
}
 
Example 17
Source File: GidsApplet.java    From GidsApplet with GNU General Public License v3.0 4 votes vote down vote up
/**
 * \brief Processes an incoming APDU.
 *
 * \see APDU.
 *
 * \param apdu The incoming APDU.
 */
public void process(APDU apdu) {
    byte buffer[] = apdu.getBuffer();
    byte ins = buffer[ISO7816.OFFSET_INS];

    // No secure messaging at the moment
    if((buffer[ISO7816.OFFSET_CLA] & 0x0C) != 0) {
        ISOException.throwIt(ISO7816.SW_SECURE_MESSAGING_NOT_SUPPORTED);
    }

    transmitManager.processChainInitialization(apdu);

    if((buffer[ISO7816.OFFSET_CLA] & 0xE0) == 0) {
        switch (ins) {
        case INS_ACTIVATE_FILE:
            fs.processActivateFile(apdu);
            break;
        case INS_CREATE_FILE:
            fs.processCreateFile(apdu);
            break;
        case INS_CHANGE_REFERENCE_DATA:
            pinManager.processChangeReferenceData(apdu);
            break;
        case INS_DELETE_FILE:
            fs.processDeleteFile(apdu);
            break;
        case INS_GENERAL_AUTHENTICATE:
            pinManager.processGeneralAuthenticate(apdu);
            break;
        case INS_GENERATE_ASYMMETRIC_KEYPAIR:
            processGenerateAsymmetricKeypair(apdu);
            break;
        case INS_GET_DATA:
            processGetData(apdu);
            break;
        case INS_GET_RESPONSE:
            transmitManager.processGetResponse(apdu);
            break;
        case INS_MANAGE_SECURITY_ENVIRONMENT:
            processManageSecurityEnvironment(apdu);
            break;
        case INS_PERFORM_SECURITY_OPERATION:
            processPerformSecurityOperation(apdu);
            break;
        case INS_PUT_DATA:
            processPutData(apdu);
            break;
        case INS_RESET_RETRY_COUNTER:
            pinManager.processResetRetryCounter(apdu);
            break;
        case ISO7816.INS_SELECT:
            fs.processSelectFile(apdu, selectingApplet());
            break;
        case INS_TERMINATE_DF:
            processTerminateDF(apdu);
            break;
        case INS_VERIFY:
            pinManager.processVerify(apdu);
            break;
        default:
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        } // switch
    } else {
        ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    }
}
 
Example 18
Source File: GidsPINManager.java    From GidsApplet with GNU General Public License v3.0 4 votes vote down vote up
/**
 * \brief Process the VERIFY apdu (INS = 20).
 *
 * This apdu is used to verify a PIN and authenticate the user. A counter is used
 * to limit unsuccessful tries (i.e. brute force attacks).
 *
 * \param apdu The apdu.
 *
 * \throw ISOException SW_INCORRECT_P1P2, ISO7816.SW_WRONG_LENGTH, SW_PIN_TRIES_REMAINING.
 */
public void processVerify(APDU apdu) throws ISOException {
    byte[] buf = apdu.getBuffer();
    short lc;
    GidsPIN pin = null;

    // P1P2 0001 only at the moment. (key-reference 01 = PIN)
    if(buf[ISO7816.OFFSET_P1] != 0x00) {
        ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
    }

    if (buf[ISO7816.OFFSET_P2] == (byte) 0x82) {
        // special resetting code for GIDS
        DeauthenticateAllPin();
        return;
    }

    try {
        pin = GetPINByReference(buf[ISO7816.OFFSET_P2]);
    } catch(NotFoundException e) {
        ISOException.throwIt(ErrorCode.SW_REFERENCE_DATA_NOT_FOUND);
    }

    lc = apdu.setIncomingAndReceive();

    if (pin.getTriesRemaining() == (byte) 0) {
        // pin blocked
        ISOException.throwIt(ISO7816.SW_FILE_INVALID);
    }

    // Lc might be 0, in this case the caller checks if verification is required.
    if((lc > 0 && (lc < pin.GetMinPINSize()) || lc > pin.GetMaxPINSize())) {
        ISOException.throwIt((short) (ErrorCode.SW_PIN_TRIES_REMAINING | pin.getTriesRemaining()));
    }

    // Caller asks if verification is needed.
    if(lc == 0) {
        if (!isInInitializationMode) {
            // Verification required, return remaining tries.
            ISOException.throwIt((short)(ErrorCode.SW_PIN_TRIES_REMAINING | pin.getTriesRemaining()));
        } else {
            // No verification required.
            ISOException.throwIt(ISO7816.SW_NO_ERROR);
        }
    }

    // Check the PIN.
    if(!pin.check(buf, ISO7816.OFFSET_CDATA, (byte) lc)) {
        ISOException.throwIt((short)(ErrorCode.SW_PIN_TRIES_REMAINING | pin.getTriesRemaining()));
    } else {

    }
}
 
Example 19
Source File: LedgerWalletApplet.java    From ledger-javacard with GNU Affero General Public License v3.0 4 votes vote down vote up
private static void handleHashSign(APDU apdu) throws ISOException {
    byte[] buffer = apdu.getBuffer();
    short offset = ISO7816.OFFSET_CDATA;
    byte i;
 byte derivationSize = buffer[offset++];
    offset += (short)(derivationSize * 4);
    short authorizationLength = (short)(buffer[offset++] & 0xff);
    if (TC.ctxP[TC.P_TX_Z_CONSUME_P2SH] == TC.FALSE) {
        boolean verified = false;
        writeIdleText();
        if (TC.ctxP[TC.P_TX_Z_USE_KEYCARD] == TC.TRUE) {
            Util.arrayCopyNonAtomic(TC.ctxP, TC.P_TX_A_OUTPUT_ADDRESS, scratch256, (short)32, (short)(TC.SIZEOF_RIPEMD + 1));
            Crypto.digestScratch.doFinal(scratch256, (short)32, (short)(TC.SIZEOF_RIPEMD + 1), scratch256, (short)(32 + TC.SIZEOF_RIPEMD + 1));
            Crypto.digestScratch.doFinal(scratch256, (short)(32 + TC.SIZEOF_RIPEMD + 1), TC.SIZEOF_SHA256, scratch256, (short)(32 + TC.SIZEOF_RIPEMD + 1));
            short addressOffset = Base58.encode(scratch256, (short)32, (short)(TC.SIZEOF_RIPEMD + 1 + 4), scratch256, (short)100, scratch256, (short)150);
            verified = Keycard.check(scratch256, (short)100, (byte)(addressOffset - 100),
                buffer, offset, (byte)authorizationLength,
                TC.ctxP, TC.P_TX_A_KEYCARD_INDEXES,
                scratch256, (short)150);
        }
        if (!verified) {
            if (!transactionPin.check(buffer, offset, (byte)authorizationLength)) {
                ISOException.throwIt(ISO7816.SW_WRONG_DATA);
            }
        }
    }
    else
    if (TC.ctxP[TC.P_TX_Z_CONSUME_P2SH] != TC.TRUE) {
        ISOException.throwIt(ISO7816.SW_WRONG_DATA);
    }
    offset += authorizationLength;
    Uint32Helper.swap(scratch256, (short)100, buffer, offset);
    offset += 4;
    byte sigHashType = buffer[offset++];
    Uint32Helper.clear(scratch256, (short)104);
    scratch256[(short)104] = sigHashType;
    Crypto.digestFull.doFinal(scratch256, (short)100, (short)8, scratch256, (short)100);
    signTransientPrivate(scratch256, (short)0, scratch256, (short)100, buffer, (short)0);
    short signatureSize = (short)((short)(buffer[1] & 0xff) + 2);
    buffer[signatureSize] = sigHashType;
    TC.clear();
    apdu.setOutgoingAndSend((short)0, (short)(signatureSize + 1));
}
 
Example 20
Source File: PasswordManagerApplet.java    From sim-password-manager with Apache License 2.0 3 votes vote down vote up
private void prng(APDU apdu) {
    byte[] buff = apdu.getBuffer();

    prng(buff, OFFSET_ZERO, AES_BLOCK_LEN);

    apdu.setOutgoingAndSend(OFFSET_ZERO, AES_BLOCK_LEN);
}