/// <inheritdoc />
        public SCardError Transmit(IntPtr sendPci, byte[] sendBuffer, SCardPCI receivePci, ref byte[] receiveBuffer)
        {
            ThrowOnInvalidCardHandle();

            var ioRecvPciPtr = IntPtr.Zero;

            if (receivePci != null)
            {
                ioRecvPciPtr = receivePci.MemoryPtr;
            }

            var rc = Platform.Lib.Transmit(
                _cardHandle,
                sendPci,
                sendBuffer,
                ioRecvPciPtr,
                receiveBuffer,
                out var pcbRecvLength);

            if (rc != SCardError.Success)
            {
                return(rc);
            }

            if (receiveBuffer != null && pcbRecvLength < receiveBuffer.Length)
            {
                Array.Resize(ref receiveBuffer, pcbRecvLength);
            }

            return(rc);
        }
Exemple #2
0
        public SCardError Transmit(IntPtr pioSendPci,
                                   byte[] sendBuffer,
                                   int sendBufLength,
                                   SCardPCI ioRecvPci,
                                   byte[] recvBuffer,
                                   ref int recvBufLength)
        {
            if (cardHandle.Equals(IntPtr.Zero))
            {
                throw new InvalidOperationException(
                          "Reader is currently not connected or no card handle has been returned.");
            }

            IntPtr ioRecvPciPtr = IntPtr.Zero;

            if (ioRecvPci != null)
            {
                ioRecvPciPtr = ioRecvPci.iomem;
            }

            SCardError rc = SCardAPI.Lib.Transmit(cardHandle,
                                                  pioSendPci,
                                                  sendBuffer,
                                                  sendBufLength,
                                                  ioRecvPciPtr,
                                                  recvBuffer,
                                                  ref recvBufLength);

            return(rc);
        }
 /// <inheritdoc />
 public int Transmit(byte[] sendBuffer, byte[] receiveBuffer)
 {
     return(Transmit(
                sendPci: SCardPCI.GetPci(Protocol),
                sendBuffer: sendBuffer,
                receiveBuffer: receiveBuffer));
 }
        /// <inheritdoc />
        public int Transmit(IntPtr sendPci, byte[] sendBuffer, int sendBufferLength, SCardPCI receivePci,
                            byte[] receiveBuffer,
                            int receiveBufferLength)
        {
            var receivePciPointer = receivePci?.MemoryPtr ?? IntPtr.Zero;

            return(Transmit(sendPci, sendBuffer, sendBufferLength, receivePciPointer, receiveBuffer,
                            receiveBufferLength));
        }
        /// <inheritdoc />
        public int Transmit(SCardPCI sendPci, byte[] sendBuffer, int sendBufferLength, byte[] receiveBuffer,
                            int receiveBufferLength)
        {
            ThrowOnInvalidSendPci(sendPci);

            var sendPciMemoryPtr = sendPci.MemoryPtr;

            return(Transmit(sendPciMemoryPtr, sendBuffer, sendBufferLength, IntPtr.Zero, receiveBuffer,
                            receiveBufferLength));
        }
        /// <inheritdoc />
        public int Transmit(SCardPCI sendPci, byte[] sendBuffer, int sendBufferLength, SCardPCI receivePci,
                            byte[] receiveBuffer,
                            int receiveBufferLength)
        {
            ThrowOnInvalidSendPci(sendPci);

            var sendPciPointer    = sendPci.MemoryPtr;
            var receivePciPointer = receivePci?.MemoryPtr ?? IntPtr.Zero;

            return(Transmit(sendPciPointer, sendBuffer, sendBufferLength, receivePciPointer, receiveBuffer,
                            receiveBufferLength));
        }
        private static void ThrowOnInvalidSendPci(SCardPCI sendPci)
        {
            if (sendPci == null)
            {
                throw new ArgumentNullException(nameof(sendPci));
            }

            if (sendPci.MemoryPtr == IntPtr.Zero)
            {
                throw new ArgumentException("Valid sendPci required", nameof(sendPci));
            }
        }
        /// <inheritdoc />
        public SCardError Transmit(byte[] sendBuffer, int sendBufferLength, byte[] receiveBuffer,
                                   ref int receiveBufferLength)
        {
            var iorecvpci = new SCardPCI(); // will be discarded

            return(Transmit(
                       SCardPCI.GetPci(ActiveProtocol),
                       sendBuffer,
                       sendBufferLength,
                       iorecvpci,
                       receiveBuffer,
                       ref receiveBufferLength));
        }
        /// <inheritdoc />
        public int Transmit(SCardPCI sendPci, byte[] sendBuffer, byte[] receiveBuffer)
        {
            var sendBufferLength    = sendBuffer?.Length ?? 0;
            var receiveBufferLength = receiveBuffer?.Length ?? 0;

            return(Transmit(
                       sendPci: sendPci,
                       sendBuffer: sendBuffer,
                       sendBufferLength: sendBufferLength,
                       receivePci: default(SCardPCI),
                       receiveBuffer: receiveBuffer,
                       receiveBufferLength: receiveBufferLength));
        }
Exemple #10
0
        public SCardError Transmit(byte[] sendBuffer,
                                   int sendBufferLength,
                                   byte[] recvBuffer,
                                   ref int recvBufferLength)
        {
            SCardPCI iorecvpci = new SCardPCI(); // will be discarded

            return(Transmit(
                       SCardPCI.GetPci(activeprot),
                       sendBuffer,
                       sendBufferLength,
                       iorecvpci,
                       recvBuffer,
                       ref recvBufferLength));
        }
        /// <inheritdoc />
        public SCardError Transmit(SCardPCI sendPci, byte[] sendBuffer, SCardPCI receivePci, ref byte[] receiveBuffer)
        {
            if (sendPci == null)
            {
                throw new ArgumentNullException(nameof(sendPci));
            }

            if (sendPci.MemoryPtr == IntPtr.Zero)
            {
                throw new ArgumentException("Valid sendPci required", nameof(sendPci));
            }

            return(Transmit(
                       sendPci.MemoryPtr,
                       sendBuffer,
                       receivePci,
                       ref receiveBuffer));
        }
Exemple #12
0
        public SCardError Transmit(SCardPCI ioSendPci,
                                   byte[] sendBuffer,
                                   SCardPCI ioRecvPci,
                                   ref byte[] recvBuffer)
        {
            if (ioSendPci == null)
            {
                throw new ArgumentNullException("ioSendPci");
            }
            if (ioSendPci.iomem == IntPtr.Zero)
            {
                throw new ArgumentException("ioSendPci");
            }

            return(Transmit(ioSendPci.iomem,
                            sendBuffer,
                            ioRecvPci,
                            ref recvBuffer));
        }
        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);
        }
Exemple #14
0
        public SCardError Transmit(IntPtr pioSendPci,
                                   byte[] sendBuffer,
                                   SCardPCI ioRecvPci,
                                   ref byte[] recvBuffer)
        {
            if (cardHandle.Equals(IntPtr.Zero))
            {
                throw new InvalidOperationException(
                          "Reader is currently not connected or no card handle has been returned.");
            }

            int pcbRecvLength;

            IntPtr ioRecvPciPtr = IntPtr.Zero;

            if (ioRecvPci != null)
            {
                ioRecvPciPtr = ioRecvPci.iomem;
            }

            SCardError rc = SCardAPI.Lib.Transmit(cardHandle,
                                                  pioSendPci,
                                                  sendBuffer,
                                                  ioRecvPciPtr,
                                                  recvBuffer,
                                                  out pcbRecvLength);

            if (rc == SCardError.Success)
            {
                if (recvBuffer != null &&
                    pcbRecvLength < recvBuffer.Length)
                {
                    Array.Resize <byte>(ref recvBuffer, (int)pcbRecvLength);
                }
            }

            return(rc);
        }
        /// <summary>Sends an APDU to the smart card that was previously connected by <see cref="M:PCSC.ISCardReader.Connect(System.String,PCSC.SCardShareMode,PCSC.SCardProtocol)" />.</summary>
        /// <param name="sendPci">Structure of Protocol Control Information.</param>
        /// <param name="sendBuffer">APDU to send to the card.</param>
        /// <param name="receivePci">Structure of protocol information.</param>
        /// <param name="receiveBuffer">Response from the card.</param>
        /// <returns>
        ///     <list type="table">
        ///         <listheader>
        ///             <term>Return value</term>
        ///             <description>Description</description>
        ///         </listheader>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.Success" />
        ///             </term>
        ///             <description> 	Successful (SCARD_S_SUCCESS)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.InsufficientBuffer" />
        ///             </term>
        ///             <description>
        ///                 <paramref name="sendBuffer" /> or <paramref name="receiveBuffer" /> are too big (SCARD_E_INSUFFICIENT_BUFFER)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.InvalidHandle" />
        ///             </term>
        ///             <description>Invalid card handle (SCARD_E_INVALID_HANDLE)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.InvalidParameter" />
        ///             </term>
        ///             <description>
        ///                 <paramref name="sendBuffer" /> or <paramref name="receiveBuffer" /> or <paramref name="sendPci" /> is <see langword="null" /> (SCARD_E_INVALID_PARAMETER)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.InvalidValue" />
        ///             </term>
        ///             <description>Invalid Protocol, reader name, etc (SCARD_E_INVALID_VALUE)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.NoService" />
        ///             </term>
        ///             <description>The server is not runing (SCARD_E_NO_SERVICE)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.NotTransacted" />
        ///             </term>
        ///             <description>APDU exchange not successful (SCARD_E_NOT_TRANSACTED)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.ProtocolMismatch" />
        ///             </term>
        ///             <description>Connect protocol is different than desired (SCARD_E_PROTO_MISMATCH)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.ReaderUnavailable" />
        ///             </term>
        ///             <description>The reader has been removed (SCARD_E_READER_UNAVAILABLE)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.CommunicationError" />
        ///             </term>
        ///             <description>An internal communications error has been detected (SCARD_F_COMM_ERROR)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.ResetCard" />
        ///             </term>
        ///             <description>The card has been reset by another application (SCARD_W_RESET_CARD)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.RemovedCard" />
        ///             </term>
        ///             <description>The card has been removed from the reader (SCARD_W_REMOVED_CARD)</description>
        ///         </item>
        ///     </list>
        /// </returns>
        /// <remarks>
        ///     <para>The card responds from the APDU and stores this response in <paramref name="receiveBuffer" />. <paramref name="sendPci" /> and <paramref name="receivePci" /> are structures containing the following (implemented in <see cref="T:PCSC.SCardPCI" />):
        ///         <example><code lang="C">
        /// typedef struct {
        /// 	DWORD dwProtocol;    // SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1
        /// 	DWORD cbPciLength;   // Length of this structure - not used
        /// } SCARD_IO_REQUEST;
        ///   </code></example>
        ///     </para>
        ///     <para>It is recommended to use pre-defined / built-in PCI structures by calling one of the following methods:
        ///         <list type="bullet">
        ///             <item><term><see cref="M:PCSC.ISCardReader.Transmit(System.IntPtr,System.Byte[],PCSC.SCardPCI,System.Byte[]@)" /></term></item>
        ///             <item><term><see cref="M:PCSC.ISCardReader.Transmit(System.IntPtr,System.Byte[],System.Byte[]@)" /></term></item></list></para>
        ///     <para>This method calls the API function SCardTransmit(). The pointers to the pre-defined / built-in PCI structures are determinated with dlsym() on UNIX/Linux hosts and GetProcAddress() on Windows hosts.</para>
        /// </remarks>
        public SCardError Transmit(SCardPCI sendPci, byte[] sendBuffer, SCardPCI receivePci, ref byte[] receiveBuffer)
        {
            if (sendPci == null) {
                throw new ArgumentNullException("sendPci");
            }
            if (sendPci.MemoryPtr == IntPtr.Zero) {
                throw new ArgumentException("sendPci");
            }

            return Transmit(
                sendPci.MemoryPtr,
                sendBuffer,
                receivePci,
                ref receiveBuffer);
        }
Exemple #16
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;
        }
Exemple #17
0
        private ResponseApdu _SimpleTransmit(byte[] cmdApdu, int cmdApduLength, IsoCase isoCase, SCardProtocol proto, SCardPCI recvPci, ref byte[] recvBuf, ref int recvBufLength)
        {
            SCardError sc = SCardError.UnknownError;
            bool cmdSent = false;

            do
            {
                // send Command APDU to the card
                sc = reader.Transmit(
                    SCardPCI.GetPci(reader.ActiveProtocol),
                    cmdApdu,
                    cmdApduLength,
                    recvPci,
                    recvBuf,
                    ref recvBufLength);

                // Do we need to resend the command APDU?
                if (sc == SCardError.InsufficientBuffer &&
                    recvBuf.Length < recvBufLength)
                {
                    // The response buffer was too small.
                    recvBuf = new byte[recvBufLength];

                    // Shall we wait until we re-send we APDU?
                    if (_retransmitWaitTime > 0)
                        Thread.Sleep(_retransmitWaitTime);
                }
                else
                    cmdSent = true;
            } while (cmdSent == false);

            if (sc == SCardError.Success)
            {
                ResponseApdu respApdu = new ResponseApdu(recvBuf, recvBufLength, isoCase, proto);
                return respApdu;
            }

            // An error occurred, throw exception..
            ThrowExceptionOnSCardError(sc);
            return null;
        }
Exemple #18
0
        public virtual Response Transmit(CommandApdu cmdApdu)
        {
            if (cmdApdu == null)
                throw new ArgumentNullException("cmdApdu");

            // prepare send buffer (Check Command APDU and convert it to an byte array)
            byte[] sendbuf;
            try
            {
                sendbuf = cmdApdu.ToArray();
            }
            catch (InvalidOperationException ex)
            {
                throw new InvalidApduException("Invalid APDU.", cmdApdu, ex);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            // create Response object
            Response resp = new Response();

            // prepare receive buffer (Response APDU)
            byte[] recvbuf = null;
            int recvbuflen = cmdApdu.ExpectedResponseLength; // expected size that shall be returned
            recvbuf = new byte[recvbuflen];

            ResponseApdu respApdu = null;
            SCardPCI recvPci = new SCardPCI();

            respApdu = _SimpleTransmit(
                sendbuf,
                sendbuf.Length,
                cmdApdu.Case,       // ISO case used by the Command APDU
                cmdApdu.Protocol,   // Protocol used by the Command APDU
                recvPci,
                ref recvbuf,
                ref recvbuflen);

            /* Check status word SW1SW2:
             *
             * 1. 0x6cxx -> Set response buffer size Le <- SW2
             * 2. AND/OR 0x61xx -> More data can be read with GET RESPONSE
             */

            // Case 1: SW1=0x6c, Previous Le/P3 not accepted -> Set le = SW2
            if (respApdu.SW1 == (byte)SW1Code.ErrorP3Incorrect)
            {
                CommandApdu resendCmdApdu = (CommandApdu)cmdApdu.Clone();
                if (respApdu.SW2 == 0)
                {
                    resendCmdApdu.Le = 0; // 256
                    recvbuflen = 256 + 2;           // 2 bytes for status word
                }
                else
                {
                    resendCmdApdu.Le = respApdu.SW2;
                    recvbuflen = respApdu.SW2 + 2;  // 2 bytes for status word
                }

                recvbuf = new byte[recvbuflen];
                recvPci = new SCardPCI();

                try
                {
                    sendbuf = resendCmdApdu.ToArray();

                    // Shall we wait until we re-send we APDU/TPDU?
                    if (_retransmitWaitTime > 0)
                        Thread.Sleep(_retransmitWaitTime);

                    // send Command APDU again with new Le value
                    respApdu = _SimpleTransmit(
                        sendbuf,
                        sendbuf.Length,
                        resendCmdApdu.Case,
                        resendCmdApdu.Protocol,
                        recvPci,
                        ref recvbuf,
                        ref recvbuflen);
                }
                catch (InvalidOperationException ex)
                {
                    throw new InvalidApduException("Got SW1=0x6c. Retransmission failed because of an invalid APDU.", resendCmdApdu, ex);
                }
            }

            // Case 2: SW1=0x61, More data available -> GET RESPONSE
            if (respApdu.SW1 == (byte)SW1Code.NormalDataResponse)
            {
                /* The transmission system shall issue a GET RESPONSE command APDU (or TPDU)
                 * to the card by assigning the minimum of SW2 and Le to parameter Le (or P3)).
                 * Le = min(Le,SW2)
                 */
                int _le = (cmdApdu.Le < respApdu.SW2) ? cmdApdu.Le : respApdu.SW2;

                do
                {
                    // add the last ResponseAPDU to the Response object
                    resp.AddResponseApdu(respApdu);
                    resp.AddRecvPci(recvPci);

                    CommandApdu getResponseApdu = _constructGetResponseApdu(ref _le);

                    if (_le == 0)
                        recvbuflen = 256 + 2; // 2 bytes for status word
                    else
                        recvbuflen = _le + 2; // 2 bytes for status word

                    recvbuf = new byte[recvbuflen];

                    try
                    {
                        sendbuf = getResponseApdu.ToArray();

                        // Shall we wait until we re-send we APDU/TPDU?
                        if (_retransmitWaitTime > 0)
                            Thread.Sleep(_retransmitWaitTime);

                        // send Command APDU again with new Le value
                        respApdu = _SimpleTransmit(
                            sendbuf,
                            sendbuf.Length,
                            getResponseApdu.Case,
                            getResponseApdu.Protocol,
                            recvPci,
                            ref recvbuf,
                            ref recvbuflen);
                    }
                    catch (InvalidOperationException ex)
                    {
                        throw new InvalidApduException("Got SW1=0x61. Retransmission failed because of an invalid GET RESPONSE APDU.", getResponseApdu, ex);
                    }

                    // In case there is more data available.
                    _le = respApdu.SW2;
                } while (
                    // More data available.
                    respApdu.SW1 == (byte)SW1Code.NormalDataResponse

                    ||

                    // Warning condition: data may be corrupted. Iso7816-4 7.1.5
                    (respApdu.SW1 == (byte)SW1Code.WarningNVDataNotChanged &&
                     respApdu.SW2 == (byte)0x81)
                    );
            }

            resp.AddResponseApdu(respApdu);
            resp.AddRecvPci(recvPci);

            return resp;
        }
Exemple #19
0
 /// <summary>Sends an APDU to the smart card that was previously connected by <see cref="M:PCSC.ISCardReader.Connect(System.String,PCSC.SCardShareMode,PCSC.SCardProtocol)" />. </summary>
 /// <param name="sendBuffer">APDU to send to the card. </param>
 /// <param name="sendBufferLength">The buffer size of <paramref name="sendBuffer" /> in bytes.</param>
 /// <param name="receiveBuffer">Response from the card.</param>
 /// <param name="receiveBufferLength">The buffer size of <paramref name="receiveBuffer" /> in bytes.</param>
 /// <returns>
 ///     <list type="table">
 ///         <listheader>
 ///             <term>Return value</term>
 ///             <description>Description</description>
 ///         </listheader>
 ///         <item>
 ///             <term>
 ///                 <see cref="F:PCSC.SCardError.Success" />
 ///             </term>
 ///             <description> 	Successful (SCARD_S_SUCCESS)</description>
 ///         </item>
 ///         <item>
 ///             <term>
 ///                 <see cref="F:PCSC.SCardError.InsufficientBuffer" />
 ///             </term>
 ///             <description>
 ///                 <paramref name="sendBuffer" /> or <paramref name="receiveBuffer" /> are too big (SCARD_E_INSUFFICIENT_BUFFER)</description>
 ///         </item>
 ///         <item>
 ///             <term>
 ///                 <see cref="F:PCSC.SCardError.InvalidHandle" />
 ///             </term>
 ///             <description>Invalid card handle (SCARD_E_INVALID_HANDLE)</description>
 ///         </item>
 ///         <item>
 ///             <term>
 ///                 <see cref="F:PCSC.SCardError.InvalidParameter" />
 ///             </term>
 ///             <description>
 ///                 <paramref name="sendBuffer" /> or <paramref name="receiveBuffer" /> is <see langword="null" /> (SCARD_E_INVALID_PARAMETER)</description>
 ///         </item>
 ///         <item>
 ///             <term>
 ///                 <see cref="F:PCSC.SCardError.InvalidValue" />
 ///             </term>
 ///             <description>Invalid Protocol, reader name, etc (SCARD_E_INVALID_VALUE)</description>
 ///         </item>
 ///         <item>
 ///             <term>
 ///                 <see cref="F:PCSC.SCardError.NoService" />
 ///             </term>
 ///             <description>The server is not runing (SCARD_E_NO_SERVICE)</description>
 ///         </item>
 ///         <item>
 ///             <term>
 ///                 <see cref="F:PCSC.SCardError.NotTransacted" />
 ///             </term>
 ///             <description>APDU exchange not successful (SCARD_E_NOT_TRANSACTED)</description>
 ///         </item>
 ///         <item>
 ///             <term>
 ///                 <see cref="F:PCSC.SCardError.ProtocolMismatch" />
 ///             </term>
 ///             <description>Connect protocol is different than desired (SCARD_E_PROTO_MISMATCH)</description>
 ///         </item>
 ///         <item>
 ///             <term>
 ///                 <see cref="F:PCSC.SCardError.ReaderUnavailable" />
 ///             </term>
 ///             <description>The reader has been removed (SCARD_E_READER_UNAVAILABLE)</description>
 ///         </item>
 ///         <item>
 ///             <term>
 ///                 <see cref="F:PCSC.SCardError.CommunicationError" />
 ///             </term>
 ///             <description>An internal communications error has been detected (SCARD_F_COMM_ERROR)</description>
 ///         </item>
 ///         <item>
 ///             <term>
 ///                 <see cref="F:PCSC.SCardError.ResetCard" />
 ///             </term>
 ///             <description>The card has been reset by another application (SCARD_W_RESET_CARD)</description>
 ///         </item>
 ///         <item>
 ///             <term>
 ///                 <see cref="F:PCSC.SCardError.RemovedCard" />
 ///             </term>
 ///             <description>The card has been removed from the reader (SCARD_W_REMOVED_CARD)</description>
 ///         </item>
 ///     </list>
 /// </returns>
 /// <remarks>
 ///     <para>The card responds from the APDU and stores this response in <paramref name="receiveBuffer" />.  The buffer <paramref name="receiveBuffer" /> must be initialized. The size of the returned data will be stored in <paramref name="receiveBufferLength" />. This method will return with error code <see cref="F:PCSC.SCardError.InsufficientBuffer" /> if the buffer size of <paramref name="receiveBuffer" /> is too small for the result. If one of the parameters <paramref name="sendBufferLength" /> or <paramref name="receiveBufferLength" /> is invalid, the method will throw an <see cref="T:System.ArgumentOutOfRangeException" />.</para>
 ///     <para>This method calls the API function SCardTransmit().</para>
 ///     <block subset="none" type="note">
 ///         <para>This method will only work if the reader has been connected with one of the following protocols:
 ///             <list type="table">
 ///                 <listheader><term>Protocol</term><description>Description</description></listheader>
 ///                 <item><term><see cref="F:PCSC.SCardProtocol.T0" /></term><description>T=0 active protocol.</description></item>
 ///                 <item><term><see cref="F:PCSC.SCardProtocol.T1" /></term><description>T=1 active protocol.</description></item>
 ///                 <item><term><see cref="F:PCSC.SCardProtocol.Raw" /></term><description>Raw active protocol.</description></item>
 ///             </list></para>
 ///     </block>
 /// </remarks>
 public SCardError Transmit(byte[] sendBuffer, int sendBufferLength, byte[] receiveBuffer,
     ref int receiveBufferLength) {
     var iorecvpci = new SCardPCI(); // will be discarded
     return Transmit(
         SCardPCI.GetPci(ActiveProtocol),
         sendBuffer,
         sendBufferLength,
         iorecvpci,
         receiveBuffer,
         ref receiveBufferLength);
 }
Exemple #20
0
        public SCardError Transmit(IntPtr pioSendPci,
                                  byte[] sendBuffer,
                                  SCardPCI ioRecvPci,
                                  ref byte[] recvBuffer)
        {
            if (cardHandle.Equals(IntPtr.Zero))
                throw new InvalidOperationException(
                    "Reader is currently not connected or no card handle has been returned.");

            int pcbRecvLength;

            IntPtr ioRecvPciPtr = IntPtr.Zero;
            if (ioRecvPci != null)
                ioRecvPciPtr = ioRecvPci.iomem;

            SCardError rc = SCardAPI.Lib.Transmit(cardHandle,
                                                pioSendPci,
                                                sendBuffer,
                                                ioRecvPciPtr,
                                                recvBuffer,
                                                out pcbRecvLength);

            if (rc == SCardError.Success)
            {
                if (recvBuffer != null &&
                    pcbRecvLength < recvBuffer.Length)
                        Array.Resize<byte>(ref recvBuffer, (int)pcbRecvLength);
            }

            return rc;
        }
Exemple #21
0
        public SCardError Transmit(SCardPCI ioSendPci,
                                  byte[] sendBuffer,
                                  SCardPCI ioRecvPci,
                                  ref byte[] recvBuffer)
        {
            if (ioSendPci == null)
                throw new ArgumentNullException("ioSendPci");
            if (ioSendPci.iomem == IntPtr.Zero)
                throw new ArgumentException("ioSendPci");

            return Transmit(ioSendPci.iomem,
                sendBuffer,
                ioRecvPci,
                ref recvBuffer);
        }
        /// <summary>Sends an APDU to the smart card that was previously connected by <see cref="M:PCSC.ISCardReader.Connect(System.String,PCSC.SCardShareMode,PCSC.SCardProtocol)" />. </summary>
        /// <param name="sendPci">A pointer to a pre-defined Structure of Protocol Control Information. You can use one of the following:
        ///     <list type="table"><listheader><term>Protocol Control Information</term><description>Description</description></listheader><item><term><see cref="P:PCSC.SCardPCI.T0" /></term><description>Pre-defined T=0 PCI structure. (SCARD_PCI_T0)</description></item><item><term><see cref="P:PCSC.SCardPCI.T1" /></term><description>Pre-defined T=1 PCI structure. (SCARD_PCI_T1)</description></item><item><term><see cref="P:PCSC.SCardPCI.Raw" /></term><description>Pre-defined RAW PCI structure. (SCARD_PCI_RAW)</description></item></list></param>
        /// <param name="sendBuffer">APDU to send to the card. </param>
        /// <param name="sendBufferLength">The buffer size of <paramref name="sendBuffer" /> in bytes.</param>
        /// <param name="receivePci">Structure of protocol information. </param>
        /// <param name="receiveBuffer">Response from the card.</param>
        /// <param name="receiveBufferLength">The buffer size of <paramref name="receiveBuffer" /> in bytes.</param>
        /// <returns>
        ///     <list type="table">
        ///         <listheader>
        ///             <term>Return value</term>
        ///             <description>Description</description>
        ///         </listheader>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.Success" />
        ///             </term>
        ///             <description> 	Successful (SCARD_S_SUCCESS)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.InsufficientBuffer" />
        ///             </term>
        ///             <description>
        ///                 <paramref name="sendBuffer" /> or <paramref name="receiveBuffer" /> are too big (SCARD_E_INSUFFICIENT_BUFFER)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.InvalidHandle" />
        ///             </term>
        ///             <description>Invalid card handle (SCARD_E_INVALID_HANDLE)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.InvalidParameter" />
        ///             </term>
        ///             <description>
        ///                 <paramref name="sendBuffer" /> or <paramref name="receiveBuffer" /> or <paramref name="sendPci" /> is <see langword="null" /> (SCARD_E_INVALID_PARAMETER)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.InvalidValue" />
        ///             </term>
        ///             <description>Invalid Protocol, reader name, etc (SCARD_E_INVALID_VALUE)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.NoService" />
        ///             </term>
        ///             <description>The server is not runing (SCARD_E_NO_SERVICE)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.NotTransacted" />
        ///             </term>
        ///             <description>APDU exchange not successful (SCARD_E_NOT_TRANSACTED)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.ProtocolMismatch" />
        ///             </term>
        ///             <description>Connect protocol is different than desired (SCARD_E_PROTO_MISMATCH)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.ReaderUnavailable" />
        ///             </term>
        ///             <description>The reader has been removed (SCARD_E_READER_UNAVAILABLE)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.CommunicationError" />
        ///             </term>
        ///             <description>An internal communications error has been detected (SCARD_F_COMM_ERROR)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.ResetCard" />
        ///             </term>
        ///             <description>The card has been reset by another application (SCARD_W_RESET_CARD)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.RemovedCard" />
        ///             </term>
        ///             <description>The card has been removed from the reader (SCARD_W_REMOVED_CARD)</description>
        ///         </item>
        ///     </list>
        /// </returns>
        /// <remarks>
        ///     <para>The card responds from the APDU and stores this response in <paramref name="receiveBuffer" />. The size of the returned data will be stored in <paramref name="receiveBufferLength" />. This method will return with error code <see cref="F:PCSC.SCardError.InsufficientBuffer" /> if the buffer size of <paramref name="receiveBuffer" /> is too small for the result. If one of the parameters <paramref name="sendBufferLength" /> or <paramref name="receiveBufferLength" /> is invalid, the method will throw an <see cref="T:System.ArgumentOutOfRangeException" />.</para>
        ///     <para>This method calls the API function SCardTransmit(). The pointers to the pre-defined / built-in PCI structures are determinated with dlsym() on UNIX/Linux hosts and GetProcAddress() on Windows hosts.</para>
        /// </remarks>
        public SCardError Transmit(IntPtr sendPci, byte[] sendBuffer, int sendBufferLength, SCardPCI receivePci,
            byte[] receiveBuffer, ref int receiveBufferLength)
        {
            ThrowOnInvalidCardHandle();

            var ioRecvPciPtr = IntPtr.Zero;
            if (receivePci != null) {
                ioRecvPciPtr = receivePci.MemoryPtr;
            }

            return Platform.Lib.Transmit(
                _cardHandle,
                sendPci,
                sendBuffer,
                sendBufferLength,
                ioRecvPciPtr,
                receiveBuffer,
                ref receiveBufferLength);
        }
        /// <inheritdoc />
        public SCardError Transmit(IntPtr sendPci, byte[] sendBuffer, int sendBufferLength, SCardPCI receivePci,
                                   byte[] receiveBuffer, ref int receiveBufferLength)
        {
            ThrowOnInvalidCardHandle();

            var ioRecvPciPtr = IntPtr.Zero;

            if (receivePci != null)
            {
                ioRecvPciPtr = receivePci.MemoryPtr;
            }

            return(Platform.Lib.Transmit(
                       _cardHandle,
                       sendPci,
                       sendBuffer,
                       sendBufferLength,
                       ioRecvPciPtr,
                       receiveBuffer,
                       ref receiveBufferLength));
        }
        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>Sends an APDU to the smart card that was previously connected by <see cref="M:PCSC.ISCardReader.Connect(System.String,PCSC.SCardShareMode,PCSC.SCardProtocol)" />. </summary>
        /// <param name="sendPci">A pointer to a pre-defined Structure of Protocol Control Information. You can use one of the following:
        ///     <list type="table"><listheader><term>Protocol Control Information</term><description>Description</description></listheader><item><term><see cref="P:PCSC.SCardPCI.T0" /></term><description>Pre-defined T=0 PCI structure. (SCARD_PCI_T0)</description></item><item><term><see cref="P:PCSC.SCardPCI.T1" /></term><description>Pre-defined T=1 PCI structure. (SCARD_PCI_T1)</description></item><item><term><see cref="P:PCSC.SCardPCI.Raw" /></term><description>Pre-defined RAW PCI structure. (SCARD_PCI_RAW)</description></item></list></param>
        /// <param name="sendBuffer">APDU to send to the card. </param>
        /// <param name="receivePci">Structure of protocol information. </param>
        /// <param name="receiveBuffer">Response from the card. </param>
        /// <returns>
        ///     <list type="table">
        ///         <listheader>
        ///             <term>Return value</term>
        ///             <description>Description</description>
        ///         </listheader>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.Success" />
        ///             </term>
        ///             <description> 	Successful (SCARD_S_SUCCESS)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.InsufficientBuffer" />
        ///             </term>
        ///             <description>
        ///                 <paramref name="sendBuffer" /> or <paramref name="receiveBuffer" /> are too big (SCARD_E_INSUFFICIENT_BUFFER)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.InvalidHandle" />
        ///             </term>
        ///             <description>Invalid card handle (SCARD_E_INVALID_HANDLE)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.InvalidParameter" />
        ///             </term>
        ///             <description>
        ///                 <paramref name="sendBuffer" /> or <paramref name="receiveBuffer" /> or <paramref name="sendPci" /> is <see langword="null" /> (SCARD_E_INVALID_PARAMETER)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.InvalidValue" />
        ///             </term>
        ///             <description>Invalid Protocol, reader name, etc (SCARD_E_INVALID_VALUE)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.NoService" />
        ///             </term>
        ///             <description>The server is not runing (SCARD_E_NO_SERVICE)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.NotTransacted" />
        ///             </term>
        ///             <description>APDU exchange not successful (SCARD_E_NOT_TRANSACTED)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.ProtocolMismatch" />
        ///             </term>
        ///             <description>Connect protocol is different than desired (SCARD_E_PROTO_MISMATCH)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.ReaderUnavailable" />
        ///             </term>
        ///             <description>The reader has been removed (SCARD_E_READER_UNAVAILABLE)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.CommunicationError" />
        ///             </term>
        ///             <description>An internal communications error has been detected (SCARD_F_COMM_ERROR)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.ResetCard" />
        ///             </term>
        ///             <description>The card has been reset by another application (SCARD_W_RESET_CARD)</description>
        ///         </item>
        ///         <item>
        ///             <term>
        ///                 <see cref="F:PCSC.SCardError.RemovedCard" />
        ///             </term>
        ///             <description>The card has been removed from the reader (SCARD_W_REMOVED_CARD)</description>
        ///         </item>
        ///     </list>
        /// </returns>
        /// <remarks>
        ///     <para>The card responds from the APDU and stores this response in <paramref name="receiveBuffer" />. <paramref name="receivePci" /> is a structure containing the following (implemented in <see cref="T:PCSC.SCardPCI" />):
        ///         <example><code lang="C">
        /// typedef struct {
        /// 	DWORD dwProtocol;    // SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1
        /// 	DWORD cbPciLength;   // Length of this structure - not used
        /// } SCARD_IO_REQUEST;
        ///   </code></example>
        ///     </para>
        ///     <para>This method calls the API function SCardTransmit(). The pointers to the pre-defined / built-in PCI structures are determinated with dlsym() on UNIX/Linux hosts and GetProcAddress() on Windows hosts.</para>
        ///     <example>
        ///         <code lang="C#">
        /// // Create a new PC/SC context.
        /// var ctx = new SCardContext();
        /// ctx.Establish(SCardScope.System);
        /// 
        /// // Connect to the reader
        /// var rfidReader = new SCardReader(ctx);
        /// SCardError rc = rfidReader.Connect(
        /// 	"OMNIKEY CardMan 5x21 00 01", 
        /// 	SCardShareMode.Shared, 
        /// 	SCardProtocol.T1);
        /// 
        /// 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
        /// 	};
        /// 
        /// rc = rfidReader.BeginTransaction();
        /// if (rc != SCardError.Success) {
        /// 	throw new Exception("Could not begin transaction.");
        /// }
        /// 
        /// Console.Out.WriteLine("Retrieving the UID .... ");
        /// 
        /// SCardPCI ioreq = new SCardPCI();   // IO returned protocol control information.
        /// byte[] ucByteReceive = new byte[10];
        /// rc = rfidReader.Transmit(
        /// 	SCardPCI.T1,// 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.WriteLine("Uid: {0}", BitConverter.ToString(ucByteReceive));
        /// } else {
        /// 	Console.WriteLine("Error: " + SCardHelper.StringifyError(rc));
        /// }
        ///             
        /// rfidReader.EndTransaction(SCardReaderDisposition.Leave);
        /// rfidReader.Disconnect(SCardReaderDisposition.Reset);
        /// ctx.Release()
        ///   </code>
        ///     </example>
        /// </remarks>
        public SCardError Transmit(IntPtr sendPci, byte[] sendBuffer, SCardPCI receivePci, ref byte[] receiveBuffer)
        {
            ThrowOnInvalidCardHandle();

            int pcbRecvLength;
            var ioRecvPciPtr = IntPtr.Zero;

            if (receivePci != null) {
                ioRecvPciPtr = receivePci.MemoryPtr;
            }

            var rc = Platform.Lib.Transmit(
                _cardHandle,
                sendPci,
                sendBuffer,
                ioRecvPciPtr,
                receiveBuffer,
                out pcbRecvLength);

            if (rc != SCardError.Success) {
                return rc;
            }

            if (receiveBuffer != null && pcbRecvLength < receiveBuffer.Length) {
                Array.Resize(ref receiveBuffer, pcbRecvLength);
            }

            return rc;
        }
Exemple #26
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();
                }
            }
        }
Exemple #27
0
        public SCardError Transmit(IntPtr pioSendPci,
                                  byte[] sendBuffer,
                                  int sendBufLength,
                                  SCardPCI ioRecvPci,
                                  byte[] recvBuffer,
                                  ref int recvBufLength)
        {
            if (cardHandle.Equals(IntPtr.Zero))
                throw new InvalidOperationException(
                    "Reader is currently not connected or no card handle has been returned.");

            IntPtr ioRecvPciPtr = IntPtr.Zero;
            if (ioRecvPci != null)
                ioRecvPciPtr = ioRecvPci.iomem;

            SCardError rc = SCardAPI.Lib.Transmit(cardHandle,
                                                pioSendPci,
                                                sendBuffer,
                                                sendBufLength,
                                                ioRecvPciPtr,
                                                recvBuffer,
                                                ref recvBufLength);
            return rc;
        }
Exemple #28
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;
        }
Exemple #29
0
 public SCardError Transmit(byte[] sendBuffer,
             int sendBufferLength,
             byte[] recvBuffer,
             ref int recvBufferLength)
 {
     SCardPCI iorecvpci = new SCardPCI(); // will be discarded
     return Transmit(
         SCardPCI.GetPci(activeprot),
         sendBuffer,
         sendBufferLength,
         iorecvpci,
         recvBuffer,
         ref recvBufferLength);
 }
        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";
        }