예제 #1
0
        protected static byte[] ReadBinary(SCardChannel channel, ushort offset, ushort length)
        {
            CAPDU capdu = new CAPDU(0x00, 0xB0, (byte)(offset / 0x0100), (byte)(offset % 0x0100), (byte)length);

            Trace.WriteLine("< " + capdu.AsString(" "));

            RAPDU rapdu = channel.Transmit(capdu);

            if (rapdu == null)
            {
                Trace.WriteLine("ReadBinary " + String.Format("{0:X4}", offset) + "," + String.Format("{0:X2}", (byte)length) + " error " + channel.LastError + " (" + channel.LastErrorAsString + ")");
                return(null);
            }

            Trace.WriteLine("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                Trace.WriteLine("ReadBinary " + String.Format("{0:X4}", offset) + "," + String.Format("{0:X2}", (byte)length) + " failed " + rapdu.SWString + " (" + SCARD.CardStatusWordsToString(rapdu.SW) + ")");
                return(null);
            }

            if (rapdu.hasData)
            {
                return(rapdu.data.GetBytes());
            }

            return(null);
        }
예제 #2
0
        protected static byte[] GetUid(SCardChannel channel)
        {
            CAPDU capdu = new CAPDU(0xFF, 0xCA, 0x00, 0x00, 0x00);

            Trace.WriteLine("< " + capdu.AsString(" "));

            RAPDU rapdu = null;

            rapdu = channel.Transmit(capdu);
            if (rapdu == null)
            {
                Trace.WriteLine("Error '" + channel.LastErrorAsString + "' while getting the card's UID");
                return(null);
            }

            Trace.WriteLine("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                Trace.WriteLine("Bad status word " + rapdu.SWString + " while getting the card's UID");
                return(null);
            }

            if (!rapdu.hasData)
            {
                Trace.WriteLine("Empty response");
                return(null);
            }

            return(rapdu.data.GetBytes());
        }
예제 #3
0
        protected override LLCP_PDU Exchange(LLCP_PDU send_pdu)
        {
            Trace.WriteLine("< " + send_pdu.AsString());

            CAPDU capdu = new CAPDU(0xFF, 0xFE, 0x00, 0x00, send_pdu.GetBytes());

            Trace.WriteLine("< " + capdu.AsString());

            RAPDU rapdu = _channel.Transmit(capdu);

            if (rapdu == null)
            {
                return(null);
            }

            Trace.WriteLine("> " + rapdu.AsString());

            if (rapdu.SW != 0x9000)
            {
                return(null);
            }

            LLCP_PDU recv_pdu = new LLCP_PDU(rapdu.data);

            Trace.WriteLine("> " + recv_pdu.AsString());

            return(recv_pdu);
        }
예제 #4
0
        protected byte[] ReadUID()
        {
            CAPDU capdu = new CAPDU(0xFF, 0xCA, 0x00, 0x00, 0x00);

            Logger.Trace("< " + capdu.AsString(" "));

            RAPDU rapdu = null;

            rapdu = Channel.Transmit(capdu);

            if (rapdu == null)
            {
                Logger.Trace("Error '" + Channel.LastErrorAsString + "' while reading the UID");
                return(null);
            }

            Logger.Trace("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                Logger.Trace("Bad status word " + rapdu.SWString + " while reading the UID");
                return(null);
            }

            if (!rapdu.hasData)
            {
                Logger.Trace("Empty response");
                return(null);
            }

            return(rapdu.data.GetBytes());
        }
        public static bool IsDesfireEV1(SCardChannel channel)
        {
            bool is_desfire_ev1 = false;

            CAPDU capdu = new CAPDU(0x90, 0x60, 0x00, 0x00, 0x00);

            Trace.WriteLine("< " + capdu.AsString(" "));

            RAPDU rapdu = channel.Transmit(capdu);

            Trace.WriteLine("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x91AF)
            {
                Trace.WriteLine("Desfire GetVersion function failed");
                return(false);
            }

            if (rapdu.GetByte(3) > 0)
            {
                Trace.WriteLine("This is a Desfire EV1");
                is_desfire_ev1 = true;
            }
            else
            {
                Trace.WriteLine("This is a Desfire EV0");
            }

            capdu = new CAPDU(0x90, 0xAF, 0x00, 0x00, 0x00);

            Trace.WriteLine("< " + capdu.AsString(" "));

            rapdu = channel.Transmit(capdu);
            Trace.WriteLine("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x91AF)
            {
                Trace.WriteLine("Desfire GetVersion(2) function failed");
                return(false);
            }

            capdu = new CAPDU(0x90, 0xAF, 0x00, 0x00, 0x00);

            Trace.WriteLine("< " + capdu.AsString(" "));

            rapdu = channel.Transmit(capdu);
            Trace.WriteLine("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9100)
            {
                Trace.WriteLine("Desfire GetVersion(3) function failed");
                return(false);
            }

            return(is_desfire_ev1);
        }
예제 #6
0
        private bool WriteBinaryWithKey(ushort address, byte[] data, byte[] key)
        {
            if (data == null)
            {
                return(false);
            }

            if (key == null)
            {
                return(false);
            }

            byte[] dataAndKey = new byte[data.Length + key.Length];
            Array.ConstrainedCopy(data, 0, dataAndKey, 0, data.Length);
            Array.ConstrainedCopy(key, 0, dataAndKey, data.Length, key.Length);

            CAPDU capdu = new CAPDU(0xFF, 0xF4, (byte)(address / 0x0100), (byte)(address % 0x0100), dataAndKey);

            log("< " + capdu.AsString(" ") + " (writing with specified key)");

            RAPDU rapdu = null;

            for (int retry = 0; retry < 4; retry++)
            {
                rapdu = _channel.Transmit(capdu);

                if (rapdu == null)
                {
                    break;
                }
                if ((rapdu.SW != 0x6F01) && (rapdu.SW != 0x6F02) && (rapdu.SW != 0x6F0B))
                {
                    break;
                }

                Thread.Sleep(15);
            }

            if (rapdu == null)
            {
                log("Error '" + _channel.LastErrorAsString + "' while writing the card");
                return(false);
            }

            log("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                log("Bad status word " + rapdu.SWString + " while writing the card");
                return(false);
            }

            return(true);
        }
예제 #7
0
        protected static bool WriteBinary(SCardChannel channel, ushort address, byte[] data)
        {
            if (data == null)
            {
                return(false);
            }

            if (data.Length != 4)
            {
                Trace.WriteLine("Type 2 Tag: Write Binary accepts only 4B");
                return(false);
            }

            CAPDU capdu = new CAPDU(0xFF, 0xD6, (byte)(address / 0x0100), (byte)(address % 0x0100), data);

            Trace.WriteLine("< " + capdu.AsString(" "));


            RAPDU rapdu = null;

            for (int retry = 0; retry < 4; retry++)
            {
                rapdu = channel.Transmit(capdu);

                if (rapdu == null)
                {
                    break;
                }
                if ((rapdu.SW != 0x6F01) && (rapdu.SW != 0x6F02) && (rapdu.SW != 0x6F0B))
                {
                    break;
                }

                Thread.Sleep(15);
            }

            if (rapdu == null)
            {
                Trace.WriteLine("Error '" + channel.LastErrorAsString + "' while writing the card");
                return(false);
            }

            Trace.WriteLine("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                Trace.WriteLine("Bad status word " + rapdu.SWString + " while writing the card");
                return(false);
            }


            return(true);
        }
예제 #8
0
        private bool ReadBinaryWithKey(byte[] key)
        {
            int  address;
            byte length;

            GetSectorData(out address, out length);

            CAPDU capdu = new CAPDU(0xFF, 0xF3, (byte)(address / 0x0100), (byte)(address % 0x0100), key, length);

            Logger.Trace("< " + capdu.AsString(" ") + " (reading with specified key)");

            RAPDU rapdu = null;

            for (int retry = 0; retry < 4; retry++)
            {
                rapdu = Card.Channel.Transmit(capdu);

                if (rapdu == null)
                {
                    break;
                }
                if ((rapdu.SW != 0x6F01) && (rapdu.SW != 0x6F02) && (rapdu.SW != 0x6F0B))
                {
                    break;
                }

                Thread.Sleep(10);
            }

            if (rapdu == null)
            {
                Logger.Trace("Error '" + Card.Channel.LastErrorAsString + "' while reading the card");
                return(false);
            }

            Logger.Trace("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                Logger.Trace("Bad status word " + rapdu.SWString + " while reading the card");
                return(false);
            }

            if (!rapdu.hasData)
            {
                Logger.Trace("Empty response");
                return(false);
            }

            Data = rapdu.data.GetBytes();
            PopulateBlocks();
            return(true);
        }
예제 #9
0
        protected static byte[] ReadBinary(SCardChannel channel, ushort address, byte length)
        {
            CAPDU capdu = new CAPDU(0xFF, 0xB0, (byte)(address / 0x0100), (byte)(address % 0x0100), length);

            Trace.WriteLine("< " + capdu.AsString(" "));

            RAPDU rapdu = null;

            for (int retry = 0; retry < 4; retry++)
            {
                rapdu = channel.Transmit(capdu);

                if (rapdu == null)
                {
                    break;
                }
                if ((rapdu.SW != 0x6F01) && (rapdu.SW != 0x6F02) && (rapdu.SW != 0x6F0B))
                {
                    break;
                }

                Thread.Sleep(10);
            }

            if (rapdu == null)
            {
                Trace.WriteLine("Error '" + channel.LastErrorAsString + "' while reading the card");
                return(null);
            }

            Trace.WriteLine("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                Trace.WriteLine("Bad status word " + rapdu.SWString + " while reading the card");
                return(null);
            }

            if (!rapdu.hasData)
            {
                Trace.WriteLine("Empty response");
                return(null);
            }

            return(rapdu.data.GetBytes());
        }
예제 #10
0
        private bool WriteBinary(ushort address, byte[] data)
        {
            if (data == null)
            {
                return(false);
            }

            CAPDU capdu = new CAPDU(0xFF, 0xD6, (byte)(address / 0x0100), (byte)(address % 0x0100), data);

            log("< " + capdu.AsString(" "));

            RAPDU rapdu = null;

            for (int retry = 0; retry < 4; retry++)
            {
                rapdu = _channel.Transmit(capdu);

                if (rapdu == null)
                {
                    break;
                }
                if ((rapdu.SW != 0x6F01) && (rapdu.SW != 0x6F02) && (rapdu.SW != 0x6F0B))
                {
                    break;
                }

                Thread.Sleep(15);
            }

            if (rapdu == null)
            {
                log("Error '" + _channel.LastErrorAsString + "' while writing the card");
                return(false);
            }

            log("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                log("Bad status word " + rapdu.SWString + " while writing the card");

                return(false);
            }

            return(true);
        }
예제 #11
0
        /*
         * SCardTransmit
         * ------------
         */
        void BtnTransmitClick(object sender, EventArgs e)
        {
            RApduClear();

            DynamicByteProvider p;

            byte[] b;

            p = (DynamicByteProvider)hexBoxCApdu.ByteProvider;

            b = new byte[p.Length];

            for (int i = 0; i < p.Length; i++)
            {
                b[i] = p.ReadByte(i);
            }

            CAPDU capdu = new CAPDU(b);

            Settings.HistoryTransmit.Add(capdu.AsString());
            hist_apdu_idx = -1;

            RAPDU rapdu = channel.Transmit(capdu);

            if (rapdu == null)
            {
                ShowError();
            }
            else
            {
                ShowSuccess();

                b = rapdu.GetBytes();

                p = new DynamicByteProvider(b);

                hexBoxRApdu.ByteProvider = p;

                eStatusWord.Text        = String.Format("{0:X2} {1:X2}", rapdu.SW1, rapdu.SW2);
                eStatusWordExplain.Text = rapdu.SWString;

                hexBoxRApdu.BackColor        = hexBoxCApdu.BackColor;
                eStatusWord.BackColor        = eCardAtr.BackColor;
                eStatusWordExplain.BackColor = eCardAtr.BackColor;
            }
        }
예제 #12
0
        private byte[] ReadBinaryWithKey(ushort address, byte length, byte[] key)
        {
            CAPDU capdu = new CAPDU(0xFF, 0xF3, (byte)(address / 0x0100), (byte)(address % 0x0100), key, length);

            log("< " + capdu.AsString(" ") + " (reading with specified key)");

            RAPDU rapdu = null;

            for (int retry = 0; retry < 4; retry++)
            {
                rapdu = _channel.Transmit(capdu);

                if (rapdu == null)
                {
                    break;
                }
                if ((rapdu.SW != 0x6F01) && (rapdu.SW != 0x6F02) && (rapdu.SW != 0x6F0B))
                {
                    break;
                }

                Thread.Sleep(10);
            }

            if (rapdu == null)
            {
                log("Error '" + _channel.LastErrorAsString + "' while reading the card");
                return(null);
            }

            log("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                log("Bad status word " + rapdu.SWString + " while reading the card");
                return(null);
            }

            if (!rapdu.hasData)
            {
                log("Empty response");
                return(null);
            }

            return(rapdu.data.GetBytes());
        }
예제 #13
0
        protected byte[] ReadBinary(ushort P1P2, byte Le = 0)
        {
            CAPDU capdu = new CAPDU(0xFF, 0xB0, (byte)(P1P2 / 0x0100), (byte)(P1P2 % 0x0100), Le);

            Logger.Trace("< " + capdu.AsString(" "));

            RAPDU rapdu = null;

            for (int retry = 0; retry < 4; retry++)
            {
                rapdu = Channel.Transmit(capdu);

                if (rapdu == null)
                {
                    break;
                }
                if ((rapdu.SW != 0x6F01) && (rapdu.SW != 0x6F02) && (rapdu.SW != 0x6F0B))
                {
                    break;
                }
            }

            if (rapdu == null)
            {
                Logger.Trace("Error '" + Channel.LastErrorAsString + "' while reading the card");
                return(null);
            }

            Logger.Trace("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                Logger.Trace("Bad status word " + rapdu.SWString + " while reading the card");
                return(null);
            }

            if (!rapdu.hasData)
            {
                Logger.Trace("Empty response");
                return(null);
            }

            return(rapdu.data.GetBytes());
        }
예제 #14
0
        protected bool WriteBinary(ushort P1P1, byte[] Data)
        {
            if (Data == null)
            {
                return(false);
            }

            CAPDU capdu = new CAPDU(0xFF, 0xD6, (byte)(P1P1 / 0x0100), (byte)(P1P1 % 0x0100), Data);

            Logger.Trace("< " + capdu.AsString(" "));

            RAPDU rapdu = null;

            for (int retry = 0; retry < 4; retry++)
            {
                rapdu = Channel.Transmit(capdu);

                if (rapdu == null)
                {
                    break;
                }
                if ((rapdu.SW != 0x6F01) && (rapdu.SW != 0x6F02) && (rapdu.SW != 0x6F0B))
                {
                    break;
                }
            }

            if (rapdu == null)
            {
                Logger.Trace("Error '" + Channel.LastErrorAsString + "' while writing the card");
                return(false);
            }

            Logger.Trace("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                Logger.Trace("Bad status word " + rapdu.SWString + " while writing the card");
                return(false);
            }

            return(true);
        }
예제 #15
0
        protected static bool WriteBinary(SCardChannel channel, ushort offset, byte[] buffer)
        {
            CAPDU capdu = new CAPDU(0x00, 0xD6, (byte)(offset / 0x0100), (byte)(offset % 0x0100), buffer);

            Trace.WriteLine("< " + capdu.AsString(" "));

            RAPDU rapdu = channel.Transmit(capdu);

            if (rapdu == null)
            {
                Trace.WriteLine("WriteBinary " + String.Format("{0:X4}", offset) + "," + String.Format("{0:X2}", (byte)buffer.Length) + " error " + channel.LastError + " (" + channel.LastErrorAsString + ")");
                return(false);
            }

            Trace.WriteLine("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                Trace.WriteLine("WriteBinary " + String.Format("{0:X4}", offset) + "," + String.Format("{0:X2}", (byte)buffer.Length) + " failed " + rapdu.SWString + " (" + SCARD.CardStatusWordsToString(rapdu.SW) + ")");
                return(false);
            }
            return(true);
        }
예제 #16
0
        private static bool SelectRootApplication(SCardChannel channel)
        {
            CAPDU capdu = new CAPDU(0x00, 0xA4, 0x00, 0x00, "3F00");

            Trace.WriteLine("< " + capdu.AsString(" "));

            RAPDU rapdu = channel.Transmit(capdu);

            if (rapdu == null)
            {
                Trace.WriteLine("SelectRootApplication error " + channel.LastError + " (" + channel.LastErrorAsString + ")");
                return(false);
            }

            Trace.WriteLine("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                Trace.WriteLine("SelectRootApplication failed " + rapdu.SWString + " (" + SCARD.CardStatusWordsToString(rapdu.SW) + ")");
                return(false);
            }

            return(true);
        }
예제 #17
0
        private static bool SelectNfcApplication(SCardChannel channel)
        {
            CAPDU capdu = new CAPDU(0x00, 0xA4, 0x04, 0x00, (new CardBuffer(NDEF_APPLICATION_ID)).GetBytes(), 0x00);

            Trace.WriteLine("< " + capdu.AsString(" "));

            RAPDU rapdu = channel.Transmit(capdu);

            if (rapdu == null)
            {
                Trace.WriteLine("SelectNfcApplication error " + channel.LastError + " (" + channel.LastErrorAsString + ")");
                return(false);
            }

            Trace.WriteLine("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                Trace.WriteLine("SelectNfcApplication failed " + rapdu.SWString + " (" + SCARD.CardStatusWordsToString(rapdu.SW) + ")");
                return(false);
            }

            return(true);
        }
예제 #18
0
        private static bool SelectFile(SCardChannel channel, ushort file_id)
        {
            CAPDU capdu = new CAPDU(0x00, 0xA4, 0x00, 0x0C, (new CardBuffer(file_id)).GetBytes());

            Trace.WriteLine("< " + capdu.AsString(" "));

            RAPDU rapdu = channel.Transmit(capdu);

            if (rapdu == null)
            {
                Trace.WriteLine("SelectFile " + String.Format("{0:X4}", file_id) + " error " + channel.LastError + " (" + channel.LastErrorAsString + ")");
                return(false);
            }

            Trace.WriteLine("> " + rapdu.AsString(" "));

            if (rapdu.SW != 0x9000)
            {
                Trace.WriteLine("SelectFile " + String.Format("{0:X4}", file_id) + " failed " + rapdu.SWString + " (" + SCARD.CardStatusWordsToString(rapdu.SW) + ")");
                return(false);
            }

            return(true);
        }