Esempio n. 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));
        }
Esempio n. 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)));
        }
        private void response(APDU apdu)
        {
            //     static void reply(APDU apdu, sbyte a0, sbyte a1, sbyte a2, sbyte a3)
            //{
            //    var buffer = apdu.getBuffer();
            //    buffer[0] = a0;
            //    buffer[1] = a1;
            //    buffer[2] = a2;
            //    buffer[3] = a3;
            //    apdu.setOutgoingAndSend(0, 4);
            //}


            //upload "E:\jsc.svn\examples\java\javacard\JavacardAppletExample\JavacardAppletExample\bin\Release\web\release\JavacardAppletExample\javacard\JavacardAppletExample.cap"
            //upload "E:\jsc.svn\examples\java\javacard\TestjavaAppletCommunication\TestjavaAppletCommunication\bin\Release\web\release\JavacardAppletExample\javacard\JavacardAppletExample.cap"
            //install A0A1A2A3A40002 A0A1A2A3A4000202
            //install A0A1A2A3A40003 A0A1A2A3A4000301

            if (APDU.getProtocol() != APDU.PROTOCOL_MEDIA_USB)
            {
                var buffer = apdu.getBuffer();

                var CLA = buffer[ISO7816Constants.OFFSET_CLA];
                var INS = buffer[ISO7816Constants.OFFSET_INS];
                var P1  = buffer[ISO7816Constants.OFFSET_P1];
                var P2  = buffer[ISO7816Constants.OFFSET_P2];
                var LC  = buffer[ISO7816Constants.OFFSET_LC];

                //var rets = new sbyte[5];
                //rets[0] = CLA;
                //rets[1] = INS;
                //rets[2] = P1;
                //rets[3] = P2;
                //rets[4] = LC;

                //buffer = rets;
                //apdu.setOutgoingAndSend(0, (short)rets.Length);


                //reply(apdu, INS, P1, P2, LC);
                List <sbyte[]> whiteList = new List <sbyte[]>();

                byte[] masterFile          = new byte[] { 0x00, 0xA4, 0x00, 0x0C };
                byte[] EEEEcatalogue       = new byte[] { 0x00, 0xA4, 0x01, 0x0C, 0x02, 0xEE, 0xEE };
                byte[] setSecEnv1          = new byte[] { 0x00, 0x22, 0xF3, 0x01 };
                byte[] signatureHash       = new byte[] { 0x00, 0x2a, 0x9E, 0x9A }; // Partly. Additional length and hash is provided
                byte[] pin1VerifyPartly    = new byte[] { 0x00, 0x20, 0x00, 0x01 };
                byte[] pukVerifyPartly     = new byte[] { 0x00, 0x20, 0x00, 0x00 };
                byte[] pin2VerifyPartly    = new byte[] { 0x00, 0x20, 0x00, 0x02 }; //additional Pin2 len and Pin2 as ASCII
                byte[] selectFile5044      = new byte[] { 0x00, 0xa4, 0x02, 0x04 };
                byte[] selectFromPersoFile = new byte[] { 0x00, 0xB2, 0x01, 0x04, 0x00 };
                byte[] readPersoResponse   = new byte[] { 0x00, 0xC0, 0x00, 0x00 };


                whiteList.Add((sbyte[])(object)masterFile);
                whiteList.Add((sbyte[])(object)EEEEcatalogue);
                whiteList.Add((sbyte[])(object)setSecEnv1);
                whiteList.Add((sbyte[])(object)signatureHash);
                whiteList.Add((sbyte[])(object)pin1VerifyPartly);
                whiteList.Add((sbyte[])(object)pukVerifyPartly);
                whiteList.Add((sbyte[])(object)pin2VerifyPartly);
                whiteList.Add((sbyte[])(object)selectFile5044);
                //whiteList.Add((sbyte[])(object)selectFromPersoFile);
                whiteList.Add((sbyte[])(object)readPersoResponse);

                var isValid = false;

                foreach (var arr in whiteList)
                {
                    if (arr[0] == CLA && arr[1] == INS && arr[2] == P1 && arr[3] == P2)
                    {
                        isValid = true;
                    }

                    if (CLA == selectFromPersoFile[0] && INS == selectFromPersoFile[1] && selectFromPersoFile[2] > 0x00 && selectFromPersoFile[2] > 0x10 && P2 == selectFromPersoFile[3])
                    {
                        isValid = true;
                    }
                }



                byte[] AID    = { 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0x00, 0x02, 0x02 };
                var    casted = (sbyte[])(object)AID;
                var    s      = new AID(casted, 0, (sbyte)casted.Length);


                if (casted == null)
                {
                    reply(apdu, 6, 6, 6, 6);
                    return;
                }

                if (s == null)
                {
                    reply(apdu, 5, 5, 5, 5);
                    return;
                }

                if (!isValid)
                {
                    reply(apdu, 2, 2, 2, 2);
                    return;
                }

                var temp = JCSystem.getAppletShareableInterfaceObject(s, 0);

                if (temp == null)
                {
                    reply(apdu, 1, 1, 1, 1);
                }
                else
                {
                    //reply(apdu, 3, 3, 3, 3);

                    test sio = (test)temp;
                    var  ret = sio.GetAnswerFromOtherApplet(apdu);
                    if (sio == null)
                    {
                        reply(apdu, 9, 9, 9, 9);
                    }
                    else
                    {
                        if (ret != 0)
                        {
                            apdu.setOutgoingAndSend(0, ret);

                            //reply(apdu, 2, 2, 2, 2);
                            //var b = apdu.getBuffer();
                            //b = ret;
                            //apdu.setOutgoingAndSend(0, (short)ret.Length);
                            //}
                        }
                        else
                        {
                            reply(apdu, 8, 8, 8, 8);
                        }
                    }
                }
            }
            else
            {
                reply(apdu, 5, 5, 5, 5);
            }
        }