public byte[] GetUid(SCardReader reader)
        {
            SCardError sc = reader.BeginTransaction();

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

            var responseApdu = SendAPDU(apdu, reader);

            reader.EndTransaction(SCardReaderDisposition.Leave);

            if (responseApdu != null && responseApdu.HasData)
            {
                return responseApdu.GetData();
            }
            else
            {
                return new byte[0];
            }
        }
Example #2
0
        public static void connect()
        {
            hContext = new SCardContext();
            hContext.Establish(SCardScope.System);

            string[] readerList = hContext.GetReaders();
            Boolean noReaders = readerList.Length <= 0;
            if (noReaders)
            {
                throw new PCSCException(SCardError.NoReadersAvailable, "Blad czytnika");
            }

            Console.WriteLine("Nazwa czytnika: " + readerList[0]);

            reader = new SCardReader(hContext);

            err = reader.Connect(readerList[0],
                SCardShareMode.Shared,
                SCardProtocol.T0 | SCardProtocol.T1);
            checkError(err);

            switch (reader.ActiveProtocol)
            {
                case SCardProtocol.T0:
                    protocol = SCardPCI.T0;
                    break;
                case SCardProtocol.T1:
                    protocol = SCardPCI.T1;
                    break;
                default:
                    throw new PCSCException(SCardError.ProtocolMismatch, "nieobslugiwany protokol: "+ reader.ActiveProtocol.ToString());
            }
        }
Example #3
0
        static void Main()
        {
            using (var context = new SCardContext()) {

                context.Establish(SCardScope.System);

                // retrieve all reader names
                var readerNames = context.GetReaders();

                if (readerNames == null || readerNames.Length < 1) {
                    Console.WriteLine("No readers found.");
                    Console.ReadKey();
                    return;
                }

                // get the card status of each reader that is currently connected
                foreach (var readerName in readerNames) {
                    using (var reader = new SCardReader(context)) {
                        Console.WriteLine("Trying to connect to reader {0}.",  readerName);

                        var sc = reader.Connect(readerName, SCardShareMode.Shared, SCardProtocol.Any);
                        if (sc == SCardError.Success) {
                            DisplayReaderStatus(reader);
                        } else {
                            Console.WriteLine("No card inserted or reader is reserved exclusively by another application.");
                            Console.WriteLine("Error message: {0}\n", SCardHelper.StringifyError(sc));
                        }
                    }
                }

                Console.ReadKey();
            }
        }
Example #4
0
        static void Main(string[] args)
        {
            var context = new SCardContext();

            context.Establish(SCardScope.System);

            // Get readers
            Console.WriteLine("Currently connected readers: ");
            var readerNames = context.GetReaders();

            foreach (var readerName in readerNames)
            {
                Console.WriteLine("\t" + readerName);
            }

            if (readerNames.Length == 0)
            {
                Console.WriteLine("No readers");
            }
            else
            {
                var reader = new SCardReader(context);
                reader.Connect(readerNames[0], SCardShareMode.Shared, SCardProtocol.T0 | SCardProtocol.T1);
                IntPtr protocol;
                switch (reader.ActiveProtocol)
                {
                case SCardProtocol.T0:
                    protocol = SCardPCI.T0;
                    break;

                case SCardProtocol.T1:
                    protocol = SCardPCI.T1;
                    break;

                default:
                    throw new PCSCException(SCardError.ProtocolMismatch, "No protocol: " + reader.ActiveProtocol.ToString());
                }

                // SELECT TELECOM
                SendCommand(reader, protocol, new byte[] { 0xA0, 0xA4, 0x00, 0x00, 0x02, 0x7F, 0x10, }, "SELECT TELECOM", ReadType.Bytes);

                // GET RESPONSE
                SendCommand(reader, protocol, new byte[] { 0xA0, 0xC0, 0x00, 0x00, 0x16 }, "GET RESPONSE", ReadType.Bytes);

                // SELECT ADN
                SendCommand(reader, protocol, new byte[] { 0xA0, 0xA4, 0x00, 0x00, 0x02, 0x6F, 0x3A }, "SELECT ADN", ReadType.Bytes);

                // GET RESPONSE
                SendCommand(reader, protocol, new byte[] { 0xA0, 0xC0, 0x00, 0x00, 0x0F }, "GET RESPONSE", ReadType.Bytes);

                // READ RECORD
                for (byte i = 0; i < 45; ++i)
                {
                    SendCommand(reader, protocol, new byte[] { 0xA0, 0xB2, i, 0x04, 0x2E }, "READ RECORD", ReadType.ASCII);
                }
                context.Release();
            }
            Console.Read();
        }
Example #5
0
        static void Main(string[] args)
        {
            SCardContext ctx = new SCardContext();
            ctx.Establish(SCardScope.System);

            string[] readernames = ctx.GetReaders();
            if (readernames == null || readernames.Length < 1)
                throw new Exception("You need at least one reader in order to run this example.");

            // Receive the ATR of each reader by using the GetAttrib function
            foreach (string name in readernames)
            {
                SCardReader reader = new SCardReader(ctx);

                Console.Write("Trying to connect to reader.. " + name);

                // Connect to the reader, error if no card present.
                SCardError rc = reader.Connect(
                    name,
                    SCardShareMode.Shared,
                    SCardProtocol.Any);

                if (rc == SCardError.Success)
                {
                    // Reader is now connected.
                    Console.WriteLine(" done.");

                    // receive ATR string attribute
                    byte[] atr;
                    rc = reader.GetAttrib(SCardAttr.ATRString, out atr);

                    if (rc != SCardError.Success)
                        // ATR not supported?
                        Console.WriteLine("Error by trying to receive the ATR. "
                            + SCardHelper.StringifyError(rc) + "\n");
                    else
                    {
                        Console.WriteLine("ATR: " + StringAtr(atr) + "\n");
                    }

                    // Disconnect
                    reader.Disconnect(SCardReaderDisposition.Leave);
                }
                else
                {
                    // Probably no SmartCard present.
                    Console.WriteLine(" failed. " + SCardHelper.StringifyError(rc) + "\n");
                }
            }

            ctx.Release();
            return;
        }
Example #6
0
        // Send APDU command
        public static void SendCommand(SCardReader reader, IntPtr protocol, byte[] comand, string codeTag, ReadType readType)
        {
            byte[] recivedBytes = new byte[256];
            var    response     = reader.Transmit(protocol, comand, ref recivedBytes);

            if (response == SCardError.Success)
            {
                Console.Write(codeTag + ": SW2: ");
                switch (readType)
                {
                case ReadType.Bytes:
                    foreach (byte code in recivedBytes)
                    {
                        Console.Write("{0:X2} ", code);
                    }
                    break;

                case ReadType.ASCII:
                    bool numberFlag = false;
                    int  numLength  = -1;
                    foreach (byte code in recivedBytes)
                    {
                        if (code == 255)
                        {
                            numberFlag = true;
                        }
                        else if (numberFlag && numLength == -1)
                        {
                            numLength = code;
                        }
                        else if (numLength != -1)
                        {
                            Console.Write("{0}{1}", (code & 0xF0) >> 4, code & 0xF);
                        }
                        else
                        {
                            Console.Write("{0:X2}", (char)code);
                        }
                    }
                    break;
                }
                Console.WriteLine();
            }
            else
            {
                Console.WriteLine("Send command error");
            }
        }
Example #7
0
        public static void Main() {
            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;
            }

            // Receive the ATR of each reader by using the GetAttrib function
            foreach (var readerName in readerNames) {
                var reader = new SCardReader(context);

                Console.Write("Trying to connect to reader.. " + readerName);

                // Connect to the reader, error if no card present.
                var rc = reader.Connect(readerName, SCardShareMode.Shared, SCardProtocol.Any);

                if (rc != SCardError.Success) {
                    Console.WriteLine(" failed. No smart card present? " + SCardHelper.StringifyError(rc) + "\n");
                } else {
                    Console.WriteLine(" done.");

                    // receive ATR string attribute
                    byte[] atr;
                    rc = reader.GetAttrib(SCardAttribute.AtrString, out atr);

                    if (rc != SCardError.Success) {
                        // ATR not supported?
                        Console.WriteLine("Error by trying to receive the ATR. {0}\n", SCardHelper.StringifyError(rc));
                    } else {
                        Console.WriteLine("ATR: {0}\n", BitConverter.ToString(atr ?? new byte[] {}));
                    }

                    reader.Disconnect(SCardReaderDisposition.Leave);
                }
            }

            // We MUST release here since we didn't use the 'using(..)' statement
            context.Release();
            Console.ReadKey();
        }
 public override byte[] GetCardMemory(SCardReader reader)
 {
     SCardError sc = reader.BeginTransaction();
     if (sc != SCardError.Success)
     {
         //TODO
         return new byte[0];
     }
     byte[] memory = new byte[12 * 4];
     int offset = 0;
     for (byte i = 0x04; i < 0x10; i++)
     {
         byte[] page = getPage(i, reader);
         Array.Copy(page, 0, memory, offset, page.Length);
         offset += page.Length;
     }
     reader.EndTransaction(SCardReaderDisposition.Leave);
     return memory;
 }
        protected ResponseApdu SendAPDU(CommandApdu apdu, SCardReader reader)
        {
            var receivePci = new SCardPCI(); // IO returned protocol control information.
            var sendPci = SCardPCI.GetPci(reader.ActiveProtocol);

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

            SCardError sc = reader.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)
            {
                // todo
                return null;
            }

            return new ResponseApdu(receiveBuffer, IsoCase.Case2Short, reader.ActiveProtocol);
        }
        private byte[] getPage(byte page, SCardReader reader)
        {
            var apdu = new CommandApdu(IsoCase.Case2Short, reader.ActiveProtocol)
            {
                CLA = 0xFF,
                Instruction = InstructionCode.ReadBinary,
                P1 = 0x00,
                P2 = page, // block number
                Le = 0x04  // bytes to read
            };

            var responseApdu = SendAPDU(apdu, reader);

            if (responseApdu != null && responseApdu.HasData)
            {
                return responseApdu.GetData();
            }
            else
            {
                return new byte[0];
            }
        }
Example #11
0
        static void Main(string[] args)
        {
            // Establish PC/SC context
            SCardContext ctx = new SCardContext();
            ctx.Establish(SCardScope.System);

            // Create a reader object
            SCardReader reader = new SCardReader(ctx);

            // Use the first reader that is found
            string firstreader = ctx.GetReaders()[0];

            // Connect to the card
            IsoCard card = new IsoCard(reader);
            card.Connect(firstreader, SCardShareMode.Shared, SCardProtocol.Any);

            // Build a ATR fetch case
            CommandApdu apdu = card.ConstructCommandApdu(
                IsoCase.Case2Short);

            apdu.CLA = 0x00; // Class
            apdu.INS = 0x84; // Instruction: GET CHALLENGE 
            apdu.P1 = 0x00;  // Parameter 1
            apdu.P2 = 0x00;  // Parameter 2
            apdu.Le = 0x08;  // Expected length of the returned data

            // Transmit the Command APDU to the card and receive the response
            Response resp = card.Transmit(apdu);

            // Show SW1SW2 from the last response packet (if more than one has been received).
            Console.WriteLine("SW1: {0:X2} SW2: {1:X2}", resp.SW1, resp.SW2);

            byte[] data;

            // First test - get the data from all response APDUs
            data = resp.GetData();
            if (data != null)
            {
                Console.Write("CHALLENGE:");

                foreach (byte b in data)
                    Console.Write(" {0:X2}", b);
                Console.WriteLine();
            }

            // Second test - get the data from each response APDU.
            int i = 0;
            foreach (ResponseApdu respApdu in resp.ResponseApduList)
            {
                data = respApdu.GetData();

                if (data != null)
                {
                    Console.Write("APDU ({0}), DATA:", i);
                    foreach (byte b in data)
                        Console.Write(" {0:X2}", b);
                    Console.WriteLine();
                    i++;
                }
            }
            return;
        }
Example #12
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();
                }
            }
        }
Example #13
0
        static void Main(string[] args)
        {
            try
            {
            SCardContext hContext = new SCardContext();
            hContext.Establish(SCardScope.System);

            var szReaders = hContext.GetReaders();

            if (szReaders.Length <= 0)
                throw new PCSCException(SCardError.NoReadersAvailable,
                    "Could not find any Smartcard reader.");

                Console.WriteLine("reader name: " + szReaders[1]);

                // Create a reader object using the existing context
                SCardReader reader = new SCardReader(hContext);

                // Connect to the card
                SCardError err = reader.Connect(szReaders[1],
                    SCardShareMode.Shared,
                    SCardProtocol.T0 | SCardProtocol.T1);
                CheckErr(err);

                IntPtr pioSendPci;
                switch (reader.ActiveProtocol)
                {
                    case SCardProtocol.T0:
                        pioSendPci = SCardPCI.T0;
                        break;
                    case SCardProtocol.T1:
                        pioSendPci = SCardPCI.T1;
                        break;
                    default:
                        throw new PCSCException(SCardError.ProtocolMismatch,
                            "Protocol not supported: "
                            + reader.ActiveProtocol.ToString());
                }

                byte[] pbRecvBuffer = new byte[256];

                // Send SELECT command
                // Select command 0x00, 0xA4, 0x04, 0x00,
                //Length  0x08
                //AID A0A1A2A3A4000301
                byte[] cmd1 = new byte[] { 0x00, 0xA4, 0x04, 0x00, 0x08, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0x00, 0x03, 0x01 };
                err = reader.Transmit(pioSendPci, cmd1, ref pbRecvBuffer);
                CheckErr(err);

                //(6A82: The application to be selected could not be found.)

                Console.Write("Select response: ");
                for (int i = 0; i < pbRecvBuffer.Length; i++)
                    Console.Write("{0:X2} ", pbRecvBuffer[i]);
                Console.WriteLine();

                pbRecvBuffer = new byte[256];

                // Send test command
                byte[] cmd2 = new byte[] { 0x00, 0x00, 0x00, 0x00 };
                err = reader.Transmit(pioSendPci, cmd2, ref pbRecvBuffer);
                CheckErr(err);

                Console.Write("Test commad response: ");
                for (int i = 0; i < pbRecvBuffer.Length; i++)
                    Console.Write("{0:X2} ", pbRecvBuffer[i]);
                Console.WriteLine();

                hContext.Release();
                
            }
            catch (PCSCException ex)
            {
                Console.WriteLine("Ouch: "
                    + ex.Message
                    + " (" + ex.SCardError.ToString() + ")");
            }
             Console.ReadLine();
        }
Example #14
0
        public byte[] SendBytes(byte[] inBytes, SCardReader reader, SCardError err, SCardContext context)
        {
            try
            {
                //SCardReader reader = new SCardReader(context);
                //// Connect to the card
                //Console.WriteLine(readerName);
                //SCardError err = reader.Connect(readerName,
                //    SCardShareMode.Shared,
                //    SCardProtocol.T0 | SCardProtocol.T1);

                IntPtr pioSendPci;
                switch (reader.ActiveProtocol)
                {
                    case SCardProtocol.T0:
                        pioSendPci = SCardPCI.T0;
                        break;
                    case SCardProtocol.T1:
                        pioSendPci = SCardPCI.T1;
                        break;
                    default:
                        throw new PCSCException(SCardError.ProtocolMismatch,
                            "Protocol not supported: "
                            + reader.ActiveProtocol.ToString());
                }
                
                byte[] pbRecvBuffer = new byte[256];
                err = reader.Transmit(pioSendPci, inBytes, ref pbRecvBuffer);
                return pbRecvBuffer;
            }
            catch (PCSCException)
            {
                return null;
            }
        }
Example #15
0
        ///// <summary>
        ///// Select an applet based on its AID (Application IDentifier). As for now the AID should have a length of 11 bytes.
        ///// </summary>
        ///// <param name="AID">Application Identifier. An 11 byte array that represents the applet to select</param>
        private void SelectApplet(byte[] AID)
        {
            TS.TraceI("Start SelectApplet with ID \"{0}\".", Helper.ByteArrayToString(AID));
            this.crdReader = GetReader();

            byte[] pbRecvBuffer = new byte[256];

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

            //// Send SELECT Applet command
            byte[] selectApplet = new byte[] { 0x00, 0xA4, 0x04, 0x00, 0x0B, AID[0], AID[1], AID[2], AID[3], AID[4], AID[5], AID[6], AID[7], AID[8], AID[9], AID[10], 0x00 };
            TS.TraceV("Select applet command: \"{0}\".", Helper.ByteArrayToString(selectApplet));

            /////*
            //// 00 = Class
            //// A4 = Instructie
            //// 04 = P1 = Select Dedicated File (DF)
            //// 00 = P2 = File Control Information (FCI)
            //// 0B = lc = Lengte van de AID
            //// AID
            //// 00 = End
            ////*/
            SCardError err = crdReader.Transmit(selectApplet, 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))
            {
                throw new CardReaderException("Invalid response");
            }

            TS.TraceI("End SelectApplet.");
        }
Example #16
0
        static void Main(string[] args)
        {
            // Establish Smartcard context
            SCardContext ctx = new SCardContext();
            ctx.Establish(SCardScope.System);

            string[] readernames = ctx.GetReaders();
            if (readernames == null || readernames.Length < 1)
                throw new Exception("You need at least one reader in order to run this example.");

            // we will use the first reader for the transmit test.
            string readername = readernames[0];

            SCardReader reader = new SCardReader(ctx);
            SCardError rc = reader.Connect(
                readername,
                SCardShareMode.Shared,
                SCardProtocol.Any);
            if (rc != SCardError.Success)
            {
                Console.WriteLine("Could not connect to card in reader " + readername + "\n"
                    + "Error: " + SCardHelper.StringifyError(rc));
                return;
            }

            // Build a GET CHALLENGE command
            CommandApdu apdu = new CommandApdu(
                IsoCase.Case2Short,
                reader.ActiveProtocol);

            apdu.CLA = 0x00; // Class
            apdu.INS = 0x84; // Instruction: GET CHALLENGE 
            apdu.P1 = 0x00;  // Parameter 1
            apdu.P2 = 0x00;  // Parameter 2
            apdu.Le = 0x08;  // Expected length of the returned data
            
            // convert the APDU object into an array of bytes
            byte[] cmd = apdu.ToArray();
            // prepare a buffer for response APDU -> LE + 2 bytes (SW1 SW2)
            byte[] outbuf = new byte[apdu.ExpectedResponseLength]; 

            rc = reader.Transmit(
                cmd,
                ref outbuf);

            if (rc == SCardError.Success)
            {
                Console.WriteLine("Ok.");

                if (outbuf != null)
                {
                    ResponseApdu response = new ResponseApdu(outbuf, apdu.Case, apdu.Protocol);
                    if (response.IsValid)
                    {
                        Console.WriteLine("SW1 SW2 = {0:X2} {1:X2}", response.SW1, response.SW2);
                        if (response.HasData)
                        {
                            Console.Write("Data: ");
                            for (int i = 0; i < (response.DataSize); i++)
                                Console.Write("{0:X2} ", response.FullApdu[i]);
                            Console.WriteLine("");
                        }
                    }
                }
            }
            else
            {
                // Error
                Console.WriteLine(SCardHelper.StringifyError(rc));
            }

            return;

        }
Example #17
0
        private bool AuthenticateBlock(byte blockNumber, SCardReader reader)
        {
            var apdu = new CommandApdu(IsoCase.Case3Short, reader.ActiveProtocol)
            {
                CLA = 0xFF,
                Instruction = InstructionCode.InternalAuthenticate,
                P1 = 0x00,
                P2 = 0x00,
                Data = new byte[]{
                    (byte)0x01, // version number
                    (byte)0x00,
                    blockNumber,
                    (byte)authentificationKeyType,
                    keyNumber}
            };

            var responseApdu = SendAPDU(apdu, reader);

            if (responseApdu != null && responseApdu.SW1 == 0x90)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
Example #18
0
        private byte[] ReadBinaryBlock(byte blockNumber, SCardReader reader)
        {
            if (!AuthenticateBlock(blockNumber, reader))
                return new byte[0]; // TODO throw exception

            byte blockSize = 0x10; // all classic variants have 16 byte blocks

            var apdu = new CommandApdu(IsoCase.Case2Short, reader.ActiveProtocol)
            {
                CLA = 0xFF,
                Instruction = InstructionCode.ReadBinary,
                P1 = 0x00,
                P2 = blockNumber, // block number
                Le = blockSize // bytes to read
            };

            var responseApdu = SendAPDU(apdu, reader);

            if (responseApdu != null && responseApdu.SW1 == 0x90)
            {
                return responseApdu.GetData().Take(16).ToArray(); // todo check size in debugging
            }
            else
            {
                return new byte[0];
            }
        }
Example #19
0
        /// <summary>
        /// Will try to connect to the _connectedReader, see if there is a card present, and if so try to read the data.
        /// </summary>
        /// <returns>Either the error message or data from the card.</returns>
        public string TryToReadCard()
        {
            SCardContext context = new SCardContext();
            context.Establish(SCardScope.System);
            SCardReader reader = new SCardReader(context);

            SCardError result = SCardError.InternalError;

            try
            {
                result = reader.Connect(_connectedReader, SCardShareMode.Shared, SCardProtocol.Any);
            }
            catch (Exception)
            {
                context.Dispose();
                reader.Dispose();
                return SCardHelper.StringifyError(result);
            }

            string message;

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

                if (result == SCardError.Success)
                    message = string.Format("Card detected:{0} Protocol: {1}{0} State: {2}{0} ATR: {3}",
                        Environment.NewLine, protocol, state, BitConverter.ToString(atr ?? new byte[0]));
                else
                    message = string.Format("Unable to read from card.{0}{1}", Environment.NewLine,
                        SCardHelper.StringifyError(result));
            }
            else
                message = string.Format("No card is detected (or reader reserved by another application){0} {1}",
                    Environment.NewLine, SCardHelper.StringifyError(result));

            context.Dispose();
            reader.Dispose();

            return message;
        }
Example #20
0
        public override byte[] GetCardMemory(SCardReader reader)
        {
            SCardError sc = reader.BeginTransaction();
            if (sc != SCardError.Success)
                return new byte[0]; // TODO proper exception

            if (!LoadAuthenticationKey(reader))
                return new byte[0]; // TODO proper exception

            byte[] memory = new byte[(int)memorySize];

            int sectors;

            switch (memorySize)
            {
                case MemorySize.Classic1K:
                    sectors = 15;
                    break;
                case MemorySize.Classic4K:
                    sectors = 31;
                    break;
                case MemorySize.ClassicMini:
                    sectors = 5;
                    break;
                default:
                    return new byte[0]; // TODO proper exception
            }

            bool readMemory = true;
            int currentSector = 1; // ignore first (=0) sector, since it's not usable

            while (readMemory && currentSector <= sectors)
            {
                bool readSector = true;
                int sectorOffset = currentSector * 4;
                int currentBlock = 0;
                while (readSector && currentBlock < 3)
                {
                    readSector = false;
                    byte[] block;
                    try
                    {
                        block = ReadBinaryBlock((byte)(sectorOffset + currentBlock), reader);
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                    int i = 0;
                    while (!readSector && i < block.Length)
                    { // check for data
                        if (block[i] != 0x00) readSector = true;
                        i++;
                    }
                    if (readSector) // update only if data
                        Buffer.BlockCopy(block, 0, memory, 48 * (currentSector - 1) + (currentBlock * 16), 16);
                    currentBlock++;
                }
                readMemory = readSector;
                currentSector++;
            }

            reader.EndTransaction(SCardReaderDisposition.Leave);

            return memory;
        }
 public abstract byte[] GetCardMemory(SCardReader reader);
        public Boolean Open(string readerName = null)
        {
            try
            {
                // Establish SCard context
                _hContext = new SCardContext();
                _hContext.Establish(SCardScope.System);

                // Create a _reader object using the existing context
                _reader = new SCardReader(_hContext);

                // Connect to the card
                if (readerName == null || readerName == String.Empty)
                {
                    // Retrieve the list of Smartcard _readers
                    string[] szReaders = _hContext.GetReaders();
                    if (szReaders.Length <= 0)
                        throw new PCSCException(SCardError.NoReadersAvailable,
                            "Could not find any Smartcard _reader.");

                    _err = _reader.Connect(szReaders[0],
                                SCardShareMode.Exclusive,
                                SCardProtocol.T0 | SCardProtocol.T1);
                    CheckErr(_err);
                }
                else
                {
                    _err = _reader.Connect(readerName,
                                SCardShareMode.Exclusive,
                                SCardProtocol.T0 | SCardProtocol.T1);
                    CheckErr(_err);
                }


                _pioSendPci = new IntPtr();
                switch (_reader.ActiveProtocol)
                {
                    case SCardProtocol.T0:
                        _pioSendPci = SCardPCI.T0;
                        break;
                    case SCardProtocol.T1:
                        _pioSendPci = SCardPCI.T1;
                        break;
                    default:
                        throw new PCSCException(SCardError.ProtocolMismatch,
                            "Protocol not supported: "
                            + _reader.ActiveProtocol.ToString());
                }

                string[] readerNames;
                SCardProtocol proto;
                SCardState state;
                byte[] atr;

                var sc = _reader.Status(
                    out readerNames,    // contains the reader name(s)
                    out state,          // contains the current state (flags)
                    out proto,          // contains the currently used communication protocol
                    out atr);           // contains the ATR

                if (atr == null || atr.Length < 2)
                {
                    return false;
                }
                
                if (atr[0] == 0x3B && atr[1] == 0x68)       //Smart card tested with old type (Figure A.)
                {
                    _apdu = new APDU_THAILAND_IDCARD_3B68();
                }
                else if (atr[0] == 0x3B && atr[1] == 0x78)   //Smart card tested with new type (figure B.) 
                {
                    _apdu = new APDU_THAILAND_IDCARD_3B68();
                }
                else if (atr[0] == 0x3B && atr[1] == 0x67)
                {
                    _apdu = new APDU_THAILAND_IDCARD_3B67();
                }
                else
                {
                    _error_code = ECODE_UNSUPPORT_CARD;
                    _error_message = "Card not support";
                    Console.WriteLine(_error_message);
                    return false;
                }


                return true;
            }
            catch (PCSCException ex)
            {
                _error_code = ECODE_SCardError;
                _error_message = "Err: " + ex.Message + " (" + ex.SCardError.ToString() + ")";
                Console.WriteLine(_error_message);
                return false;
            }
        }
Example #23
0
 public void SelectReader(string readerName)
 {
     this.ReaderName = readerName;
         this.crdReader = GetReader();
 }
Example #24
0
        /// <summary>
        ///     Retrieves the UID of a card that is currently connected to the given
        ///     reader.
        /// </summary>
        /// <param name="readername"></param>
        /// <exception cref="Exception">Could not begin transaction.</exception>
        private byte[] UidFromConnectedCard( string readername )
        {
            SCardReader rfidReader = new SCardReader( Context );
            SCardError resultCode = rfidReader.Connect( readername, SCardShareMode.Shared, SCardProtocol.Any );

            if( resultCode != SCardError.Success ) {
                throw new Exception( "Unable to connect to RFID card / chip. Error: " + SCardHelper.StringifyError( resultCode ) );
            }

            // prepare APDU
            byte[] payload = new byte[] {
                0xFF, // the instruction class
                0xCA, // the instruction code
                0x00, // parameter to the instruction
                0x00, // parameter to the instruction
                0x00 // size of I/O transfer
            };
            byte[] receiveBuffer = new byte[10];

            resultCode = rfidReader.BeginTransaction();
            if( resultCode != SCardError.Success ) {
                throw new Exception( "Could not begin transaction." );
            }

            SCardPCI ioreq = new SCardPCI();

            IntPtr protocolControlInformation = SCardPCI.GetPci( rfidReader.ActiveProtocol );
            resultCode = rfidReader.Transmit( protocolControlInformation, payload, ioreq, ref receiveBuffer );

            if( resultCode != SCardError.Success ) {
                Log.Error( SCardHelper.StringifyError( resultCode ) );
                receiveBuffer = null;
            }

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

            return receiveBuffer;
        }
 public SmartCardIO()
 {
   ctx = new SCardContext();
   ctx.Establish(this.scope);
   reader = new SCardReader(ctx);
 }
Example #26
0
        private bool LoadAuthenticationKey(SCardReader reader)
        {
            var apdu = new CommandApdu(IsoCase.Case3Short, reader.ActiveProtocol)
            {
                CLA = 0xFF,
                Instruction = InstructionCode.ExternalAuthenticate,
                P1 = 0x00, // key structure
                P2 = keyNumber, // key number
                Data = authentificationKey
            };

            var responseApdu = SendAPDU(apdu, reader);

            if (responseApdu != null && responseApdu.SW1 == 0x90)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
Example #27
0
        static void Main(string[] args)
        {
            SCardContext ctx = new SCardContext();

            ctx.Establish(SCardScope.System);

            // retrieve all reader names
            string[] readernames = ctx.GetReaders();

            if (readernames != null)
            {
                // get the card status of each reader that is currently connected
                foreach (string readername in readernames)
                {
                    SCardReader reader = new SCardReader(ctx);
                    Console.Write("Trying to connect to reader " + readername + "..");

                    SCardError serr = reader.Connect(readername,
                        SCardShareMode.Shared,
                        SCardProtocol.Any);

                    if (serr == SCardError.Success)
                    {
                        // SmartCard inserted, reader is now connected.
                        Console.WriteLine(" done.");

                        string[] tmpreadernames;
                        SCardProtocol proto;
                        SCardState state;
                        byte[] atr;

                        serr = reader.Status(
                            out tmpreadernames, // contains the reader name(s)
                            out state,          // contains the current state (flags)
                            out proto,          // contains the currently used communication protocol
                            out atr);           // contains the card ATR

                        if (serr == SCardError.Success)
                        {
                            Console.WriteLine("Connected with protocol " +
                                proto + " in state " + state);
                            if (atr != null && atr.Length > 0)
                            {
                                Console.Write("Card ATR: ");
                                foreach (byte b in atr)
                                    Console.Write("{0:X2}", b);
                                Console.WriteLine();
                            }

                            Console.WriteLine();
                        }
                        else
                        {
                            Console.WriteLine("Unable to retrieve card status.\nError message: "
                                + SCardHelper.StringifyError(serr)
                                + ".\n");

                        }

                        reader.Disconnect(SCardReaderDisposition.Reset);
                    }
                    else
                    {
                        /* SmardCard not inserted or reader is reserved exclusively by
                           another application. */
                        Console.WriteLine(" failed.\nError message: "
                            + SCardHelper.StringifyError(serr)
                            + ".\n");
                    }
                }
            }
            return;
        }
Example #28
0
        static void Main(string[] args)
        {
            SCardContext ctx = new SCardContext();
            ctx.Establish(SCardScope.System);

            string[] readernames = ctx.GetReaders();
            if (readernames == null || readernames.Length < 1)
                throw new Exception("You need at least one reader in order to run this example.");

            // Show available readers.
            Console.WriteLine("Available readers: ");
            for (int i = 0; i < readernames.Length; i++)
                Console.WriteLine("[" + i + "] " + readernames[i]);

            int num = 0;

            if (readernames.Length > 1)
            {
                // Ask the user which one to choose.
                Console.Write("Which reader is an RFID reader? ");
                string relin = Console.ReadLine();
                if (!(int.TryParse(relin, out num))
                    || num < 0
                    || num > readernames.Length)
                {
                    Console.WriteLine("An invalid number has been entered. Exiting.");
                    return;
                }
            }

            string readername = readernames[num];

            SCardReader RFIDReader = new SCardReader(ctx);
            SCardError rc = RFIDReader.Connect(
                readername,
                SCardShareMode.Shared,
                SCardProtocol.Any);

            if (rc != SCardError.Success)
            {
                Console.WriteLine("Unable to connect to RFID card / chip. Error: " +
                    SCardHelper.StringifyError(rc));
                return;
            }

            // prepare APDU
            byte[] ucByteSend = new byte[] 
            {
                0xFF,   // the instruction class
                0xCA,   // the instruction code 
                0x00,   // parameter to the instruction
                0x00,   // parameter to the instruction
                0x00    // size of I/O transfer
            };
            byte[] ucByteReceive = new byte[10];

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

            rc = RFIDReader.BeginTransaction();
            if (rc != SCardError.Success)
                throw new Exception("Could not begin transaction.");

            SCardPCI ioreq = new SCardPCI();    /* creates an empty object (null).
                                                 * IO returned protocol control information.
                                                 */
            IntPtr sendPci = SCardPCI.GetPci(RFIDReader.ActiveProtocol);
            rc = RFIDReader.Transmit(
                sendPci,    /* Protocol control information, T0, T1 and Raw
                             * are global defined protocol header structures.
                             */
                ucByteSend, /* the actual data to be written to the card */
                ioreq,      /* The returned protocol control information */
                ref ucByteReceive);

            if (rc == SCardError.Success)
            {
                Console.Write("Uid: ");
                for (int i = 0; i < (ucByteReceive.Length); i++)
                    Console.Write("{0:X2} ", ucByteReceive[i]);
                Console.WriteLine("");
            }
            else
            {
                Console.WriteLine("Error: " + SCardHelper.StringifyError(rc));
            }

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

            return;
        }
Example #29
0
        /// <summary>
        /// Tries to connect to the selected reader.
        /// </summary>
        /// <returns>Null if successful. The error message if not.</returns>
        public string StartMonitoringSelectedReader(string readerName)
        {
            if (string.IsNullOrEmpty(readerName)) return "Reader name is null or empty";
            if (!_readers.Contains(readerName)) return "The reader does not exist. [Logic Error]";
            _connectedReader = readerName;

            SCardContext context = new SCardContext();
            context.Establish(SCardScope.System);
            SCardReader reader = new SCardReader(context);

            SCardError result = SCardError.InternalError;

            try
            {
                result = reader.Connect(readerName, SCardShareMode.Shared, SCardProtocol.Any);
            }
            catch (Exception)
            {
                context.Dispose();
                reader.Dispose();
                return SCardHelper.StringifyError(result);
            }

            _monitor = new SCardMonitor(new SCardContext(), SCardScope.System, true);
            _monitor.Initialized += (_cardInitalised);
            _monitor.CardInserted += (_cardInserted);
            _monitor.CardRemoved += (_cardRemoved);
            _monitor.Start(readerName);

            return null;
        }
Example #30
0
        private SCardReader GetReader()
        {
            TS.TraceI("Start GetReader.");
            //// Establish SCard context
            SCardContext hContext = OpenSystemWideCardContext();

            //// Create a reader object using the existing context
            SCardReader reader = new SCardReader(hContext);

            //// Connect to the card
            SCardError err = reader.Connect(this.ReaderName, SCardShareMode.Shared, SCardProtocol.T0 | SCardProtocol.T1);
            if (err != SCardError.Success)
            {
                TS.TraceV("CardReaderException: \"{0}\".", SCardHelper.StringifyError(err));
                throw new CardReaderException(err, "Unfortunately, this smart card can not be read");
            }

            if (reader.ActiveProtocol != SCardProtocol.T0 && reader.ActiveProtocol != SCardProtocol.T1)
            {
                throw new CardReaderException(SCardError.ProtocolMismatch, "Protocol not supported: " + reader.ActiveProtocol.ToString());
            }
            TS.TraceV("AciveProtocol: \"{0}\".", reader.ActiveProtocol);

            TS.TraceI("End GetReader.");
            return reader;
        }
Example #31
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;
        }
Example #32
-1
 public PCSCReader()
 {
     context = new SCardContext();
     context.Establish(SCardScope.System);
     readerNames = context.GetReaders();
     reader = new SCardReader(context);
 }