Пример #1
0
 internal static extern int     SCardTransmit(IntPtr hCard,
                                              [In] ref SCard_IO_Request pioSendPci,
                                              byte[] pbSendBuffer,
                                              UInt32 cbSendLength,
                                              ref SCard_IO_Request pioRecvPci,
                                              [Out] byte[] pbRecvBuffer,
                                              ref UInt32 pcbRecvLength
                                              );
Пример #2
0
 internal static extern int SCardTransmit(IntPtr hCard,
     [In] ref SCard_IO_Request pioSendPci,
     byte[] pbSendBuffer,
     UInt32 cbSendLength,
     ref SCard_IO_Request pioRecvPci,
     [Out] byte[] pbRecvBuffer,
     ref UInt32 pcbRecvLength
     );
Пример #3
0
        /// <summary>
        /// Wraps the PCSC function
        /// LONG SCardTransmit(
        ///		SCARDHANDLE hCard,
        ///		LPCSCARD_I0_REQUEST pioSendPci,
        ///		LPCBYTE pbSendBuffer,
        ///		DWORD cbSendLength,
        ///		LPSCARD_IO_REQUEST pioRecvPci,
        ///		LPBYTE pbRecvBuffer,
        ///		LPDWORD pcbRecvLength
        ///	);
        /// </summary>
        /// <param name="ApduCmd">APDUCommand object with the APDU to send to the card</param>
        /// <returns>An APDUResponse object with the response from the card</returns>
        public override APDUResponse Transmit(APDUCommand ApduCmd)
        {
            uint	RecvLength = (uint) (ApduCmd.Le + APDUResponse.SW_LENGTH);
            byte[]	ApduBuffer = null;
            byte[] ApduResponse = new byte[RecvLength];
            SCard_IO_Request	ioRequest = new SCard_IO_Request();
            ioRequest.m_dwProtocol = m_nProtocol;
            ioRequest.m_cbPciLength = 8;
            SCard_IO_Request ioResponse = new SCard_IO_Request();
            ioResponse.m_dwProtocol = m_nProtocol;
            ioResponse.m_cbPciLength = 8;

            // Build the command APDU
            if (ApduCmd.Data == null)
            {
                ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + ((ApduCmd.Le != 0) ? 1 : 0)];

                if (ApduCmd.Le != 0)
                    ApduBuffer[4] = (byte) ApduCmd.Le;
            }
            else
            {
                ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + 1 + ApduCmd.Data.Length + ((ApduCmd.Le != 0) ? 1 : 0)];

                for (int nI = 0; nI < ApduCmd.Data.Length; nI++)
                    ApduBuffer[APDUCommand.APDU_MIN_LENGTH + 1 + nI] = ApduCmd.Data[nI];

                ApduBuffer[APDUCommand.APDU_MIN_LENGTH] = (byte) ApduCmd.Data.Length;

                if (ApduCmd.Le != 0)
                    ApduBuffer[ApduBuffer.Length - 1] = (byte)ApduCmd.Le;
            }

            ApduBuffer[0] = ApduCmd.Class;
            ApduBuffer[1] = ApduCmd.Ins;
            ApduBuffer[2] = ApduCmd.P1;
            ApduBuffer[3] = ApduCmd.P2;

            m_nLastError = SCardTransmit(m_hCard, ref ioRequest, ApduBuffer, (uint) ApduBuffer.Length, ref ioResponse, ApduResponse, ref RecvLength);
            if (m_nLastError != 0)
            {
                string msg = "SCardTransmit error: " + m_nLastError;
                throw new Exception(msg);
            }
            int sw1 = ApduResponse[ApduResponse.Length - 2] & 0xff;
            int sw2 = ApduResponse[ApduResponse.Length - 1] & 0xff;

            if (sw1 == 0x6c) //wrong length, read again with correct len
            {
                ApduBuffer = new byte[] { ApduCmd.Class, ApduCmd.Ins, ApduCmd.P1, ApduCmd.P2, (byte)sw2 };
                ApduResponse = new byte[sw2 + APDUResponse.SW_LENGTH];
                RecvLength = (uint)ApduResponse.Length;
                m_nLastError = SCardTransmit(m_hCard, ref ioRequest, ApduBuffer, (uint)ApduBuffer.Length, ref ioResponse, ApduResponse, ref RecvLength);
                if (m_nLastError != 0)
                {
                    string msg = "SCardTransmit error: " + m_nLastError;
                    throw new Exception(msg);
                }
                sw1 = ApduResponse[ApduResponse.Length - 2] & 0xff;
                sw2 = ApduResponse[ApduResponse.Length - 1] & 0xff;
            }

            MemoryStream ms = new MemoryStream();
            ms.Write(ApduResponse, 0, ApduResponse.Length - APDUResponse.SW_LENGTH);

            //while has remaining bytes to be read
            while (sw1 == 0x61)
            {
                ApduBuffer = new byte[] { 0, 0xc0, 0, 0, (byte)sw2 }; //read sw2 number of bytes
                ApduResponse = new byte[sw2 + APDUResponse.SW_LENGTH];
                RecvLength = (uint)ApduResponse.Length;
                m_nLastError = SCardTransmit(m_hCard, ref ioRequest, ApduBuffer, (uint)ApduBuffer.Length, ref ioResponse, ApduResponse, ref RecvLength);
                if (m_nLastError != 0)
                {
                    string msg = "SCardTransmit error: " + m_nLastError;
                    throw new Exception(msg);
                }
                sw1 = ApduResponse[ApduResponse.Length - 2] & 0xff;
                sw2 = ApduResponse[ApduResponse.Length - 1] & 0xff;
                if (ApduResponse.Length > APDUResponse.SW_LENGTH)
                {
                    ms.Write(ApduResponse, 0, ApduResponse.Length - APDUResponse.SW_LENGTH);
                }
            }
            ms.WriteByte((byte)sw1);
            ms.WriteByte((byte)sw2);

            return new APDUResponse(ms.ToArray());
        }
Пример #4
0
        /// <summary>
        /// Wraps the PCSC function
        /// LONG SCardTransmit(
        ///		SCARDHANDLE hCard,
        ///		LPCSCARD_I0_REQUEST pioSendPci,
        ///		LPCBYTE pbSendBuffer,
        ///		DWORD cbSendLength,
        ///		LPSCARD_IO_REQUEST pioRecvPci,
        ///		LPBYTE pbRecvBuffer,
        ///		LPDWORD pcbRecvLength
        ///	);
        /// </summary>
        /// <param name="ApduCmd">APDUCommand object with the APDU to send to the card</param>
        /// <returns>An APDUResponse object with the response from the card</returns>
        public override APDUResponse Transmit(APDUCommand ApduCmd)
        {
            uint RecvLength = (uint)(ApduCmd.Le + APDUResponse.SW_LENGTH);

            byte[]           ApduBuffer   = null;
            byte[]           ApduResponse = new byte[RecvLength];
            SCard_IO_Request ioRequest    = new SCard_IO_Request();

            ioRequest.m_dwProtocol  = m_nProtocol;
            ioRequest.m_cbPciLength = 8;
            SCard_IO_Request ioResponse = new SCard_IO_Request();

            ioResponse.m_dwProtocol  = m_nProtocol;
            ioResponse.m_cbPciLength = 8;

            // Build the command APDU
            if (ApduCmd.Data == null)
            {
                ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + ((ApduCmd.Le != 0) ? 1 : 0)];

                if (ApduCmd.Le != 0)
                {
                    ApduBuffer[4] = (byte)ApduCmd.Le;
                }
            }
            else
            {
                ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + 1 + ApduCmd.Data.Length + ((ApduCmd.Le != 0) ? 1 : 0)];

                for (int nI = 0; nI < ApduCmd.Data.Length; nI++)
                {
                    ApduBuffer[APDUCommand.APDU_MIN_LENGTH + 1 + nI] = ApduCmd.Data[nI];
                }

                ApduBuffer[APDUCommand.APDU_MIN_LENGTH] = (byte)ApduCmd.Data.Length;

                if (ApduCmd.Le != 0)
                {
                    ApduBuffer[ApduBuffer.Length - 1] = (byte)ApduCmd.Le;
                }
            }

            ApduBuffer[0] = ApduCmd.Class;
            ApduBuffer[1] = ApduCmd.Ins;
            ApduBuffer[2] = ApduCmd.P1;
            ApduBuffer[3] = ApduCmd.P2;

            m_nLastError = SCardTransmit(m_hCard, ref ioRequest, ApduBuffer, (uint)ApduBuffer.Length, ref ioResponse, ApduResponse, ref RecvLength);
            if (m_nLastError != 0)
            {
                string msg = "SCardTransmit error: " + m_nLastError;
                throw new Exception(msg);
            }
            int sw1 = ApduResponse[ApduResponse.Length - 2] & 0xff;
            int sw2 = ApduResponse[ApduResponse.Length - 1] & 0xff;

            if (sw1 == 0x6c) //wrong length, read again with correct len
            {
                ApduBuffer   = new byte[] { ApduCmd.Class, ApduCmd.Ins, ApduCmd.P1, ApduCmd.P2, (byte)sw2 };
                ApduResponse = new byte[sw2 + APDUResponse.SW_LENGTH];
                RecvLength   = (uint)ApduResponse.Length;
                m_nLastError = SCardTransmit(m_hCard, ref ioRequest, ApduBuffer, (uint)ApduBuffer.Length, ref ioResponse, ApduResponse, ref RecvLength);
                if (m_nLastError != 0)
                {
                    string msg = "SCardTransmit error: " + m_nLastError;
                    throw new Exception(msg);
                }
                sw1 = ApduResponse[ApduResponse.Length - 2] & 0xff;
                sw2 = ApduResponse[ApduResponse.Length - 1] & 0xff;
            }

            MemoryStream ms = new MemoryStream();

            ms.Write(ApduResponse, 0, ApduResponse.Length - APDUResponse.SW_LENGTH);

            //while has remaining bytes to be read
            while (sw1 == 0x61)
            {
                ApduBuffer   = new byte[] { 0, 0xc0, 0, 0, (byte)sw2 }; //read sw2 number of bytes
                ApduResponse = new byte[sw2 + APDUResponse.SW_LENGTH];
                RecvLength   = (uint)ApduResponse.Length;
                m_nLastError = SCardTransmit(m_hCard, ref ioRequest, ApduBuffer, (uint)ApduBuffer.Length, ref ioResponse, ApduResponse, ref RecvLength);
                if (m_nLastError != 0)
                {
                    string msg = "SCardTransmit error: " + m_nLastError;
                    throw new Exception(msg);
                }
                sw1 = ApduResponse[ApduResponse.Length - 2] & 0xff;
                sw2 = ApduResponse[ApduResponse.Length - 1] & 0xff;
                if (ApduResponse.Length > APDUResponse.SW_LENGTH)
                {
                    ms.Write(ApduResponse, 0, ApduResponse.Length - APDUResponse.SW_LENGTH);
                }
            }
            ms.WriteByte((byte)sw1);
            ms.WriteByte((byte)sw2);

            return(new APDUResponse(ms.ToArray()));
        }