Java Code Examples for javacard.framework.APDU#setIncomingAndReceive()
The following examples show how to use
javacard.framework.APDU#setIncomingAndReceive() .
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 | 9 votes |
/** * Store the incoming APDU data in a fixed buffer, the first byte will contain the data length. * * @param pin_type indicates which PIN should be checked. */ void storeVariableLength(APDU apdu, byte[] destination, short pin_type) { byte[] buffer = apdu.getBuffer(); // When writing DOs, PW1 really means PW1 submitted as PW2. if (!pins[pin_type].isValidated() || ((pin_type == PIN_INDEX_PW1) && !pinSubmitted[1])) { ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED); } short length = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF); if ((short) (length + 1) > destination.length || length > (short) 255 || apdu.setIncomingAndReceive() != length) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } JCSystem.beginTransaction(); destination[0] = (byte) length; Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, destination, (short) 1, length); JCSystem.commitTransaction(); }
Example 2
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 6 votes |
private static void handleAdmSetKeycardSeed(APDU apdu, boolean airgap) throws ISOException { byte[] buffer = apdu.getBuffer(); short offset = ISO7816.OFFSET_CDATA; byte keyLength; apdu.setIncomingAndReceive(); if ((setup == TC.TRUE) || (setup != TC.FALSE)) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } if (buffer[ISO7816.OFFSET_LC] != (byte)(KEYCARD_KEY_LENGTH + 1)) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if ((buffer[offset] == (byte)0) || (buffer[offset] > TC.MAX_KEYCARD_DIGIT_ADDRESS)) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } if (!airgap) { Keycard.setIssuer(buffer[offset], buffer, (short)(offset + 1)); } else { Crypto.initCipherAES(pairingKey, false); Crypto.blobEncryptDecryptAES.doFinal(buffer, (short)(offset + 1), (short)16, scratch256, (short)0); Keycard.setIssuer(buffer[offset], scratch256, (short)0); } }
Example 3
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 6 votes |
private static void handleVerifyPin(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); if ((setup == TC.FALSE) || (setup != TC.TRUE)) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } if (buffer[ISO7816.OFFSET_P1] == P1_GET_REMAINING_ATTEMPTS) { buffer[0] = walletPin.getTriesRemaining(); apdu.setOutgoingAndSend((short)0, (short)1); return; } apdu.setIncomingAndReceive(); if (buffer[ISO7816.OFFSET_LC] != walletPinSize) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } Util.arrayFillNonAtomic(scratch256, (short)0, WALLET_PIN_SIZE, (byte)0xff); Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, scratch256, (short)0, walletPinSize); if (!walletPin.check(scratch256, (short)0, WALLET_PIN_SIZE)) { if (walletPin.getTriesRemaining() == 0) { reset(); } ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED); } }
Example 4
Source File: TransitApplet.java From JCMathLib with MIT License | 6 votes |
/** * Verifies the PIN. * * @param apdu * The APDU */ private void verify(APDU apdu) { byte[] buffer = apdu.getBuffer(); byte numBytes = buffer[ISO7816.OFFSET_LC]; byte count = (byte) apdu.setIncomingAndReceive(); if (numBytes != count) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // Verify PIN if (pin.check(buffer, ISO7816.OFFSET_CDATA, numBytes) == false) { ISOException.throwIt(SW_VERIFICATION_FAILED); } }
Example 5
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
private static void handleStorePublicKey(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); apdu.setIncomingAndReceive(); short offset = ISO7816.OFFSET_CDATA; byte derivationSize = buffer[offset++]; byte i; if (Crypto.keyAgreement == null) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } if (derivationSize > MAX_DERIVATION_PATH) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } Crypto.initCipher(chipKey, false); Crypto.blobEncryptDecrypt.doFinal(masterDerived, (short)0, (short)DEFAULT_SEED_LENGTH, scratch256, (short)0); i = Bip32Cache.copyPrivateBest(buffer, (short)(ISO7816.OFFSET_CDATA + 1), derivationSize, scratch256, (short)0); for (; i<derivationSize; i++) { Util.arrayCopyNonAtomic(buffer, (short)(offset + 4 * i), scratch256, Bip32.OFFSET_DERIVATION_INDEX, (short)4); if ((proprietaryAPI == null) && ((scratch256[Bip32.OFFSET_DERIVATION_INDEX] & (byte)0x80) == 0)) { if (!Bip32Cache.setPublicIndex(buffer, (short)(ISO7816.OFFSET_CDATA + 1), i)) { ISOException.throwIt(SW_PUBLIC_POINT_NOT_AVAILABLE); } } if (!Bip32.derive(buffer)) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } Bip32Cache.storePrivate(buffer, (short)(ISO7816.OFFSET_CDATA + 1), (byte)(i + 1), scratch256); } offset += (short)(derivationSize * 4); Crypto.random.generateData(scratch256, (short)32, (short)32); signTransientPrivate(scratch256, (short)0, scratch256, (short)32, scratch256, (short)64); if (Crypto.verifyPublic(buffer, offset, scratch256, (short)32, scratch256, (short)64)) { Bip32Cache.storePublic(buffer, (short)(ISO7816.OFFSET_CDATA + 1), derivationSize, buffer, offset); } else { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } }
Example 6
Source File: U2FApplet.java From CCU2F with Apache License 2.0 | 5 votes |
private void handleSetAttestationCert(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); short len = apdu.setIncomingAndReceive(); short dataOffset = apdu.getOffsetCdata(); short copyOffset = Util.makeShort(buffer[ISO7816.OFFSET_P1], buffer[ISO7816.OFFSET_P2]); if ((short)(copyOffset + len) > (short)attestationCertificate.length) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } Util.arrayCopy(buffer, dataOffset, attestationCertificate, copyOffset, len); if ((short)(copyOffset + len) == (short)attestationCertificate.length) { attestationCertificateSet = true; } }
Example 7
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
private static void handleSetContactlessLimit(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); apdu.setIncomingAndReceive(); if (isContactless()) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } if (buffer[ISO7816.OFFSET_LC] != LIMIT_LAST) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, limits, (short)0, LIMIT_LAST); if (limitsSet != TC.TRUE) { limitsSet = TC.TRUE; } }
Example 8
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
private static void handleHasCachedPublicKey(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); apdu.setIncomingAndReceive(); short offset = ISO7816.OFFSET_CDATA; byte derivationSize = buffer[offset++]; if (derivationSize > MAX_DERIVATION_PATH) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } boolean result = Bip32Cache.hasPublic(buffer, offset, derivationSize); buffer[0] = (result ? (byte)0x01 : (byte)0x00); apdu.setOutgoingAndSend((short)0, (short)1); }
Example 9
Source File: GidsPINManager.java From GidsApplet with GNU General Public License v3.0 | 5 votes |
/** * \brief Process the general authentication process */ public void processGeneralAuthenticate(APDU apdu) { byte[] buf = apdu.getBuffer(); byte p1 = buf[ISO7816.OFFSET_P1]; byte p2 = buf[ISO7816.OFFSET_P2]; short lc; if(isInInitializationMode) { ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); } if(p1 != (byte) 0x00 || p2 != (byte) 0x00 ) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } // Bytes received must be Lc. lc = apdu.setIncomingAndReceive(); short innerPos = 0, innerLen = 0; if (buf[ISO7816.OFFSET_CDATA] != (byte) 0x7C) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } try { innerLen = UtilTLV.decodeLengthField(buf, (short) (ISO7816.OFFSET_CDATA+1)); innerPos = (short) (ISO7816.OFFSET_CDATA + 1 + UtilTLV.getLengthFieldLength(buf, (short) (ISO7816.OFFSET_CDATA+1))); } catch (InvalidArgumentsException e1) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } // inner functions never return if their input tag is found if (CheckForExternalChallenge(apdu, buf, innerPos, innerLen)) { return; } if (CheckForChallengeResponse(apdu, buf, innerPos, innerLen)) { return; } ISOException.throwIt(ISO7816.SW_DATA_INVALID); }
Example 10
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
private static void handleHashSignDerive(APDU apdu, boolean checkStage) throws ISOException { byte[] buffer = apdu.getBuffer(); short offset = ISO7816.OFFSET_CDATA; byte i; apdu.setIncomingAndReceive(); if (checkStage) { checkInterfaceConsistency(); if (TC.ctx[TC.TX_B_TRANSACTION_STATE] != Transaction.STATE_SIGN_READY) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } } byte derivationSize = buffer[offset++]; if (derivationSize > MAX_DERIVATION_PATH) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } Crypto.initCipher(chipKey, false); Crypto.blobEncryptDecrypt.doFinal(masterDerived, (short)0, (short)DEFAULT_SEED_LENGTH, scratch256, (short)0); i = Bip32Cache.copyPrivateBest(buffer, (short)(ISO7816.OFFSET_CDATA + 1), derivationSize, scratch256, (short)0); offset += (short)(i * 4); for (; i<derivationSize; i++) { Util.arrayCopyNonAtomic(buffer, offset, scratch256, Bip32.OFFSET_DERIVATION_INDEX, (short)4); if ((proprietaryAPI == null) && ((scratch256[Bip32.OFFSET_DERIVATION_INDEX] & (byte)0x80) == 0)) { if (!Bip32Cache.setPublicIndex(buffer, (short)(ISO7816.OFFSET_CDATA + 1), i)) { ISOException.throwIt(SW_PUBLIC_POINT_NOT_AVAILABLE); } } if (!Bip32.derive(buffer)) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } Bip32Cache.storePrivate(buffer, (short)(ISO7816.OFFSET_CDATA + 1), (byte)(i + 1), scratch256); offset += (short)4; } }
Example 11
Source File: NdefApplet.java From openjavacard-ndef with GNU General Public License v3.0 | 5 votes |
/** * 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 12
Source File: NdefApplet.java From openjavacard-ndef with GNU General Public License v3.0 | 5 votes |
/** * 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 13
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
private static void handleSetAttestationPublic(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); apdu.setIncomingAndReceive(); checkAirgapPersonalizationAvailable(); if (buffer[ISO7816.OFFSET_LC] != (byte)attestationPublic.length) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, attestationPublic, (short)0, (short)attestationPublic.length); }
Example 14
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 4 votes |
private static void handleSetUserKeycard(APDU apdu, boolean airgap) throws ISOException { byte[] buffer = apdu.getBuffer(); short offset = ISO7816.OFFSET_CDATA; apdu.setIncomingAndReceive(); if ((setup == TC.FALSE) || (setup != TC.TRUE)) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } if (Keycard.issuerKeycardSize == (byte)0) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } if (buffer[ISO7816.OFFSET_P1] == P1_SET_KEYCARD) { if (buffer[ISO7816.OFFSET_LC] != (byte)(KEYCARD_KEY_LENGTH + 1)) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } Keycard.setPairingData(buffer, ISO7816.OFFSET_CDATA); Keycard.generateRandomIndexes(Keycard.challenge, (short)0, KEYCARD_CHALLENGE_LENGTH); buffer[0] = CONFIRM_PREVIOUS_KEYCARD; Util.arrayCopyNonAtomic(Keycard.challenge, (short)0, buffer, (short)1, KEYCARD_CHALLENGE_LENGTH); apdu.setOutgoingAndSend((short)0, (short)(KEYCARD_CHALLENGE_LENGTH + 1)); } else if (buffer[ISO7816.OFFSET_P1] == P1_CONFIRM_KEYCARD) { if (buffer[ISO7816.OFFSET_LC] != KEYCARD_CHALLENGE_LENGTH) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (!Keycard.check(null, (short)0, (byte)0, buffer, ISO7816.OFFSET_CDATA, (byte)4, Keycard.challenge, (short)0, scratch256, (short)150)) { Keycard.clearPairingData(); ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED); } else { Keycard.getPairingData(scratch256, (short)0); if (!airgap) { Keycard.setUser(scratch256[0], scratch256, (short)1); } else { Crypto.initCipherAES(pairingKey, false); Crypto.blobEncryptDecryptAES.doFinal(scratch256, (short)1, (short)16, scratch256, (short)100); Keycard.setUser(scratch256[0], scratch256, (short)100); } } } else { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } }
Example 15
Source File: Ppse2Pay.java From CardExamples with The Unlicense | 4 votes |
@Override public void process(APDU apdu) throws ISOException { byte[] buf = apdu.getBuffer(); if (selectingApplet()) { //check that LC is 0x0E if((short)(buf[ISO7816.OFFSET_LC] & 0xFF) != 0x0E) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); //get the rest of the apdu and check length if((short)(buf[ISO7816.OFFSET_LC] & 0xFF) != apdu.setIncomingAndReceive()) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); if(FCI_TEMPLATE==null) { FCI_TEMPLATE = new byte[12 + ADF.length]; FCI_TEMPLATE[0]=(byte)0xA5; //FCI Proprietary Template FCI_TEMPLATE[1]=(byte)(10 + ADF.length); //length FCI_TEMPLATE[2]=(byte)0xBF; //FCI Issuer Discretionary Data FCI_TEMPLATE[3]=(byte)0x0C; FCI_TEMPLATE[4]=(byte)(7 + ADF.length); //length FCI_TEMPLATE[5]=(byte)0x61; //Directory Entry FCI_TEMPLATE[6]=(byte)(ADF.length + 5); //length FCI_TEMPLATE[7]=(byte)0x4F; //ADF Name FCI_TEMPLATE[8]=(byte)(ADF.length); //length for(short i=0;i<ADF.length;i++) FCI_TEMPLATE[9+i] = ADF[i]; FCI_TEMPLATE[9 + ADF.length]=(byte)0x87; //Application Priority Indicator FCI_TEMPLATE[10 + ADF.length]=(byte)1; //length FCI_TEMPLATE[11 + ADF.length]=(byte)0x01; } //return FCI upon successful select apdu.setOutgoing(); buf[0]=(byte)0x6F; //FCI Template buf[1]=(byte)(2 + DF.length + FCI_TEMPLATE.length); //length buf[2]=(byte)0x84; //DF Name buf[3]=(byte)DF.length; //length for(short i=0;i<DF.length;i++) buf[4+i] = DF[i]; for(short i=0;i<FCI_TEMPLATE.length;i++) buf[4 + DF.length + i] = FCI_TEMPLATE[i]; apdu.setOutgoingLength((short)(4 + DF.length + FCI_TEMPLATE.length)); apdu.sendBytes((short)0,(short)(4 + DF.length + FCI_TEMPLATE.length)); return; } switch (buf[ISO7816.OFFSET_INS]) { case (byte) 0xA4: //select PPSE //check that P1 & P2 are correct if(buf[ISO7816.OFFSET_P1] != (byte) 0x04 || buf[ISO7816.OFFSET_P2] != (byte) 0x00) ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); //check that LC is 0x0E if((short)(buf[ISO7816.OFFSET_LC] & 0xFF) != 0x0E) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); //get the rest of the apdu and check length if((short)(buf[ISO7816.OFFSET_LC] & 0xFF) != apdu.setIncomingAndReceive()) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); //otherwise, the file name was wrong for this select else ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND); case (byte) 0xEE: //loopback //check that P1 & P2 are correct if(buf[ISO7816.OFFSET_P1] != (byte) 0x00 || buf[ISO7816.OFFSET_P2] != (byte) 0x00) ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); //check that the length byte is within the spec (1-250) if((short)(buf[ISO7816.OFFSET_LC] & 0xFF) < 1 || (short)(buf[ISO7816.OFFSET_LC] & 0xFF) > 250) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); //get the rest of the apdu and check length if((short)(buf[ISO7816.OFFSET_LC] & 0xFF) != apdu.setIncomingAndReceive()) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); short len = buf[ISO7816.OFFSET_LC]; for(short i=0;i<len;i++) buf[i] = buf[i+5]; apdu.setOutgoingLength(len); apdu.sendBytes((short)0,len); break; default: // good practice: If you don't know the INStruction, say so: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } }
Example 16
Source File: IsoApplet.java From IsoApplet with GNU General Public License v3.0 | 4 votes |
/** * \brief Compute a digital signature of the data from the apdu * using the private key referenced by an earlier * MANAGE SECURITY ENVIRONMENT apdu. * * \attention The apdu should contain a hash, not raw data for RSA keys. * PKCS1 padding will be applied if neccessary. * * \param apdu The PERFORM SECURITY OPERATION apdu with P1=9E and P2=9A. * * \throw ISOException SW_CONDITIONS_NOT_SATISFIED, SW_WRONG_LENGTH * and SW_UNKNOWN. */ private void computeDigitalSignature(APDU apdu) throws ISOException { byte[] buf = apdu.getBuffer(); short offset_cdata; short lc; short sigLen = 0; switch(currentAlgorithmRef[0]) { case ALG_RSA_PAD_PKCS1: // Receive. // Bytes received must be Lc. lc = apdu.setIncomingAndReceive(); if(lc != apdu.getIncomingLength()) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } offset_cdata = apdu.getOffsetCdata(); // RSA signature operation. RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) keys[currentPrivateKeyRef[0]]; if(lc > (short) 247) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } rsaPkcs1Cipher.init(rsaKey, Cipher.MODE_ENCRYPT); sigLen = rsaPkcs1Cipher.doFinal(buf, offset_cdata, lc, ram_buf, (short)0); if(sigLen != 256) { ISOException.throwIt(ISO7816.SW_UNKNOWN); } // A single short APDU can handle 256 bytes - only one send operation neccessary. short le = apdu.setOutgoing(); if(le < sigLen) { ISOException.throwIt(ISO7816.SW_CORRECT_LENGTH_00); } apdu.setOutgoingLength(sigLen); apdu.sendBytesLong(ram_buf, (short) 0, sigLen); break; case ALG_ECDSA_SHA1: // Get the key - it must be a EC private key, // checks have been done in MANAGE SECURITY ENVIRONMENT. ECPrivateKey ecKey = (ECPrivateKey) keys[currentPrivateKeyRef[0]]; // Initialisation should be done when: // - No command chaining is performed at all. // - Command chaining is performed and this is the first apdu in the chain. if(ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS] == (short) 0) { ecdsaSignature.init(ecKey, Signature.MODE_SIGN); if(isCommandChainingCLA(apdu)) { ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS] = (short) 1; } } short recvLen = apdu.setIncomingAndReceive(); offset_cdata = apdu.getOffsetCdata(); // Receive data. For extended APDUs, the data is received piecewise // and aggregated in the hash. When using short APDUs, command // chaining is performed. while (recvLen > 0) { ecdsaSignature.update(buf, offset_cdata, recvLen); recvLen = apdu.receiveBytes(offset_cdata); } if(!isCommandChainingCLA(apdu)) { sigLen = ecdsaSignature.sign(buf, (short)0, (short)0, buf, (short) 0); ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS] = (short) 0; apdu.setOutgoingAndSend((short) 0, sigLen); } else { ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS]++; } break; default: // Wrong/unknown algorithm. ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } }
Example 17
Source File: IsoApplet.java From IsoApplet with GNU General Public License v3.0 | 4 votes |
/** * \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. */ private void processVerify(APDU apdu) throws ISOException { byte[] buf = apdu.getBuffer(); short offset_cdata; short lc; // P1P2 0001 only at the moment. (key-reference 01 = PIN) if(buf[ISO7816.OFFSET_P1] != 0x00 || buf[ISO7816.OFFSET_P2] != 0x01) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } // Bytes received must be Lc. lc = apdu.setIncomingAndReceive(); if(lc != apdu.getIncomingLength()) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } offset_cdata = apdu.getOffsetCdata(); // Lc might be 0, in this case the caller checks if verification is required. if((lc > 0 && (lc < PIN_MIN_LENGTH) || lc > PIN_MAX_LENGTH)) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // Caller asks if verification is needed. if(lc == 0 && state != STATE_CREATION && state != STATE_INITIALISATION) { // Verification required, return remaining tries. ISOException.throwIt((short)(SW_PIN_TRIES_REMAINING | pin.getTriesRemaining())); } else if(lc == 0 && (state == STATE_CREATION || state == STATE_INITIALISATION)) { // No verification required. ISOException.throwIt(ISO7816.SW_NO_ERROR); } // Pad the PIN if not done by caller, so no garbage from the APDU will be part of the PIN. Util.arrayFillNonAtomic(buf, (short)(offset_cdata + lc), (short)(PIN_MAX_LENGTH - lc), (byte) 0x00); // Check the PIN. if(!pin.check(buf, offset_cdata, PIN_MAX_LENGTH)) { fs.setUserAuthenticated(false); ISOException.throwIt((short)(SW_PIN_TRIES_REMAINING | pin.getTriesRemaining())); } else { fs.setUserAuthenticated(true); } }
Example 18
Source File: Gpg.java From OpenPGP-Card with GNU General Public License v3.0 | 4 votes |
/** * The PUT DATA APDU implementation. */ private void putData(APDU apdu) { byte[] buffer = apdu.getBuffer(); short length = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF); short tag = Util.getShort(buffer, ISO7816.OFFSET_P1); switch (tag) { // Private use objects. case 0x101: storeVariableLength(apdu, privateDO1, PIN_INDEX_PW1); break; case 0x102: storeVariableLength(apdu, privateDO2, PIN_INDEX_PW3); break; case 0x103: storeVariableLength(apdu, privateDO3, PIN_INDEX_PW1); break; case 0x104: storeVariableLength(apdu, privateDO4, PIN_INDEX_PW3); break; case 0x5B: storeVariableLength(apdu, name, PIN_INDEX_PW3); break; case 0x5E: storeVariableLength(apdu, loginData, PIN_INDEX_PW3); break; case 0x5F2D: storeVariableLength(apdu, language, PIN_INDEX_PW3); break; case 0x5F35: storeFixedLength(apdu, sex, (short) 0, (short) 1); break; case 0x5F50: storeVariableLength(apdu, url, PIN_INDEX_PW3); break; case 0xC4: if (!pins[PIN_INDEX_PW3].isValidated()) { ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED); } if (length < (short) 1 || length > (short) 8 || length != apdu.setIncomingAndReceive()) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } pinValidForMultipleSignatures = buffer[ISO7816.OFFSET_CDATA]; break; case 0xC7: case 0xC8: case 0xC9: storeFixedLength(apdu, fingerprints, (short) (20 * (tag - 0xC7)), (short) 20); break; case 0xCA: case 0xCB: case 0xCC: storeFixedLength(apdu, caFingerprints, (short) (20 * (tag - 0xCA)), (short) 20); break; case 0xCE: case 0xCF: case 0xD0: storeFixedLength(apdu, generationDates, (short) (4 * (tag - 0xCE)), (short) 4); break; case 0xD3: storeVariableLength(apdu, buffer, PIN_INDEX_PW3); // Reset code must be zero or 8 - MAX_PIN_LENGTH. if (length > MAX_PIN_LENGTH || (length != (byte) 0 && length < (byte) 8)) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } updatePIN(PIN_INDEX_RC, buffer, (short) 1, buffer[0]); break; default: ISOException.throwIt(ISO7816.SW_RECORD_NOT_FOUND); } }
Example 19
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 4 votes |
private static void handleTrustedInput(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); byte p1 = buffer[ISO7816.OFFSET_P1]; byte dataOffset = (short)0; apdu.setIncomingAndReceive(); if (p1 == P1_TRUSTED_INPUT_FIRST) { Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, TC.ctx, TC.TX_I_TRANSACTION_TARGET_INPUT, TC.SIZEOF_U32); TC.ctx[TC.TX_B_TRANSACTION_STATE] = Transaction.STATE_NONE; TC.ctx[TC.TX_B_TRUSTED_INPUT_PROCESSED] = (byte)0x00; TC.ctx[TC.TX_B_HASH_OPTION] = Transaction.HASH_FULL; dataOffset = (short)4; } else if (p1 != P1_TRUSTED_INPUT_NEXT) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } short remainingData = (short)((short)(buffer[ISO7816.OFFSET_LC] & 0xff) - dataOffset); byte result = Transaction.parseTransaction(Transaction.PARSE_TRUSTED_INPUT, buffer, (short)(ISO7816.OFFSET_CDATA + dataOffset), remainingData); if (result == Transaction.RESULT_ERROR) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } else if (result == Transaction.RESULT_MORE) { return; } else if (result == Transaction.RESULT_FINISHED) { short offset = 0; buffer[offset++] = BLOB_MAGIC_TRUSTED_INPUT; Crypto.random.generateData(buffer, offset, (short)3); offset += 3; Crypto.digestFull.doFinal(scratch256, (short)0, (short)0, scratch256, (short)0); Crypto.digestFull.doFinal(scratch256, (short)0, (short)32, buffer, offset); offset += 32; GenericBEHelper.swap(TC.SIZEOF_U32, buffer, offset, TC.ctx, TC.TX_I_TRANSACTION_TARGET_INPUT); offset += 4; Util.arrayCopyNonAtomic(TC.ctx, TC.TX_A_TRANSACTION_AMOUNT, buffer, offset, TC.SIZEOF_AMOUNT); offset += TC.SIZEOF_AMOUNT; Crypto.initCipher(trustedInputKey, true); Crypto.blobEncryptDecrypt.doFinal(buffer, (short)0, offset, scratch256, (short)0); Util.arrayCopyNonAtomic(scratch256, (short)(offset - 8), buffer, offset, (short)8); offset += 8; apdu.setOutgoingAndSend((short)0, offset); } }
Example 20
Source File: GidsApplet.java From GidsApplet with GNU General Public License v3.0 | 4 votes |
/** * \brief Compute a digital signature of the data from the apdu * using the private key referenced by an earlier * MANAGE SECURITY ENVIRONMENT apdu. * * \attention The apdu should contain a hash, not raw data for RSA keys. * PKCS1 padding will be applied if neccessary. * * \param apdu The PERFORM SECURITY OPERATION apdu with P1=9E and P2=9A. * * \throw ISOException SW_CONDITIONS_NOT_SATISFIED, SW_WRONG_LENGTH * and SW_UNKNOWN. */ private void computeDigitalSignature(APDU apdu) throws ISOException { byte[] buf = apdu.getBuffer(); short lc, le; short sigLen = 0; PrivateKey rsaKey = null; byte[] ram_buf = transmitManager.GetRamBuffer(); CRTKeyFile key = (CRTKeyFile) currentKey[0]; switch((byte) (currentAlgorithmRef[0] & 0xF0)) { case (byte) 0x10: // padding made off card -> raw encryption to be performed lc = transmitManager.doChainingOrExtAPDU(apdu); // RSA signature operation. rsaKey = key.GetKey().getPrivate(); rsaRawCipher.init(rsaKey, Cipher.MODE_ENCRYPT); sigLen = rsaRawCipher.doFinal(ram_buf, (short) 0, lc, ram_buf, (short)0); transmitManager.sendDataFromRamBuffer(apdu, (short)0, sigLen); break; case (byte) 0x50: // rsa padding made by the card, only the hash is provided // Receive. // Bytes received must be Lc. lc = apdu.setIncomingAndReceive(); // RSA signature operation. rsaKey = key.GetKey().getPrivate(); if(lc > (short) 247) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } rsaPkcs1Cipher.init(rsaKey, Cipher.MODE_ENCRYPT); sigLen = rsaPkcs1Cipher.doFinal(buf, ISO7816.OFFSET_CDATA, lc, ram_buf, (short)0); /*if(sigLen != 256) { ISOException.throwIt(ISO7816.SW_UNKNOWN); }*/ transmitManager.sendDataFromRamBuffer(apdu, (short)0, sigLen); break; default: // Wrong/unknown algorithm. ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } }