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);
        }
Example #2
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());
        }
        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);
        }
        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);
        }
Example #5
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());
        }
        /// <summary>
        /// Write all sectors to the card
        /// </summary>
        /// <param name="address"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private bool MifareClassicWrite(ushort address, byte[] data, byte[] key)
        {
            if (data == null)
            {
                return(false);
            }

            CAPDU capdu = null;

            if (key == null)
            {
                capdu = new CAPDU(0xFF, 0xF4, (byte)(address / 0x0100), (byte)(address % 0x0100), data);
            }
            else
            {
                // Concat data and key
                byte[] sentData = new byte[data.Length + key.Length];
                System.Buffer.BlockCopy(data, 0, sentData, 0, data.Length);
                System.Buffer.BlockCopy(key, 0, sentData, data.Length, key.Length);
                capdu = new CAPDU(0xFF, 0xF4, (byte)(address / 0x0100), (byte)(address % 0x0100), sentData);
            }

            Logger.Trace("< " + capdu.AsString(" ") + " (writing without 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)
            {
                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);
        }
Example #7
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);
        }
Example #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);
        }
Example #9
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);
        }
        protected byte[] MifareClassicRead(ushort blockNumber, byte dataLength = 0, byte[] keyValue = null)
        {
            CAPDU capdu = null;

            if (keyValue == null)               // Reading without key
            {
                capdu = new CAPDU(0xFF, 0xF3, (byte)(blockNumber / 0x0100), (byte)(blockNumber % 0x0100), dataLength);
            }
            else                                                // Reading with key
            {
                capdu = new CAPDU(0xFF, 0xF3, (byte)(blockNumber / 0x0100), (byte)(blockNumber % 0x0100), keyValue, dataLength);
            }

            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());
        }
Example #11
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);
        }
Example #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());
        }
Example #13
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());
        }
Example #14
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());
        }
Example #15
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);
        }
Example #16
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);
        }
Example #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);
        }
Example #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);
        }
Example #19
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);
        }
Example #20
0
        private void RunScript(object threadParams)
        {
            bool            fatalError = false;
            RunScriptParams runParams  = (RunScriptParams)threadParams;

            do
            {
                foreach (CAPDU capdu in runParams.script)
                {
                    AddToResult("\nCommand:");
                    AddToResult(capdu.AsString(" "), Color.Blue);

                    /* Perform the exchange */
                    RAPDU rapdu = runParams.card.Transmit(capdu);

                    /* Error during the exchange? */
                    if (rapdu == null)
                    {
                        AddToResult("\nError " + BinConvert.ToHex(runParams.card.LastError) + "\n", Color.Red);
                        AddToResult(runParams.card.LastErrorAsString + "\n", Color.Red);
                        if (runParams.stopOnPCSCError)
                        {
                            fatalError = true;
                        }
                        runParams.loop = false;
                        break;
                    }

                    /* Status word? */
                    Color responseColor;
                    bool  responseError = false;
                    if ((rapdu.SW == 0x9000) || (rapdu.SW == 0x9100) || (rapdu.SW == 0x91AF))
                    {
                        responseColor = Color.Green;
                    }
                    else if (rapdu.SW1 != 0x6F)
                    {
                        responseColor = Color.DarkOrange;
                        responseError = true;
                    }
                    else
                    {
                        responseColor = Color.Red;
                        responseError = true;
                    }

                    if (runParams.showHex)
                    {
                        AddToResult("\nResponse: (" + rapdu.Length + "B)\n");
                        AddToResult(rapdu.AsString(" "), responseColor);
                    }

                    if (runParams.showAscii)
                    {
                        if ((rapdu.data != null) && (rapdu.data.Length > 0))
                        {
                            AddToResult("\nResponse (ASCII):\n");
                            AddToResult(ConvertToString(rapdu.data.GetBytes()) + " / SW=" + BinConvert.ToHex(rapdu.SW), responseColor);
                        }
                        else if (!runParams.showHex)
                        {
                            AddToResult("\nResponse:\n");
                            AddToResult("SW=" + BinConvert.ToHex(rapdu.SW), responseColor);
                        }
                    }

                    AddToResult("\n(" + rapdu.SWString + ")\n", responseColor);

                    if (runParams.stopOnSWnot9000 && responseError)
                    {
                        runParams.loop = false;
                        break;
                    }
                }
            }while (runParams.loop);

            ScriptExited(fatalError);
        }