Java Code Examples for javacard.framework.Util#getShort()
The following examples show how to use
javacard.framework.Util#getShort() .
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: UtilTLV.java From GidsApplet with GNU General Public License v3.0 | 5 votes |
public static short GetBERTLVDataLen(byte[] buf, short offset, short len) { short size = 0; short sizeforsize = 0; short i = 1; if ((buf[offset] & 0x1F) != 0x1F) { // simplified tag } else { // tag start with all 5 last bits to 1 // skip the tag while (((buf[(short) (offset + i)] & 0x80) != 0) && ((short)(i+offset)) < len) { i++; } // pass the last byte of the tag i+=1; } // check the size if ((buf[(short) (offset + i)] & 0x80) != 0) { // size encoded in many bytes sizeforsize = (short) (buf[(short) (offset + i)] & 0x7F); if (sizeforsize > 2) { // more than two bytes for encoding => not something than we can handle return 0; } else if (sizeforsize == 1) { size = Util.makeShort((byte) 0,buf[(short) (offset + i + 1)]); } else if (sizeforsize == 2) { size = Util.getShort(buf, (short) (offset + i + 1)); } } else { // size encode in one byte size = Util.makeShort((byte) 0,buf[(short) (offset + i)]); } return size; }
Example 2
Source File: NdefApplet.java From openjavacard-ndef with GNU General Public License v3.0 | 5 votes |
/** * Process a READ BINARY command * * This supports simple reads at any offset. * * The length of the returned data is limited * by the maximum R-APDU length as well as by * the maximum read size NDEF_MAX_READ. * * @param apdu to process * @throws ISOException on error */ private void processReadBinary(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); // access the file byte[] file = accessFileForRead(vars[VAR_SELECTED_FILE]); // get and check the read offset short offset = Util.getShort(buffer, ISO7816.OFFSET_P1); if(offset < 0 || offset >= file.length) { ISOException.throwIt(ISO7816.SW_WRONG_P1P2); } // determine the output size short le = apdu.setOutgoingNoChaining(); if(le > NDEF_MAX_READ) { le = NDEF_MAX_READ; } // adjust for end of file short limit = (short)(offset + le); if(limit < 0) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if(limit >= file.length) { le = (short)(file.length - offset); } // send the requested data apdu.setOutgoingLength(le); apdu.sendBytesLong(file, offset, le); }
Example 3
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 4
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 5
Source File: NdefApplet.java From openjavacard-ndef with GNU General Public License v3.0 | 5 votes |
/** * Process a READ BINARY command * * This supports simple reads at any offset. * * The length of the returned data is limited * by the maximum R-APDU length as well as by * the maximum read size NDEF_MAX_READ. * * @param apdu to process * @throws ISOException on error */ private void processReadBinary(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); // access the file byte[] file = accessFileForRead(vars[VAR_SELECTED_FILE]); // get and check the read offset short offset = Util.getShort(buffer, ISO7816.OFFSET_P1); if(offset < 0 || offset >= file.length) { ISOException.throwIt(ISO7816.SW_WRONG_P1P2); } // determine the output size short le = apdu.setOutgoingNoChaining(); if(le > NDEF_MAX_READ) { le = NDEF_MAX_READ; } // adjust for end of file short limit = (short)(offset + le); if(limit < 0) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if(limit >= file.length) { le = (short)(file.length - offset); } // send the requested data apdu.setOutgoingLength(le); apdu.sendBytesLong(file, offset, le); }
Example 6
Source File: NdefApplet.java From openjavacard-ndef with GNU General Public License v3.0 | 5 votes |
/** * Process an UPDATE BINARY command * * Supports simple writes at any offset. * * The amount of data that can be written in one * operation is limited both by maximum C-APDU * length and the maximum write size NDEF_MAX_WRITE. * * @param apdu to process * @throws ISOException on error */ private void processUpdateBinary(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); // access the file byte[] file = accessFileForWrite(vars[VAR_SELECTED_FILE]); // get and check the write offset short offset = Util.getShort(buffer, ISO7816.OFFSET_P1); if(offset < 0 || offset >= file.length) { ISOException.throwIt(ISO7816.SW_WRONG_P1P2); } // receive data short lc = apdu.setIncomingAndReceive(); // check the input size if(lc > NDEF_MAX_WRITE) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // file limit checks short limit = (short)(offset + lc); if(limit < 0 || limit >= file.length) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // perform the update Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, file, offset, lc); }
Example 7
Source File: Gpg.java From OpenPGP-Card with GNU General Public License v3.0 | 5 votes |
private short addKeyPart(byte part, byte[] data, short offset, KeyPair key) { short size = Util.getShort(commandChainingBuffer, TEMP_PUT_KEY_EXPECTED_CHUNK_SIZE); short nextSize = RSA_KEY_HALF_LENGTH_BYTES; switch (part) { case KEY_PART_E: ((RSAPublicKey) key.getPublic()).setExponent(data, offset, size); break; case KEY_PART_PRIME_P: ((RSAPrivateCrtKey) key.getPrivate()).setP(data, offset, size); break; case KEY_PART_PRIME_Q: ((RSAPrivateCrtKey) key.getPrivate()).setQ(data, offset, size); break; case KEY_PART_PARAM_PQ: ((RSAPrivateCrtKey) key.getPrivate()).setPQ(data, offset, size); break; case KEY_PART_PARAM_DP1: ((RSAPrivateCrtKey) key.getPrivate()).setDP1(data, offset, size); break; case KEY_PART_PARAM_DQ1: ((RSAPrivateCrtKey) key.getPrivate()).setDQ1(data, offset, size); nextSize = RSA_KEY_LENGTH_BYTES; break; case KEY_PART_N: ((RSAPublicKey) key.getPublic()).setModulus(data, offset, RSA_KEY_LENGTH_BYTES); if (!key.getPrivate().isInitialized() || !key.getPublic().isInitialized()) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } return (short) (offset + RSA_KEY_LENGTH_BYTES); } Util.setShort(commandChainingBuffer, TEMP_PUT_KEY_EXPECTED_CHUNK_SIZE, nextSize); return (short) (offset + size); }
Example 8
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 4 votes |
/** * This function allows to decrypt a secure channel message * * ins: 0x82 * * p1: 0x00 (RFU) * p2: 0x00 (RFU) * data: [IV(16b) | data_size(2b) | encrypted_command | mac_size(2b) | mac] * * return: [decrypted command] * */ private short ProcessSecureChannel(APDU apdu, byte[] buffer){ short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]); short offset = ISO7816.OFFSET_CDATA; if (!initialized_secure_channel){ ISOException.throwIt(SW_SECURE_CHANNEL_UNINITIALIZED); } // check hmac if (bytesLeft<18) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); short sizein = Util.getShort(buffer, (short) (offset+SIZE_SC_IV)); if (bytesLeft<(short)(SIZE_SC_IV+2+sizein+2)) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); short sizemac= Util.getShort(buffer, (short) (offset+SIZE_SC_IV+2+sizein)); if (sizemac != (short)20) ISOException.throwIt(SW_SECURE_CHANNEL_WRONG_MAC); if (bytesLeft<(short)(SIZE_SC_IV+2+sizein+2+sizemac)) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); HmacSha160.computeHmacSha160(sc_buffer, OFFSET_SC_MACKEY, SIZE_SC_MACKEY, buffer, offset, (short)(SIZE_SC_IV+2+sizein), recvBuffer, (short)0); if ( Util.arrayCompare(recvBuffer, (short)0, buffer, (short)(offset+SIZE_SC_IV+2+sizein+2), (short)20) != (byte)0 ) ISOException.throwIt(SW_SECURE_CHANNEL_WRONG_MAC); // process IV // IV received from client should be odd and strictly greater than locally saved IV // IV should be random (the 12 first bytes), never reused (the last 4 bytes counter) and different for send and receive if ((buffer[(short)(offset+SIZE_SC_IV-(short)1)] & (byte)0x01)==0x00)// should be odd ISOException.throwIt(SW_SECURE_CHANNEL_WRONG_IV); if ( !Biginteger.lessThan(sc_buffer, OFFSET_SC_IV_COUNTER, buffer, (short)(offset+SIZE_SC_IV_RANDOM), SIZE_SC_IV_COUNTER ) ) //and greater than local IV ISOException.throwIt(SW_SECURE_CHANNEL_WRONG_IV); // update local IV Util.arrayCopy(buffer, (short)(offset+SIZE_SC_IV_RANDOM), sc_buffer, OFFSET_SC_IV_COUNTER, SIZE_SC_IV_COUNTER); Biginteger.add1_carry(sc_buffer, OFFSET_SC_IV_COUNTER, SIZE_SC_IV_COUNTER); randomData.generateData(sc_buffer, OFFSET_SC_IV_RANDOM, SIZE_SC_IV_RANDOM); sc_aes128_cbc.init(sc_sessionkey, Cipher.MODE_DECRYPT, buffer, offset, SIZE_SC_IV); offset+=SIZE_SC_IV; bytesLeft-=SIZE_SC_IV; //decrypt command offset+=2; bytesLeft-=2; if (bytesLeft<sizein) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); short sizeout=sc_aes128_cbc.doFinal(buffer, offset, sizein, buffer, (short) (0)); return sizeout; }
Example 9
Source File: TransitApplet.java From JCMathLib with MIT License | 4 votes |
/** * Processes a transit entry event. The passed-in entry station ID is * recorded and the correlation ID is incremented. The UID and the * correlation ID are returned in the response message. * * Request Message: [2-bytes Entry Station ID] * * Response Message: [[2-bytes UID], [2-bytes Correlation ID]] * * @param buffer * The APDU buffer * @param messageOffset * The offset of the request message content in the APDU buffer * @param messageLength * The length of the request message content. * @return The offset at which content can be appended to the response * message */ private short processEntry(byte[] buffer, short messageOffset, short messageLength) { // Request Message: [2-bytes Entry Station ID] if (messageLength != 2) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // Check minimum balance if (balance < MIN_TRANSIT_BALANCE) { ISOException.throwIt(SW_MIN_TRANSIT_BALANCE); } // Check consistent transit state: should not currently be in transit if (entryStationId >= 0) { ISOException.throwIt(SW_INVALID_TRANSIT_STATE); } JCSystem.beginTransaction(); // Get/assign entry station ID from request message entryStationId = Util.getShort(buffer, messageOffset); // Increment correlation ID correlationId++; JCSystem.commitTransaction(); // Response Message: [[8-bytes UID], [2-bytes Correlation ID]] short offset = 0; // Append UID to response message offset = Util.arrayCopy(uid, (short) 0, buffer, offset, UID_LENGTH); // Append correlation ID to response message offset = Util.setShort(buffer, offset, correlationId); return offset; }
Example 10
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 4 votes |
/** * This function encrypts/decrypt a given message with a 16bytes secret key derived from the 2FA key. * It also returns an id derived from the 2FA key. * This is used to privately exchange tx data between the hw wallet and the 2FA device. * * Algorithms: * id_2FA is hmac-sha1(secret_2FA, "id_2FA"), * key_2FA is hmac-sha1(secret_2FA, "key_2FA"), * message encrypted using AES * * ins: 0x76 * p1: 0x00 for encryption, 0x01 for decryption * p2: Init-Update-Finalize * data(init): IF_ENCRYPT: none ELSE: [IV(16b)] * data(update/finalize): [chunk_size(2b) | chunk_data] * * return(init): IF_ENCRYPT:[IV(16b) | id_2FA(20b)] ELSE: none * return(update/finalize): [chunk_size(2b) | chunk_data] * * */ private short CryptTransaction2FA(APDU apdu, byte[] buffer){ // check that PIN[0] has been entered previously if (!pins[0].isValidated()) ISOException.throwIt(SW_UNAUTHORIZED); // check that 2FA is enabled if (!needs_2FA) ISOException.throwIt(SW_2FA_UNINITIALIZED_KEY); byte ciph_dir = buffer[ISO7816.OFFSET_P1]; byte ciph_op = buffer[ISO7816.OFFSET_P2]; short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]); short dataOffset = ISO7816.OFFSET_CDATA; short IVlength=(short)16; switch(ciph_op){ case OP_INIT: if (ciph_dir!=Cipher.MODE_ENCRYPT && ciph_dir!=Cipher.MODE_DECRYPT ) ISOException.throwIt(SW_INVALID_PARAMETER); if (ciph_dir==Cipher.MODE_ENCRYPT){ randomData.generateData(buffer,(short)0, IVlength); aes128_cbc.init(key_2FA, Cipher.MODE_ENCRYPT, buffer, (short)0, IVlength); Util.arrayCopyNonAtomic(data2FA, OFFSET_2FA_ID, buffer, (short)IVlength, (short)20); return (short)(IVlength + 20); } if (ciph_dir==Cipher.MODE_DECRYPT){ aes128_cbc.init(key_2FA, Cipher.MODE_DECRYPT, buffer, dataOffset, IVlength); return (short)0; } break; case OP_PROCESS: case OP_FINALIZE: if (bytesLeft < 2) ISOException.throwIt(SW_INVALID_PARAMETER); short size = Util.getShort(buffer, dataOffset); if (bytesLeft < (short) (2 + size)) ISOException.throwIt(SW_INVALID_PARAMETER); short sizeout=0; if (ciph_op == OP_PROCESS){ sizeout=aes128_cbc.update(buffer, (short) (dataOffset + 2), size, buffer, (short) 2); } else {// ciph_op == OP_FINALIZE sizeout=aes128_cbc.doFinal(buffer, (short) (dataOffset + 2), size, buffer, (short) 2); } // Also copies the Short size information Util.setShort(buffer,(short)0, sizeout); return (short) (sizeout + 2); default: ISOException.throwIt(SW_INCORRECT_P2); } return (short)0; }
Example 11
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 4 votes |
/** * This function signs a given transaction hash with a std or the last extended key * If 2FA is enabled, a HMAC must be provided as an additional security layer. * * ins: 0x7A * p1: key number or 0xFF for the last derived Bip32 extended key * p2: 0x00 * data: [hash(32b) | option: 2FA-flag(2b)|hmac(20b)] * * return: [sig ] * */ private short SignTransactionHash(APDU apdu, byte[] buffer){ // check that PIN[0] has been entered previously if (!pins[0].isValidated()) ISOException.throwIt(SW_UNAUTHORIZED); byte key_nb = buffer[ISO7816.OFFSET_P1]; if ( (key_nb!=(byte)0xFF) && ((key_nb < 0) || (key_nb >= MAX_NUM_KEYS)) ) ISOException.throwIt(SW_INCORRECT_P1); short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]); if (bytesLeft<MessageDigest.LENGTH_SHA_256) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); // check whether the seed is initialized if (key_nb==(byte)0xFF && !bip32_seeded) ISOException.throwIt(SW_BIP32_UNINITIALIZED_SEED); // check 2FA if required if(needs_2FA){ // check data length if (bytesLeft<MessageDigest.LENGTH_SHA_256+MessageDigest.LENGTH_SHA+(short)2) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); // check flag for 2fa_hmac_chalresp short hmac_flags= Util.getShort(buffer, (short)(ISO7816.OFFSET_CDATA+32)); if (hmac_flags!=HMAC_CHALRESP_2FA) ISOException.throwIt(SW_INCORRECT_ALG); // hmac of 64-bytes msg: ( 32bytes tx_hash | 32bytes 0xCC-padding) Util.arrayCopyNonAtomic(buffer, (short)ISO7816.OFFSET_CDATA, recvBuffer, (short)0, (short)32); Util.arrayFillNonAtomic(recvBuffer, (short)32, (short)32, (byte)0xCC); HmacSha160.computeHmacSha160(data2FA, OFFSET_2FA_HMACKEY, (short)20, recvBuffer, (short)0, (short)64, recvBuffer, (short)64); if (Util.arrayCompare(buffer, (short)(ISO7816.OFFSET_CDATA+32+2), recvBuffer, (short)64, (short)20)!=0) ISOException.throwIt(SW_SIGNATURE_INVALID); } // hash+sign singlehash if (key_nb==(byte)0xFF) sigECDSA.init(bip32_extendedkey, Signature.MODE_SIGN); else{ Key key= eckeys[key_nb]; // check type and size if ((key == null) || !key.isInitialized()) ISOException.throwIt(SW_INCORRECT_P1); if (key.getType() != KeyBuilder.TYPE_EC_FP_PRIVATE) ISOException.throwIt(SW_INCORRECT_ALG); if (key.getSize()!= LENGTH_EC_FP_256) ISOException.throwIt(SW_INCORRECT_ALG); sigECDSA.init(key, Signature.MODE_SIGN); } short sign_size= sigECDSA.signPreComputedHash(buffer, ISO7816.OFFSET_CDATA, MessageDigest.LENGTH_SHA_256, buffer, (short)0); return sign_size; }
Example 12
Source File: Gpg.java From OpenPGP-Card with GNU General Public License v3.0 | 4 votes |
private void decrypt(APDU apdu) { byte[] buffer = apdu.getBuffer(); // PW1 with 0x82 if (!pins[PIN_INDEX_PW1].isValidated() || !pinSubmitted[1]) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } if (!confidentialityKey.getPrivate().isInitialized()) { ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND); } boolean firstCommand = (commandChainingBuffer[TEMP_INS] != buffer[ISO7816.OFFSET_INS]); // Mark the command chain as bad so it stays in this state in case of exception. short len = apdu.setIncomingAndReceive(); if (len < 1) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (firstCommand) { Util.arrayCopyNonAtomic(buffer, (short) (ISO7816.OFFSET_CDATA + 1), commandChainingBuffer, TEMP_GET_RESPONSE_DATA, (short) (len - 1)); len = (short) (len - 1); } else { short existing = Util.getShort(commandChainingBuffer, TEMP_GET_RESPONSE_LENGTH); if ((short) (len + existing) > RSA_KEY_LENGTH_BYTES) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, commandChainingBuffer, (short) (TEMP_GET_RESPONSE_DATA + existing), len); len += existing; } if (len < RSA_KEY_LENGTH_BYTES) { commandChainingBuffer[TEMP_INS] = CMD_COMPUTE_PSO; Util.setShort(commandChainingBuffer, TEMP_GET_RESPONSE_LENGTH, len); return; // For compatibily with GPG } // We have enough bytes to decrypt. cipherRSA.init(confidentialityKey.getPrivate(), Cipher.MODE_DECRYPT); len = cipherRSA.doFinal(commandChainingBuffer, TEMP_GET_RESPONSE_DATA, RSA_KEY_LENGTH_BYTES, buffer, (short) 0); // Clear command chaining buffer to make ready for next operation. Util.arrayFillNonAtomic(commandChainingBuffer, (short) 0, (short) commandChainingBuffer.length, (byte) 0); apdu.setOutgoingAndSend((short) 0, len); }
Example 13
Source File: UtilTLV.java From openjavacard-ndef with GNU General Public License v3.0 | 4 votes |
/** * \brief Decode the length field of a TLV-entry. * * The length field itself can be 1, 2 or 3 bytes long: * - If the length is between 0 and 127, it is 1 byte long. * - If the length is between 128 and 255, it is 2 bytes long. * The first byte is 0x81 to indicate this. * - If the length is between 256 and 65535, it is 3 bytes long. * The first byte is 0x82, the following 2 contain the actual length. * Note: Only lengths up to 0x7FFF (32767) are supported here, because a short in Java is signed. * * \param buf The buffer containing the length field. * * \param offset The offset at where the length field starts. * * \param length The length of the buffer (buf). This is to prevent that the index gets out of bounds. * * \return The (positive) length encoded by the length field, or in case of an error, -1. * * \throw InvalidArgumentsException If offset is too big for a signed Java short * If the first byte of the length field is invalid */ public static short decodeLengthField(byte[] buf, short offset) { if(buf[offset] == (byte)0x82) { // 256..65535 // Check for short overflow // (In Java, a short is signed: positive values are 0000..7FFF) if(buf[(short)(offset+1)] < 0) { // 80..FF return -1; } return Util.getShort(buf, (short)(offset+1)); } else if(buf[offset] == (byte)0x81) { return (short) ( 0x00FF & buf[(short)(offset+1)]); } else if(buf[offset] > 0) { // 00..7F return (short) ( 0x007F & buf[offset]); } else { return -1; } }
Example 14
Source File: NdefApplet.java From openjavacard-ndef with GNU General Public License v3.0 | 4 votes |
/** * Process a READ BINARY command * * This supports simple reads at any offset. * * The length of the returned data is limited * by the maximum R-APDU length as well as by * the maximum read size NDEF_MAX_READ. * * @param apdu to process * @throws ISOException on error */ private void processReadBinary(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); // access the file byte[] file = accessFileForRead(vars[VAR_SELECTED_FILE]); // get and check the read offset short offset = Util.getShort(buffer, ISO7816.OFFSET_P1); if(offset < 0 || offset >= file.length) { ISOException.throwIt(ISO7816.SW_WRONG_P1P2); } // determine the output size short le = apdu.setOutgoingNoChaining(); if(le > NDEF_MAX_READ) { le = NDEF_MAX_READ; } // adjust for end of file short limit = (short)(offset + le); if(limit < 0) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if(limit >= file.length) { le = (short)(file.length - offset); } // send the requested data if(vars[VAR_SELECTED_FILE] == FILEID_NDEF_CAPABILITIES) { // send fixed capabilities Util.arrayCopyNonAtomic(file, (short)0, buffer, (short)0, (short)file.length); fixCaps(buffer, (short)0, (short)file.length); apdu.setOutgoingLength(le); apdu.sendBytesLong(buffer, offset, le); } else { // send directly apdu.setOutgoingLength(le); apdu.sendBytesLong(file, offset, le); } }
Example 15
Source File: NdefApplet.java From openjavacard-ndef with GNU General Public License v3.0 | 4 votes |
/** * Main constructor * * This will construct and initialize an instance * of this applet according to the provided app data. * * @param buf containing application data * @param off offset of app data in buf * @param len length of app data in buf */ protected NdefApplet(byte[] buf, short off, byte len) { short initSize = DEFAULT_NDEF_DATA_SIZE; byte initReadAccess = DEFAULT_NDEF_READ_ACCESS; byte initWriteAccess = DEFAULT_NDEF_WRITE_ACCESS; byte[] initBuf = null; short initOff = 0; short initLen = 0; // create variables vars = JCSystem.makeTransientShortArray(NUM_VARS, JCSystem.CLEAR_ON_DESELECT); // process application data if(FEATURE_INSTALL_PARAMETERS) { // check TLV consistency if (!UtilTLV.isTLVconsistent(buf, off, len)) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } // DATA INITIAL short initTag = UtilTLV.findTag(buf, off, len, AD_TAG_NDEF_DATA_INITIAL); if (initTag >= 0) { initBuf = buf; initLen = UtilTLV.decodeLengthField(buf, (short) (initTag + 1)); initOff = (short) (initTag + 1 + UtilTLV.getLengthFieldLength(initLen)); // restrict writing, can be overridden using DATA ACCESS initWriteAccess = FILE_ACCESS_NONE; // adjust size, can be overridden initSize = (short) (2 + initLen); } // DATA ACCESS short tagAccess = UtilTLV.findTag(buf, off, len, AD_TAG_NDEF_DATA_ACCESS); if (tagAccess >= 0) { short accessLen = UtilTLV.decodeLengthField(buf, (short) (tagAccess + 1)); if (accessLen != 2) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } initReadAccess = buf[(short) (tagAccess + 2)]; initWriteAccess = buf[(short) (tagAccess + 3)]; } // DATA SIZE short tagSize = UtilTLV.findTag(buf, off, len, AD_TAG_NDEF_DATA_SIZE); if (tagSize >= 0) { short sizeLen = UtilTLV.decodeLengthField(buf, (short) (tagSize + 1)); if (sizeLen != 2) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } initSize = Util.getShort(buf, (short) (tagSize + 2)); if (initSize < 0) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } } } // squash write access if not supported if(!FEATURE_WRITING) { initWriteAccess = FILE_ACCESS_NONE; } // set up access dataReadAccess = initReadAccess; dataWriteAccess = initWriteAccess; // create file contents capsFile = makeCaps(initSize, initReadAccess, initWriteAccess); dataFile = makeData(initSize, initBuf, initOff, initLen); }
Example 16
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 17
Source File: EC_Consts.java From ECTester with MIT License | 4 votes |
public static short transformParameter(short transformation, byte[] buffer, short offset, short length) { if (transformation == TRANSFORMATION_NONE) { return length; } short transformationMask = TRANSFORMATION_FIXED; while (transformationMask <= TRANSFORMATION_04_MASK) { short transformationPart = (short) (transformationMask & transformation); switch (transformationPart) { case (short) 0: break; case TRANSFORMATION_FIXED: if (length >= 1) { buffer[offset] = (byte) 0xcc; buffer[(short) (offset + length - 1)] = (byte) 0xcc; } break; case TRANSFORMATION_FULLRANDOM: randomData.generateData(buffer, offset, length); break; case TRANSFORMATION_ONEBYTERANDOM: short first = Util.getShort(buffer, (short) 0); // save first two bytes randomData.generateData(buffer, (short) 0, (short) 2); // generate position short rngPos = Util.getShort(buffer, (short) 0); // save generated position Util.setShort(buffer, (short) 0, first); // restore first two bytes if (rngPos < 0) { // make positive rngPos = (short) -rngPos; } rngPos %= length; // make < param length byte original = buffer[rngPos]; do { randomData.generateData(buffer, rngPos, (short) 1); } while (original == buffer[rngPos]); break; case TRANSFORMATION_ZERO: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 0); break; case TRANSFORMATION_ONE: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 0); buffer[(short) (offset + length)] = (byte) 1; break; case TRANSFORMATION_MAX: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 1); break; case TRANSFORMATION_INCREMENT: short index = (short) (offset + length - 1); byte value; do { value = buffer[index]; buffer[index--] = ++value; } while (value == (byte) 0 && index >= offset); break; case TRANSFORMATION_INFINITY: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 0); length = 1; break; case TRANSFORMATION_COMPRESS_HYBRID: case TRANSFORMATION_COMPRESS: if ((short) (length % 2) != 1) { // an uncompressed point should have odd length (since 1 byte type, + 2 * coords) ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } short half = (short) ((short) (length - 1) / 2); byte yLSB = buffer[(short) (offset + length)]; byte yBit = (byte) (yLSB & 0x01); if (yBit == 1) { buffer[offset] = 3; } else { buffer[offset] = 2; } if (transformationPart == TRANSFORMATION_COMPRESS) { length = (short) (half + 1); } else { buffer[offset] += 4; } break; case TRANSFORMATION_04_MASK: buffer[offset] = 4; break; default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } transformationMask = (short) (transformationMask << 1); } return length; }
Example 18
Source File: UtilTLV.java From GidsApplet with GNU General Public License v3.0 | 4 votes |
public static short CheckBERTLV(byte[] buf, short offset, short len) { short size = 0; short sizeforsize = 0; short i = 1; short totalsize = 0; if ((buf[offset] & 0x1F) != 0x1F) { // simplified tag } else { // tag start with all 5 last bits to 1 // skip the tag while (((buf[(short) (offset + i)] & 0x80) != 0) && i < len) { i++; } // pass the last byte of the tag i+=1; } if ((short) (i+1) >len) { return 0; } // check the size if ((buf[(short) (offset + i)] & 0x80) != 0) { // size encoded in many bytes sizeforsize = (short) (buf[(short) (offset + i)] & 0x7F); if ((short) (i+1+sizeforsize) >len) { return 0; } if (sizeforsize > (short) 2) { // more than two bytes for encoding => not something than we can handle return 0; } else if (sizeforsize == (short) 1) { if ((short) (offset + i + 1 + sizeforsize) > len) { return 0; } size = Util.makeShort((byte) 0,buf[(short) (offset + i + 1)]); } else if (sizeforsize == 2) { totalsize = (short) (i + 1 + sizeforsize + size); if ((short) (offset + i + 1 + sizeforsize) > len) { return (short) 0; } size = Util.getShort(buf, (short) (offset + i + 1)); } } else { // size encode in one byte size = Util.makeShort((byte) 0,buf[(short) (offset + i)]); } totalsize = (short) (i + 1 + sizeforsize + size); if (totalsize < (short) 240 && (short) (offset + totalsize) > len) { return (short) 0; } return totalsize; }
Example 19
Source File: UtilTLV.java From GidsApplet with GNU General Public License v3.0 | 4 votes |
/** * \brief Decode the length field of a TLV-entry. * * The length field itself can be 1, 2 or 3 bytes long: * - If the length is between 0 and 127, it is 1 byte long. * - If the length is between 128 and 255, it is 2 bytes long. * The first byte is 0x81 to indicate this. * - If the length is between 256 and 65535, it is 3 bytes long. * The first byte is 0x82, the following 2 contain the actual length. * Note: Only lengths up to 0x7FFF (32767) are supported here, because a short in Java is signed. * * \param buf The buffer containing the length field. * * \param offset The offset at where the length field starts. * * \param length The length of the buffer (buf). This is to prevent that the index gets out of bounds. * * \return The (positive) length encoded by the length field, or in case of an error, -1. * * \throw InvalidArgumentsException If offset is too big for a signed Java short * If the first byte of the length field is invalid */ public static short decodeLengthField(byte[] buf, short offset) throws InvalidArgumentsException { if(buf[offset] == (byte)0x82) { // 256..65535 // Check for short overflow // (In Java, a short is signed: positive values are 0000..7FFF) if(buf[(short)(offset+1)] < 0) { // 80..FF throw InvalidArgumentsException.getInstance(); } return Util.getShort(buf, (short)(offset+1)); } else if(buf[offset] == (byte)0x81) { return (short) ( 0x00FF & buf[(short)(offset+1)]); } else if(buf[offset] > 0) { // 00..7F return (short) ( 0x007F & buf[offset]); } else { throw InvalidArgumentsException.getInstance(); } }
Example 20
Source File: UtilTLV.java From IsoApplet with GNU General Public License v3.0 | 4 votes |
/** * \brief Decode the length field of a TLV-entry. * * The length field itself can be 1, 2 or 3 bytes long: * - If the length is between 0 and 127, it is 1 byte long. * - If the length is between 128 and 255, it is 2 bytes long. * The first byte is 0x81 to indicate this. * - If the length is between 256 and 65535, it is 3 bytes long. * The first byte is 0x82, the following 2 contain the actual length. * Note: Only lengths up to 0x7FFF (32767) are supported here, because a short in Java is signed. * * \param buf The buffer containing the length field. * * \param offset The offset at where the length field starts. * * \param length The length of the buffer (buf). This is to prevent that the index gets out of bounds. * * \return The (positive) length encoded by the length field, or in case of an error, -1. * * \throw InvalidArgumentsException If offset is too big for a signed Java short * If the first byte of the length field is invalid */ public static short decodeLengthField(byte[] buf, short offset) throws InvalidArgumentsException { if(buf[offset] == (byte)0x82) { // 256..65535 // Check for short overflow // (In Java, a short is signed: positive values are 0000..7FFF) if(buf[(short)(offset+1)] < 0) { // 80..FF throw InvalidArgumentsException.getInstance(); } return Util.getShort(buf, (short)(offset+1)); } else if(buf[offset] == (byte)0x81) { return (short) ( 0x00FF & buf[(short)(offset+1)]); } else if(buf[offset] > 0) { // 00..7F return (short) ( 0x007F & buf[offset]); } else { throw InvalidArgumentsException.getInstance(); } }