Java Code Examples for javacard.framework.APDU#setOutgoingAndSend()
The following examples show how to use
javacard.framework.APDU#setOutgoingAndSend() .
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: 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 2
Source File: OCUnitTests.java From JCMathLib with MIT License | 6 votes |
void test_EC_MUL(APDU apdu) { byte[] apdubuf = apdu.getBuffer(); short p1_len = (short) (apdubuf[ISO7816.OFFSET_P1] & 0x00FF); PM.check(PM.TRAP_EC_MUL_1); Bignat scalar = m_testBN1; scalar.set_size(p1_len); scalar.from_byte_array(p1_len, (short) 0, apdubuf, ISO7816.OFFSET_CDATA); PM.check(PM.TRAP_EC_MUL_2); m_testPoint1.setW(apdubuf, (short) (ISO7816.OFFSET_CDATA + p1_len), m_testCurve.POINT_SIZE); PM.check(PM.TRAP_EC_MUL_3); m_testPoint1.multiplication(scalar); PM.check(PM.TRAP_EC_MUL_4); short len = m_testPoint1.getW(apdubuf, (short) 0); PM.check(PM.TRAP_EC_MUL_5); apdu.setOutgoingAndSend((short) 0, len); }
Example 3
Source File: OCUnitTests.java From JCMathLib with MIT License | 6 votes |
void test_BN_EXP_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_EXP_MOD_1); Bignat num1 = m_testBN1; num1.set_size(p1); PM.check(PM.TRAP_BN_EXP_MOD_2); Bignat num2 = m_testBN2; num2.set_size(p2); PM.check(PM.TRAP_BN_EXP_MOD_3); Bignat mod = m_testBN3; mod.set_size((short) (dataLen - p1 - p2)); PM.check(PM.TRAP_BN_EXP_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_EXP_MOD_5); num1.mod_exp(num2, mod); PM.check(PM.TRAP_BN_EXP_MOD_6); 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 |
void test_BN_SUB_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_SUB_MOD_1); Bignat num1 = m_testBN1; num1.set_size(p1); PM.check(PM.TRAP_BN_SUB_MOD_2); Bignat num2 = m_testBN2; num2.set_size(p2); PM.check(PM.TRAP_BN_SUB_MOD_3); Bignat mod = m_testBN3; mod.set_size((short) (dataLen - p1 - p2)); PM.check(PM.TRAP_BN_SUB_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_SUB_MOD_5); num1.mod_sub(num2, mod); PM.check(PM.TRAP_BN_SUB_MOD_6); short len = num1.copy_to_buffer(apdubuf, (short) 0); apdu.setOutgoingAndSend((short) 0, len); }
Example 5
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
private static void handleGetFeatures(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); buffer[0] = (byte)0; if (proprietaryAPI != null) { buffer[0] |= JC_FEATURE_HAS_PROPRIETARY_API; } apdu.setOutgoingAndSend((short)0, (short)1); }
Example 6
Source File: OCUnitTests.java From JCMathLib with MIT License | 5 votes |
void test_EC_GEN(APDU apdu) { byte[] apdubuf = apdu.getBuffer(); PM.check(PM.TRAP_EC_GEN_1); m_testPoint1.randomize(); PM.check(PM.TRAP_EC_GEN_2); short len = m_testPoint1.getW(apdubuf, (short) 0); PM.check(PM.TRAP_EC_GEN_3); apdu.setOutgoingAndSend((short) 0, len); }
Example 7
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
private static void handleGetContactlessLimit(APDU apdu) throws ISOException { if ((setup == TC.FALSE) || (setup != TC.TRUE)) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } Util.arrayCopyNonAtomic(limits, (short)0, scratch256, (short)0, LIMIT_LAST); apdu.setOutgoingAndSend((short)0, LIMIT_LAST); }
Example 8
Source File: OCUnitTests.java From JCMathLib with MIT License | 5 votes |
void test_BN_SQRT(APDU apdu, short dataLen) { byte[] apdubuf = apdu.getBuffer(); short p1 = (short) (apdubuf[ISO7816.OFFSET_P1] & 0x00FF); Bignat num = m_testBN1; num.set_size(p1); num.from_byte_array(p1, p1, apdubuf, ISO7816.OFFSET_CDATA); Bignat num2 = m_testBN2; num2.clone(m_testCurve.pBN); num.sqrt_FP(num2); short len = num.copy_to_buffer(apdubuf, (short) 0); apdu.setOutgoingAndSend((short) 0, len); }
Example 9
Source File: TransitApplet.java From JCMathLib with MIT License | 4 votes |
/** * Processes an incoming request. The request message signature is verified, * then it is dispatched to the relevant handling method. The response * message is then signed and sent back. * * @param apdu * The APDU */ private void processRequest(APDU apdu) { // C-APDU: [CLA, INS, P1, P2, LC, [Request Message], [8-bytes MAC]] // Request Message: [T, L, [V...]] byte[] buffer = apdu.getBuffer(); if ((buffer[ISO7816.OFFSET_P1] != 0) || (buffer[ISO7816.OFFSET_P2] != 0)) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } byte numBytes = buffer[ISO7816.OFFSET_LC]; byte count = (byte) apdu.setIncomingAndReceive(); if (numBytes != count) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // Check request message signature if (!checkMAC(buffer)) { ISOException.throwIt(SW_WRONG_SIGNATURE); } if ((numBytes - MAC_LENGTH) != (buffer[TLV_LENGTH_OFFSET] + 2)) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } // R-APDU: [[Response Message], [2-bytes Status Word], [8-bytes MAC]] short offset = 0; // Dispatch request message for processing switch (buffer[TLV_TAG_OFFSET]) { case PROCESS_ENTRY: offset = processEntry(buffer, TLV_VALUE_OFFSET, buffer[TLV_LENGTH_OFFSET]); break; case PROCESS_EXIT: offset = processExit(buffer, TLV_VALUE_OFFSET, buffer[TLV_LENGTH_OFFSET]); break; case CREDIT: offset = credit(buffer, TLV_VALUE_OFFSET, buffer[TLV_LENGTH_OFFSET]); break; case GET_BALANCE: offset = getBalance(buffer, TLV_VALUE_OFFSET, buffer[TLV_LENGTH_OFFSET]); break; default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } // Append status word to response message offset = Util.setShort(buffer, offset, SW_SUCCESS); // Sign response message and append MAC to response message offset = generateMAC(buffer, offset); // Send R-APDU apdu.setOutgoingAndSend((short) 0, offset); }
Example 10
Source File: PasswordManagerApplet.java From sim-password-manager with Apache License 2.0 | 4 votes |
private void encrypt(APDU apdu) { if (!keysGenerated) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } byte[] buff = apdu.getBuffer(); short len = apdu.setIncomingAndReceive(); if (len > MAX_DATA_LEN) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } prng(iv, OFFSET_ZERO, AES_BLOCK_LEN); initAes(); try { aesCipher.RoundKeysSchedule(keyBytes, (short) 0, roundKeysBuff); short offset = Util.arrayCopyNonAtomic(buff, ISO7816.OFFSET_CDATA, cipherBuff, OFFSET_ZERO, len); short padSize = addPadding(cipherBuff, offset, len); short paddedLen = (short) (len + padSize); short blocks = (short) (paddedLen / AES_BLOCK_LEN); for (short i = 0; i < blocks; i++) { short cipherOffset = (short) (i * AES_BLOCK_LEN); for (short j = 0; j < AES_BLOCK_LEN; j++) { cbcV[j] ^= cipherBuff[(short) (cipherOffset + j)]; } // encrypts in place boolean success = aesCipher.AESEncryptBlock(cbcV, OFFSET_ZERO, roundKeysBuff); if (!success) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } Util.arrayCopyNonAtomic(cbcV, OFFSET_ZERO, cipherBuff, cipherOffset, AES_BLOCK_LEN); } offset = Util.arrayCopyNonAtomic(iv, OFFSET_ZERO, buff, OFFSET_ZERO, AES_BLOCK_LEN); offset = Util.arrayCopyNonAtomic(cipherBuff, OFFSET_ZERO, buff, AES_BLOCK_LEN, paddedLen); apdu.setOutgoingAndSend(OFFSET_ZERO, (short) (AES_BLOCK_LEN + paddedLen)); } finally { clearCipherState(); } }
Example 11
Source File: U2FApplet.java From CCU2F with Apache License 2.0 | 4 votes |
public void process(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); if (selectingApplet()) { if (attestationCertificateSet) { Util.arrayCopyNonAtomic(VERSION, (short)0, buffer, (short)0, (short)VERSION.length); apdu.setOutgoingAndSend((short)0, (short)VERSION.length); } return; } if (buffer[ISO7816.OFFSET_CLA] == PROPRIETARY_CLA) { if (attestationCertificateSet) { ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED); } switch(buffer[ISO7816.OFFSET_INS]) { case FIDO_ADM_SET_ATTESTATION_CERT: handleSetAttestationCert(apdu); break; default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } } else if (buffer[ISO7816.OFFSET_CLA] == FIDO_CLA) { if (!attestationCertificateSet) { ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED); } switch(buffer[ISO7816.OFFSET_INS]) { case FIDO_INS_ENROLL: handleEnroll(apdu); break; case FIDO_INS_SIGN: handleSign(apdu); break; case FIDO_INS_VERSION: handleVersion(apdu); break; case ISO_INS_GET_DATA: handleGetData(apdu); break; default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } } else { ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); } }
Example 12
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 13
Source File: GidsApplet.java From GidsApplet with GNU General Public License v3.0 | 4 votes |
/** * \brief Decipher the data from the apdu using the private key referenced by * an earlier MANAGE SECURITY ENVIRONMENT apdu. * * \param apdu The PERFORM SECURITY OPERATION apdu with P1=80 and P2=86. * * \throw ISOException SW_CONDITIONS_NOT_SATISFIED, SW_WRONG_LENGTH and * SW_WRONG_DATA */ private void decipher(APDU apdu) { byte[] buf = apdu.getBuffer(); short offset_cdata; short lc; short decLen = -1; byte[] ram_buf = transmitManager.GetRamBuffer(); Cipher cipher = null; lc = transmitManager.doChainingOrExtAPDU(apdu); offset_cdata = 0; // Padding indicator should be "No further indication". if(buf[offset_cdata] != (byte) 0x00) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } switch((byte) (currentAlgorithmRef[0] & 0xF0)) { case (byte) 0x80: cipher = rsaOaepCipher; break; case (byte) 0x40: cipher = rsaPkcs1Cipher; break; case (byte) 0x00: cipher = rsaRawCipher; break; default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } // Get the key - it must be an RSA private key, // checks have been done in MANAGE SECURITY ENVIRONMENT. CRTKeyFile key = (CRTKeyFile) currentKey[0]; PrivateKey theKey = key.GetKey().getPrivate(); // Check the length of the cipher. // Note: The first byte of the data field is the padding indicator // and therefor not part of the ciphertext. if(lc != (short)(theKey.getSize() / 8)) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } cipher.init(theKey, Cipher.MODE_DECRYPT); try { decLen = cipher.doFinal(ram_buf, (short) 0, lc, buf, (short) 0); } catch(CryptoException e) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } // We have to send at most 256 bytes. A short APDU can handle that - only one send operation neccessary. apdu.setOutgoingAndSend((short)0, decLen); }
Example 14
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 4 votes |
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 15
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 16
Source File: IsoApplet.java From IsoApplet with GNU General Public License v3.0 | 4 votes |
/** * \brief Decipher the data from the apdu using the private key referenced by * an earlier MANAGE SECURITY ENVIRONMENT apdu. * * \param apdu The PERFORM SECURITY OPERATION apdu with P1=80 and P2=86. * * \throw ISOException SW_CONDITIONS_NOT_SATISFIED, SW_WRONG_LENGTH and * SW_WRONG_DATA */ private void decipher(APDU apdu) { short offset_cdata; short lc; short decLen = -1; lc = doChainingOrExtAPDU(apdu); offset_cdata = 0; // Padding indicator should be "No further indication". if(ram_buf[offset_cdata] != (byte) 0x00) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } switch(currentAlgorithmRef[0]) { case ALG_RSA_PAD_PKCS1: // Get the key - it must be an RSA private key, // checks have been done in MANAGE SECURITY ENVIRONMENT. RSAPrivateCrtKey theKey = (RSAPrivateCrtKey) keys[currentPrivateKeyRef[0]]; // Check the length of the cipher. // Note: The first byte of the data field is the padding indicator // and therefor not part of the ciphertext. if((short)(lc-1) != (short)(theKey.getSize() / 8)) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } rsaPkcs1Cipher.init(theKey, Cipher.MODE_DECRYPT); try { decLen = rsaPkcs1Cipher.doFinal(ram_buf, (short)(offset_cdata+1), (short)(lc-1), apdu.getBuffer(), (short) 0); } catch(CryptoException e) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } // We have to send at most 256 bytes. A short APDU can handle that - only one send operation neccessary. apdu.setOutgoingAndSend((short)0, decLen); break; default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } }
Example 17
Source File: U2FApplet.java From CCU2F with Apache License 2.0 | 4 votes |
private void handleVersion(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); Util.arrayCopyNonAtomic(VERSION, (short)0, buffer, (short)0, (short)VERSION.length); apdu.setOutgoingAndSend((short)0, (short)VERSION.length); }
Example 18
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 19
Source File: TransitApplet.java From JCMathLib with MIT License | 4 votes |
/** * Initializes a CAD/card interaction session. This is the first step of * mutual authentication. A new card challenge is generated and used along * with the passed-in host challenge to generate the derivation data from * which a new session key is derived. The card challenge is appended to the * response message. The response message is signed using the newly * generated session key then sent back. Note that mutual authentication is * subsequently completed upon succesful verification of the signature of * the first request received. * * @param apdu * The APDU */ private void initializeSession(APDU apdu) { // C-APDU: [CLA, INS, P1, P2, LC, [4-bytes Host Challenge]] byte[] buffer = apdu.getBuffer(); if ((buffer[ISO7816.OFFSET_P1] != 0) || (buffer[ISO7816.OFFSET_P2] != 0)) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } byte numBytes = buffer[ISO7816.OFFSET_LC]; byte count = (byte) apdu.setIncomingAndReceive(); if (numBytes != CHALLENGE_LENGTH || count != CHALLENGE_LENGTH) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // Generate card challenge generateCardChallenge(); // Generate key derivation data from host challenge and card challenge generateKeyDerivationData(buffer); // Generate session key from derivation data generateSessionKey(); // R-APDU: [[4-bytes Card Challenge], [2-bytes Status Word], [8-bytes // MAC]] short offset = 0; // Append card challenge to response message offset = Util.arrayCopyNonAtomic(cardChallenge, (short) 0, buffer, offset, CHALLENGE_LENGTH); // Append status word to response message offset = Util.setShort(buffer, offset, SW_SUCCESS); // Sign response message and append MAC to response message offset = generateMAC(buffer, offset); // Send R-APDU apdu.setOutgoingAndSend((short) 0, offset); }
Example 20
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 4 votes |
private static void handleGetFirmwareVersion(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); Util.arrayCopyNonAtomic(FIRMWARE_VERSION, (short)0, buffer, (short)0, (short)FIRMWARE_VERSION.length); apdu.setOutgoingAndSend((short)0, (short)FIRMWARE_VERSION.length); }