Beispiel #1
0
        /// <summary>
        /// Process READ BINARY instruction (CC2)
        /// <para>
        /// C-APDU: <code>00 B0 {P1-P2: offset} {Le}</code>
        /// </para>
        /// <para>
        /// R-APDU when an EF is selected: <code>{data in EF}</code>
        /// </para>
        /// <para>
        /// R-APDU when no EF is selected: <code>{headers of EF in current DF}</code>
        /// </para>
        /// </summary>
        /// <param name="apdu"></param>
        /// <returns></returns>
        private IFakeCardFeedback ProcessRead(CommandAPDU apdu)
        {
            short le        = apdu.SetOutgoing(); // in BYTES
            short wordCount = (short)((short)(le + 3) / 4);

            byte[] buffer = JCSystem.makeTransientByteArray((short)(wordCount * 4), JCSystem.CLEAR_ON_DESELECT);
            short  offset;

            if (_currentEF != null)
            {
                // an EF is selected ==> read binary
                offset = Util.getShort(apdu.GetBuffer(), JavaCard.ISO7816.OFFSET_P1); // in WORDS

                byte[] header = JCSystem.makeTransientByteArray(8, JCSystem.CLEAR_ON_DESELECT);
                _currentEF.GetHeader(header, 0);
                _headerParser.Parse(header, 0, 8);
                offset += (short)(_currentEF.Read(offset, buffer, 0, wordCount, _headerParser.fileType == HeaderParser.FILETYPE_EFSZ) << 2);
            }
            else
            {
                // no EF selected ==> DIR
                offset = 0;
                byte currentChildNumber = 0;
                File fileChild          = _currentDF.GetChild(currentChildNumber);
                // get header of each file in current DF
                while (fileChild != null && offset < le)
                {
                    fileChild.GetHeader(buffer, offset);
                    offset   += (short)(fileChild.GetHeaderSize() << 2);
                    fileChild = _currentDF.GetChild(++currentChildNumber);
                }
            }

            // Pad with FF
            Util.arrayFillNonAtomic(buffer, offset, (short)(le - offset), (byte)MemoryState.Free);

            // and send data!
            apdu.SetOutgoingLength(le);
            return(apdu.SendBytesLong(buffer, 0, le));
        }
Beispiel #2
0
        /// <summary>
        /// Process WRITE BINARY instruction (CC3)
        /// <para>
        /// C-APDU: <code>00 B0 {offset} {Lc} {data} </code>
        /// </para>
        /// <list type="table">
        ///     <item>
        ///         <term>offset</term>
        ///         <description>offset of first word of the file coded by P1 P2 (WORDS) to be written.</description>
        ///     </item>
        ///     <item>
        ///         <term>data</term>
        ///         <description>data to be written in file.</description>
        ///     </item>
        /// </list>
        /// </summary>
        /// <param name="apdu"></param>
        /// <returns></returns>
        private IFakeCardFeedback ProcessWrite(CommandAPDU apdu)
        {
            // TODO: check ==> security of current EF

            byte[] apduBuffer = apdu.GetBuffer();
            apdu.SetIncomingAndReceive();

            short offset    = Util.getShort(apduBuffer, JavaCard.ISO7816.OFFSET_P1); // in WORDS
            short length    = APDUHelpers.getIncomingLength(apdu);                   // in BYTES
            short wordCount = (short)((short)(length + 3) / 4);                      // length in WORDS

            // availability check
            VerifyOutOfFile(offset, wordCount);
            if (!_currentEF.IsAvailable(offset, wordCount))
            {
                ISOException.throwIt(JavaCard.ISO7816.SW_WRONG_LENGTH);
            }

            // copy data in a buffer
            byte[] buffer    = JCSystem.makeTransientByteArray((short)(wordCount * 4), JCSystem.CLEAR_ON_DESELECT);
            short  udcOffset = APDUHelpers.getOffsetCdata(apdu);

            Util.arrayCopyNonAtomic(apduBuffer, udcOffset, buffer, 0, length);

            // complete words with FF in buffer
            short iMax = (short)(wordCount * 4);

            for (short i = length; i < iMax; i++)
            {
                buffer[i] = 0xFF;
            }

            // and write data to file
            _currentEF.Write(buffer, 0, offset, wordCount);

            return(FakeCardFeedback.FromSuccess(unchecked ((short)0x9000)));
        }