SmartCard programming in C#
Communicate with SmartCards using C# and WinSCard
Because I’ve not found any complete wrapper lib for C# I created it. If there is something missing, feel free to contact me.
Some little helper functions to make the life easier
Required values:
IntPtr pcscContext; // Pointer to the resource manager context IntPtr pcscCard; // Pointer to the connection to the smart card uint lastResult; // Stores the last SCard function result SCardSelectedFileResponse selectedFileResponse; // Stores the last response to SelectFile command
SCardGetAttrib helper:
private bool GetAttrib(SCARD_ATTR attr, ref byte[] buffer, ref uint bufferlen) { if (WinSCard.SCARD_S_SUCCESS == (lastResult = WinSCard.SCardGetAttrib(pcscCard, attr, buffer, ref bufferlen))) return true; return false; } byte[] buffer = new byte[256]; uint bufferlen = 256; string vendorName = ""; if (GetAttrib(SCARD_ATTR.VENDOR_NAME, ref buffer, ref bufferlen)) vendorName = WinSCard.SCardByteArrayToString(buffer, (int)bufferlen);
SCardTransmit helper:
private bool Transmit(byte[] command, ref byte[] buffer, ref uint bufferlen) { WinSCard.SCARD_IO_REQUEST req = new WinSCard.SCARD_IO_REQUEST(); req.cbPciLength = 0x8; req.dwProtocol = 0x1; buffer = new byte[0x3E9]; bufferlen = 0x3E9; if (WinSCard.SCARD_S_SUCCESS == (lastResult = WinSCard.SCardTransmit(pcscCard, req, command, (uint) command.Length, 0, buffer, ref bufferlen))) return true; return false; }
Using SCardTransmit with the SelectFile Helper:
private bool SelectFile(ushort Index) { byte[] buffer = new byte[0]; uint bufferlen = 0; byte[] cmd = BitConverter.GetBytes(Index); cmd = new byte[] { 0x00, 0xA4, 0x00, 0x00, 0x02, cmd[1], cmd[0] }; if (!Transmit(cmd, ref buffer, ref bufferlen)) return false; if (WinSCard.SCARD_SW_DATA_STILL_AVAIL == (WinSCard.SCardGetStatusWord(buffer, (int)bufferlen) & 0xFF00)) { cmd = new byte[] { 0x00, 0xC0, 0x00, 0x00, (byte)(WinSCard.SCardGetStatusWord(buffer, (int)bufferlen) & 0xFF) }; if (Transmit(cmd, ref buffer, ref bufferlen)) selectedFileResponse = new SCardSelectedFileResponse(buffer); } return true; } SelectFile(0x3F00);