Beispiel #1
0
        /// <summary>
        /// Will try to connect to _connectedReader and read the card.
        /// </summary>
        /// <returns>Either the data from the card or the error message. Or if 'uidOnly' is true, just the UID prefixed with 'UID^' and ending with '^'</returns>
        public string ReadCard(bool uidOnly = false)
        {
            SCardContext context = new SCardContext();
            context.Establish(SCardScope.System);
            SCardReader reader = new SCardReader(context);

            SCardError result = reader.Connect(_connectedReader, SCardShareMode.Shared, SCardProtocol.Any);

            if (result != SCardError.Success)
            {
                context.Dispose();
                reader.Dispose();
                return string.Format("No card is detected (or reader reserved by another application){0}{1}",
                    Environment.NewLine, SCardHelper.StringifyError(result));
            }

            string[] readerNames; SCardProtocol protocol; SCardState state; byte[] atr;
            result = reader.Status(out readerNames, out state, out protocol, out atr);

            if (result != SCardError.Success)
            {
                context.Dispose();
                reader.Dispose();
                return string.Format("Unable to read from card.{0}{1}", Environment.NewLine, SCardHelper.StringifyError(result));
            }

            string message = string.Format("Card detected:{0}Protocol: {1}{0}State: {2}{0}ATR: {3}{0}",
                Environment.NewLine, protocol, state, BitConverter.ToString(atr ?? new byte[0]));

            CommandApdu apdu = new CommandApdu(IsoCase.Case2Short, reader.ActiveProtocol)
            {
                CLA = 0xFF,
                Instruction = InstructionCode.GetData,
                P1 = 0x00,
                P2 = 0x00,
                Le = 0
            };

            result = reader.BeginTransaction();

            if (result != SCardError.Success)
            {
                context.Dispose();
                reader.Dispose();
                return string.Format("Cannot start transaction.{0} {1}", Environment.NewLine, SCardHelper.StringifyError(result));
            }

            SCardPCI recievePci = new SCardPCI();
            IntPtr sendPci = SCardPCI.GetPci(reader.ActiveProtocol);

            byte[] recieveBuffer = new byte[256];

            result = reader.Transmit(sendPci, apdu.ToArray(), recievePci, ref recieveBuffer);

            if (result != SCardError.Success)
            {
                context.Dispose();
                reader.Dispose();
                return string.Format("Cannot transmit data.{0} {1}", Environment.NewLine, SCardHelper.StringifyError(result));
            }

            var responseApdu = new ResponseApdu(recieveBuffer, IsoCase.Case2Short, reader.ActiveProtocol);

            message += string.Format("SW1: {1}{0}SW2: {2}{0}", Environment.NewLine, responseApdu.SW1, responseApdu.SW2);

            string data = responseApdu.HasData ? BitConverter.ToString(responseApdu.GetData()) : "--";

            if (uidOnly)
            {
                context.Dispose();
                reader.Dispose();
                return string.Format("UID^{0}^", data);
            }

            message += string.Format("UID: {0}",data);

            reader.EndTransaction(SCardReaderDisposition.Leave);
            reader.Disconnect(SCardReaderDisposition.Reset);

            context.Dispose();
            reader.Dispose();
            return message;
        }
Beispiel #2
0
        public static void Main() {
            using (var context = new SCardContext()) {
                context.Establish(SCardScope.System);

                var readerNames = context.GetReaders();
                if (readerNames == null || readerNames.Length < 1) {
                    Console.WriteLine("You need at least one reader in order to run this example.");
                    Console.ReadKey();
                    return;
                }

                var readerName = ChooseRfidReader(readerNames);
                if (readerName == null) {
                    return;
                }

                using (var rfidReader = new SCardReader(context)) {

                    var sc = rfidReader.Connect(readerName, SCardShareMode.Shared, SCardProtocol.Any);
                    if (sc != SCardError.Success) {
                        Console.WriteLine("Could not connect to reader {0}:\n{1}",
                            readerName,
                            SCardHelper.StringifyError(sc));
                        Console.ReadKey();
                        return;
                    }
                    
                    var apdu = new CommandApdu(IsoCase.Case2Short, rfidReader.ActiveProtocol) {
                        CLA = 0xFF,
                        Instruction = InstructionCode.GetData,
                        P1 = 0x00,
                        P2 = 0x00,
                        Le = 0  // We don't know the ID tag size
                    };

                    sc = rfidReader.BeginTransaction();
                    if (sc != SCardError.Success) {
                        Console.WriteLine("Could not begin transaction.");
                        Console.ReadKey();
                        return;
                    }

                    Console.WriteLine("Retrieving the UID .... ");

                    var receivePci = new SCardPCI(); // IO returned protocol control information.
                    var sendPci = SCardPCI.GetPci(rfidReader.ActiveProtocol);

                    var receiveBuffer = new byte[256];
                    var command = apdu.ToArray();

                    sc = rfidReader.Transmit(
                        sendPci,            // Protocol Control Information (T0, T1 or Raw)
                        command,            // command APDU
                        receivePci,         // returning Protocol Control Information
                        ref receiveBuffer); // data buffer

                    if (sc != SCardError.Success) {
                        Console.WriteLine("Error: " + SCardHelper.StringifyError(sc));
                    }

                    var responseApdu = new ResponseApdu(receiveBuffer, IsoCase.Case2Short, rfidReader.ActiveProtocol);
                    Console.Write("SW1: {0:X2}, SW2: {1:X2}\nUid: {2}", 
                        responseApdu.SW1, 
                        responseApdu.SW2, 
                        responseApdu.HasData ? BitConverter.ToString(responseApdu.GetData()) : "No uid received");

                    rfidReader.EndTransaction(SCardReaderDisposition.Leave);
                    rfidReader.Disconnect(SCardReaderDisposition.Reset);

                    Console.ReadKey();
                }
            }
        }
Beispiel #3
0
        private byte[] ReadFileNextBlock(int offSet, int lenght)
        {
            TS.TraceV("Start ReadFileNextBlock, offset = \"{0}\", length = \"{1}\".", offSet, lenght);
            byte[] pbRecvBuffer = new byte[lenght + 2]; //// Last 2 bytes are sw1 + sw2
            byte[] offSetArr = MTVReader.Converter.IntToByteArray(offSet, 2);
            byte[] lenghtArr = MTVReader.Converter.IntToByteArray(lenght, 1);
            byte[] readFile = new byte[] { 0x00, 0xB0, offSetArr[0], offSetArr[1], lenghtArr[0] };

            SCardError err = this.crdReader.Transmit(readFile, ref pbRecvBuffer);
            if (err != SCardError.Success)
            {
                TS.TraceV("CardReaderException: \"{0}\".", SCardHelper.StringifyError(err));
                throw new CardReaderException(err, "Unfortunately, this smart card can not be read");
            }

            ResponseApdu resp = new ResponseApdu(pbRecvBuffer, IsoCase.Case4Extended, this.crdReader.ActiveProtocol);
            if ((resp.SW1 != 0x90) && (resp.SW2 != 0x00))
            {
                throw new CardReaderException(string.Format("Error reading next block for file at offset {0}, length {1}", offSet, lenght));
            }
            TS.TraceV("End ReadFileNextBlock.");
            return resp.GetData();
        }
Beispiel #4
0
        public byte[] ReadFile(byte[] AID, byte[] FileID)
        {
            TS.TraceI("Readfile with AID \"{0}\" and FileID \"{1}\".", Helper.ByteArrayToString(AID), Helper.ByteArrayToString(FileID));
            SelectApplet(AID);

            if (FileID.Length != 0x02)
            {
                throw new ArgumentException("Invalid length FileID", "FileID");
            }

            if (this.crdReader == null)
            {
                throw new CardReaderException("No valid reader available");
            }

            byte[] pbRecvBuffer = new byte[256];

            //// Send SELECT File
            byte[] selectFile = new byte[] { 0x00, 0xA4, 0x02, 0x04, 0x02, FileID[0], FileID[1], 0x00 };
            TS.TraceV("Select file with command: \"{0}\".", Helper.ByteArrayToString(selectFile));
            /*
                00 = Class
                A4 = Instructie
                02 = P1 (select EF under current DF)
                04 = P2 (return FCP data)
                02 = Lc
                XX = Data
                XX = Data
                00 = Le
            */
            SCardError err = this.crdReader.Transmit(selectFile, ref pbRecvBuffer);
            if (err != SCardError.Success)
            {
                throw new CardReaderException(err, SCardHelper.StringifyError(err));
            }

            ResponseApdu resp = new ResponseApdu(pbRecvBuffer, IsoCase.Case4Extended, this.crdReader.ActiveProtocol);
            if ((resp.SW1 != 0x90) && (resp.SW2 != 0x00))
            {
                return null;
            }

            byte[] fileInfo = resp.GetData();

            if (fileInfo == null)
            {
                throw new CardReaderException(string.Format(
                    "No data available reading FileID \"{0}\" with AID \"{1}\".", Helper.ByteArrayToString(FileID), Helper.ByteArrayToString(AID)));
            }

            TLVList myanswer = TLV.Parse(new MemoryStream(fileInfo));

            TLV fileLengthTLV = myanswer.getTag("1,62|1,80");
            if (fileLengthTLV == null)
            {
                throw new CardReaderException("Missing tag: 1,62|1,80");
            }

            int fileLength = Helper.ByteArrayToInt(fileLengthTLV.Value);
            TS.TraceV("File length = \"{0}\".", fileLength);

            //// Read the remaining bytes for this file
            byte[] fileData = new byte[fileLength];
            int bytesRead = 0;
            const int blockSize = 255;

            TS.TraceV("Start reading file with blocksize \"{0}\".", blockSize);
            while (bytesRead < fileLength)
            {
                int lngth = blockSize;
                if (fileLength - bytesRead < blockSize)
                {
                    //// Cannot read an entire block anymore; adjust length of data to read
                    lngth = fileLength - bytesRead;
                    if (lngth == 0)
                    {
                        break;
                    }
                }

                byte[] nextBlock = ReadFileNextBlock(bytesRead, lngth);
                Buffer.BlockCopy(nextBlock, 0, fileData, bytesRead, nextBlock.Length);
                bytesRead += nextBlock.Length;

                TS.TraceV("\"{0}\" bytes read.", bytesRead);
            }
            TS.TraceI("File read.");
            return fileData;
        }
        public string ReadSmartCard()
        {
            using (var context = new SCardContext())
            {
                context.Establish(SCardScope.System);
                string readerName = null;
                try
                {
                    string[] readerNames = context.GetReaders();
                    readerName = readerNames[0];
                }
                catch(Exception ex)
                {
                    return "error";
                }

                if (readerName == null)
                {
                    return "error";
                }

                using (var rfidReader = new SCardReader(context))
                {

                    var sc = rfidReader.Connect(readerName, SCardShareMode.Shared, SCardProtocol.Any);
                    if (sc != SCardError.Success)
                    {
                        return "error";//"Could not connect to reader {0}:\n{1}";

                    }

                    var apdu = new CommandApdu(IsoCase.Case2Short, rfidReader.ActiveProtocol)
                    {
                        CLA = 0xFF,
                        Instruction = InstructionCode.GetData,
                        P1 = 0x00,
                        P2 = 0x00,
                        Le = 0  // We don't know the ID tag size
                    };

                    sc = rfidReader.BeginTransaction();
                    if (sc != SCardError.Success)
                    {
                        return "none";// "Could not begin transaction.";

                    }

                    var receivePci = new SCardPCI(); // IO returned protocol control information.
                    var sendPci = SCardPCI.GetPci(rfidReader.ActiveProtocol);

                    var receiveBuffer = new byte[256];
                    var command = apdu.ToArray();

                    sc = rfidReader.Transmit(
                        sendPci,            // Protocol Control Information (T0, T1 or Raw)
                        command,            // command APDU
                        receivePci,         // returning Protocol Control Information
                        ref receiveBuffer); // data buffer

                    if (sc != SCardError.Success)
                    {
                        return "none";//SCardHelper.StringifyError(sc);
                    }

                    var responseApdu = new ResponseApdu(receiveBuffer, IsoCase.Case2Short, rfidReader.ActiveProtocol);

                    rfidReader.EndTransaction(SCardReaderDisposition.Leave);
                    rfidReader.Disconnect(SCardReaderDisposition.Reset);

                    int id = responseApdu.HasData ? BitConverter.ToInt32(responseApdu.GetData(),0) : -1;
                    //int id = responseApdu.HasData ? System.Text.Encoding.UTF8.GetString(responseApdu.GetData()) : "none";

                    if (id < 0) id = id * (-1);
                    return id.ToString();

                }
            }
            return "none";
        }