Exemplo n.º 1
0
        /// <summary>
        /// Process FSEARCH instruction (CC2).
        /// <para>
        /// C-APDU: <code>00 B0 {P1-P2: offset} 04</code>
        /// </para>
        /// <para>
        /// R-APDU when an EF is selected: <code>{offset} {number of word in current EF} {looked-up word}</code>
        /// </para>
        /// <para>
        /// R-APDU when no EF is selected: <code>{offset} {number of word in current DF} {looked-up word}</code>
        /// </para>
        /// </summary>
        /// <param name="apdu"></param>
        /// <returns></returns>
        private IFakeCardFeedback ProcessFSearch(CommandAPDU apdu)
        {
            // get offset
            byte[] buffer = apdu.GetBuffer();
            short  offset = Util.getShort(buffer, JavaCard.ISO7816.OFFSET_P1); // in WORDS

            // get le
            short le = apdu.SetOutgoing(); // in BYTES

            if (le != 0)
            {
                ISOException.throwIt(JavaCard.ISO7816.SW_WRONG_LENGTH);
            }

            short wordCount;
            short offsetFound = offset;

            // check that there is a current EF
            if (_currentEF != null)
            {
                wordCount = (short)(_currentEF.GetLength() - _currentEF.GetHeaderSize());
                while (!(_currentEF.IsAvailable(offsetFound, 1) || offsetFound == wordCount))
                {
                    offsetFound++;
                }
            }
            else
            {
                wordCount = (short)(_currentDF.GetLength() - _currentDF.GetHeaderSize());
                while (!(_currentDF.IsAvailable(offsetFound, 1) || offsetFound == wordCount))
                {
                    offsetFound++;
                }
            }

            // check that there is still some empty space
            if (offsetFound == wordCount)
            {
                ISOException.throwIt(Constants.SW_DATA_NOT_FOUND);
            }
            // copy answer in buffer
            Util.setShort(buffer, 0, offsetFound);
            Util.setShort(buffer, 2, wordCount);
            Util.arrayFillNonAtomic(buffer, 4, 4, (byte)MemoryState.Free);

            // and send it!
            return(apdu.SetOutgoingAndSend(0, 8));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Process GENERATE RANDOM instruction (CC2)
        /// <para>
        /// C-APDU: <code>00 C4 00 00 08</code>
        /// </para>
        /// </summary>
        /// <param name="apdu"></param>
        /// <returns></returns>
        private IFakeCardFeedback ProcessGenerateRandom(CommandAPDU apdu)
        {
            byte[] apduBuffer = apdu.GetBuffer();
            short  le         = apdu.SetOutgoing();

            // verify that Le='08'
            if (le != 8)
            {
                // if not => error
                ISOException.throwIt(JavaCard.ISO7816.SW_WRONG_LENGTH);
            }

            // generate 8 random bytes
            var rndGen = new RNGCryptoServiceProvider();

            rndGen.GetBytes(apduBuffer, 0, 8);
            // and send it!
            return(apdu.SetOutgoingAndSend(0, 8));
        }
Exemplo n.º 3
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));
        }