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]; } }
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()); } }
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(); } }
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(); }
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; }
// 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"); } }
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]; } }
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; }
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(); } } }
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(); }
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; } }
///// <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."); }
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; }
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; } }
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]; } }
/// <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; }
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; } }
public void SelectReader(string readerName) { this.ReaderName = readerName; this.crdReader = GetReader(); }
/// <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); }
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; } }
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; }
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; }
/// <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; }
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; }
/// <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; }
public PCSCReader() { context = new SCardContext(); context.Establish(SCardScope.System); readerNames = context.GetReaders(); reader = new SCardReader(context); }