예제 #1
0
        public APDUResponse Transmit(APDUCommand apduCmd)
        {
            try
            {
                Core.Smartcard.APDUCommand apduCommand = new Core.Smartcard.APDUCommand(
                    apduCmd.Class,
                    apduCmd.Ins,
                    apduCmd.P1,
                    apduCmd.P2,
                    (apduCmd.Data == null || apduCmd.Data.Length == 0) ? null : apduCmd.Data,
                    apduCmd.Le);

                Core.Smartcard.APDUResponse apduResponse = card.Transmit(apduCommand);

                return(new APDUResponse()
                {
                    Data = apduResponse.Data,
                    SW1 = apduResponse.SW1,
                    SW2 = apduResponse.SW2
                });
            }
            catch (SmartCardException scEx)
            {
                SmartcardFault scFault = new SmartcardFault(scEx);
                throw new FaultException <SmartcardFault>(scFault);
            }
            catch (Exception ex)
            {
                GeneralFault genFault = new GeneralFault(ex);
                throw new FaultException <GeneralFault>(genFault);
            }
        }
예제 #2
0
        public APDUResponse ProcessCommand(string cmdClass, string cmdIns, APDUParam apduParam)
        {
            byte        bClass      = byte.Parse(cmdClass, NumberStyles.AllowHexSpecifier);
            byte        bIns        = byte.Parse(cmdIns, NumberStyles.AllowHexSpecifier);
            APDUCommand apduCommand = new APDUCommand(bClass, bIns, 0, 0, null, 0);

            apduCommand.Update(apduParam);

            return(ExecuteApduCommand(apduCommand));
        }
예제 #3
0
        /// <summary>
        /// Process a simple APDU command, all parameters are included in the
        /// XML description
        /// </summary>
        /// <param name="command">APDU command name</param>
        /// <returns>An APDUResponse object with the response of the card </returns>
        public APDUResponse ProcessCommand(string apduName)
        {
            APDUCommand apduCmd = null;

            apduCmd = APDUByName(apduName);
            if (apduCmd == null)
            {
                throw new ApduCommandException(ApduCommandException.NoSuchCommand);
            }

            return(ExecuteApduCommand(apduCmd));
        }
        /// <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)
        {
            // Must verify that it works with all type of cards
            uint outputLength = (ApduCmd.Le == 0)
                ? APDUResponse.MAX_LENGHT
                :(ApduCmd.Le + APDUResponse.SW_LENGTH);

            byte[] ApduBuffer   = null;
            byte[] ApduResponse = new byte[outputLength];

            PCSC.SCard_IO_Request ioRequest = new PCSC.SCard_IO_Request();
            ioRequest.Protocol  = protocol;
            ioRequest.PciLength = (uint)Marshal.SizeOf(ioRequest);

            // Build the command APDU
            if (ApduCmd.Data == null)
            {
                ApduBuffer    = new byte[APDUCommand.APDU_MIN_LENGTH + 1]; // Pass the Le = 0 as well
                ApduBuffer[4] = (byte)ApduCmd.Le;
            }
            else
            {
                int apduBufferLengh = (ApduCmd.Class == 0x90)
                    ? APDUCommand.APDU_MIN_LENGTH + 1 + ApduCmd.Data.Length + 1
                    : APDUCommand.APDU_MIN_LENGTH + 1 + ApduCmd.Data.Length;

                ApduBuffer = new byte[apduBufferLengh];
                Buffer.BlockCopy(ApduCmd.Data, 0, ApduBuffer, APDUCommand.APDU_MIN_LENGTH + 1, ApduCmd.Data.Length);
                ApduBuffer[APDUCommand.APDU_MIN_LENGTH] = (byte)ApduCmd.Data.Length;
                if (ApduCmd.Class == 0x90)
                {
                    ApduBuffer[apduBufferLengh - 1] = 0;
                }
            }

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

            lastError = PCSC.SCardTransmit(cardHandle, ref ioRequest, ApduBuffer, (uint)ApduBuffer.Length, IntPtr.Zero, ApduResponse, out outputLength);
            ThrowSmartcardException("SCardTransmit", lastError);

            byte[] responseData = new byte[outputLength];
            Buffer.BlockCopy(ApduResponse, 0, responseData, 0, (int)outputLength);
            string apduString = string.Format("APDU Buffer[{0}] => Response[{1}]", ByteArray.ToString(ApduBuffer), ByteArray.ToString(responseData));

            apduTrace.Add(apduString);
            Trace.WriteLine(apduString);

            return(new APDUResponse(responseData));
        }
예제 #5
0
        /// <summary>
        /// Executes an APDU command
        /// </summary>
        /// <param name="apduCmd">APDUCommand object to execute</param>
        /// <returns>APDUResponse object of the response</returns>
        public APDUResponse ExecuteApduCommand(APDUCommand apduCmd)
        {
            byte bLe = 0;

            // Send the command
            m_apduResp = Card.Transmit(apduCmd);
            AddLog(new APDULog(apduCmd, m_apduResp));

            // Check if SW2 can be used as Le for the next call
            if (m_apduResp.SW1 == 0x9F)
            {
                m_bLeSW2 = true;
            }
            else
            {
                m_bLeSW2 = false;
            }

            if (m_bReplay)
            {
                if (m_bCheckSW1 && (m_apduResp.SW1 == m_bSW1Cond))
                {
                    // Replay the command with Le = SW2 of response
                    bLe         = m_apduResp.SW2;
                    m_bCheckSW1 = false;
                }
                else if (m_bLeData)
                {
                    // Replay the command with Le = Le + Data[m_nDataId - 1] of response
                    bLe       = (byte)(m_apduResp.Data[m_nDataId - 1] + apduCmd.Le);
                    m_bLeData = false;
                }

                // Replay the command
                apduCmd = new APDUCommand(
                    apduCmd.Class,
                    apduCmd.Ins,
                    apduCmd.P1,
                    apduCmd.P2,
                    apduCmd.Data,
                    bLe);

                m_apduResp = Card.Transmit(apduCmd);
                AddLog(new APDULog(apduCmd, m_apduResp));

                m_bReplay = false;
            }

            return(m_apduResp);
        }
예제 #6
0
        /// <summary>
        /// Process a simple APDU command, Parameters can be provided in the APDUParam object
        /// </summary>
        /// <param name="command">APDU command name</param>
        /// <param name="apduParam">Parameters for the command</param>
        /// <returns>An APDUResponse object with the response of the card </returns>
        public APDUResponse ProcessCommand(string apduName, APDUParam apduParam)
        {
            APDUCommand apduCmd = null;

            // Get the base APDU
            apduCmd = APDUByName(apduName);
            if (apduCmd == null)
            {
                throw new ApduCommandException(ApduCommandException.NoSuchCommand);
            }

            apduCmd.Update(apduParam);

            return(ExecuteApduCommand(apduCmd));
        }
예제 #7
0
        /// <summary>
        /// Gets an APDU command by name
        /// </summary>
        /// <param name="apduName">APDU name</param>
        /// <returns>An APDUCommand object, null if the command was not found</returns>
        public APDUCommand APDUByName(string apduName)
        {
            APDUCommand apduCmd = null;

            if (m_xmlApduList != null)
            {
                for (int nI = 0; nI < m_xmlApduList.Count; nI++)
                {
                    XmlNode apdu = m_xmlApduList.Item(nI);

                    string sName = apdu.Attributes[xmlAttrName].Value;
                    if (sName == apduName)
                    {
                        apduCmd = APDUFromXml(apdu);
                        break;
                    }
                }
            }

            return(apduCmd);
        }
        /// <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)
        {
            // Must verify that it works with all type of cards
            uint outputLength = (ApduCmd.Le == 0)
                ? APDUResponse.MAX_LENGHT
                : (ApduCmd.Le + APDUResponse.SW_LENGTH);

            byte[] ApduBuffer   = null;
            byte[] ApduResponse = new byte[outputLength];

            PCSC.SCard_IO_Request ioRequest = new PCSC.SCard_IO_Request();
            ioRequest.Protocol  = protocol;
            ioRequest.PciLength = (uint)Marshal.SizeOf(ioRequest);

            // Build the command APDU
            if (ApduCmd.Data == null)
            {
                ApduBuffer    = new byte[APDUCommand.APDU_MIN_LENGTH + 1]; // Pass the Le = 0 as well
                ApduBuffer[4] = (byte)ApduCmd.Le;
            }
            else
            {
                ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + 1 + ApduCmd.Data.Length];
                Buffer.BlockCopy(ApduCmd.Data, 0, ApduBuffer, APDUCommand.APDU_MIN_LENGTH + 1, ApduCmd.Data.Length);
                ApduBuffer[APDUCommand.APDU_MIN_LENGTH] = (byte)ApduCmd.Data.Length;
            }

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

            lastError = PCSC.SCardTransmit(cardHandle, ref ioRequest, ApduBuffer, (uint)ApduBuffer.Length, IntPtr.Zero, ApduResponse, out outputLength);
            ThrowSmartcardException("SCardTransmit", lastError);

            byte[] ApduData = new byte[outputLength];
            Buffer.BlockCopy(ApduResponse, 0, ApduData, 0, (int)outputLength);

            return(new APDUResponse(ApduData));
        }
예제 #9
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)
        {
            // Must verify that it works with all type of cards
            uint outputLength =  (ApduCmd.Le == 0)
                ? APDUResponse.MAX_LENGHT
                :(ApduCmd.Le + APDUResponse.SW_LENGTH);
            byte[]	ApduBuffer = null;
            byte[] ApduResponse = new byte[outputLength];

            PCSC.SCard_IO_Request	ioRequest = new PCSC.SCard_IO_Request();
            ioRequest.Protocol = protocol;
            ioRequest.PciLength = (uint)Marshal.SizeOf(ioRequest);

            // Build the command APDU
            if (ApduCmd.Data == null)
            {
                ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + 1]; // Pass the Le = 0 as well
                ApduBuffer[4] = (byte)ApduCmd.Le;
            }
            else
            {
                int apduBufferLengh = (ApduCmd.Class == 0x90)
                    ? APDUCommand.APDU_MIN_LENGTH + 1 + ApduCmd.Data.Length + 1
                    : APDUCommand.APDU_MIN_LENGTH + 1 + ApduCmd.Data.Length;

                ApduBuffer = new byte[apduBufferLengh];
                Buffer.BlockCopy(ApduCmd.Data, 0, ApduBuffer, APDUCommand.APDU_MIN_LENGTH + 1, ApduCmd.Data.Length);
                ApduBuffer[APDUCommand.APDU_MIN_LENGTH] = (byte) ApduCmd.Data.Length;
                if (ApduCmd.Class == 0x90)
                {
                    ApduBuffer[apduBufferLengh - 1] = 0;
                }
            }

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

            lastError = PCSC.SCardTransmit(cardHandle, ref ioRequest, ApduBuffer, (uint)ApduBuffer.Length, IntPtr.Zero, ApduResponse, out outputLength);
            ThrowSmartcardException("SCardTransmit", lastError);

            byte[] responseData = new byte[outputLength];
            Buffer.BlockCopy(ApduResponse, 0, responseData, 0, (int)outputLength);
            string apduString = string.Format("APDU Buffer[{0}] => Response[{1}]", ByteArray.ToString(ApduBuffer), ByteArray.ToString(responseData));
            apduTrace.Add(apduString);
            Trace.WriteLine(apduString);

            return new APDUResponse(responseData);
        }
예제 #10
0
        public APDUResponse Transmit(APDUCommand apduCmd)
        {
            try
            {
                Core.Smartcard.APDUCommand apduCommand = new Core.Smartcard.APDUCommand(
                    apduCmd.Class,
                    apduCmd.Ins,
                    apduCmd.P1,
                    apduCmd.P2,
                    (apduCmd.Data == null || apduCmd.Data.Length == 0) ? null : apduCmd.Data,
                    apduCmd.Le);

                Core.Smartcard.APDUResponse apduResponse = card.Transmit(apduCommand);

                return new APDUResponse()
                {
                    Data = apduResponse.Data,
                    SW1 = apduResponse.SW1,
                    SW2 = apduResponse.SW2
                };
            }
            catch (SmartCardException scEx)
            {
                SmartcardFault scFault = new SmartcardFault(scEx);
                throw new FaultException<SmartcardFault>(scFault);
            }
            catch (Exception ex)
            {
                GeneralFault genFault = new GeneralFault(ex);
                throw new FaultException<GeneralFault>(genFault);
            }
        }
예제 #11
0
        private void DisplayAPDUCommand(APDUCommand apduCmd)
        {
            if (apduCmd != null)
            {
                textClass.Text = string.Format("{0:X02}", apduCmd.Class);
                textIns.Text = string.Format("{0:X02}", apduCmd.Ins);
                textP1.Text = string.Format("{0:X02}", apduCmd.P1);
                textP2.Text = string.Format("{0:X02}", apduCmd.P2);
                textLe.Text = apduCmd.Le.ToString();

                textData.Text = (apduCmd.Data != null)
                    ? ByteArray.ToString(apduCmd.Data)
                    : string.Empty;

                apduParam = new APDUParam();

                apduParam.P1 = apduCmd.P1;
                apduParam.P2 = apduCmd.P2;
                apduParam.Le = apduCmd.Le;
            }
        }
예제 #12
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[ApduCmd.Le + APDUResponse.SW_LENGTH];
            SCard_IO_Request	ioRequest = new SCard_IO_Request();
            ioRequest.m_dwProtocol = m_nProtocol;
            ioRequest.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];
                Buffer.BlockCopy(ApduCmd.Data, 0, ApduBuffer, APDUCommand.APDU_MIN_LENGTH + 1, ApduCmd.Data.Length);
                ApduBuffer[APDUCommand.APDU_MIN_LENGTH] = (byte) ApduCmd.Data.Length;
            }

            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, IntPtr.Zero, ApduResponse, out RecvLength);
            ThrowSmartcardException("SCardTransmit", m_nLastError);

            byte[] ApduData = new byte[RecvLength];
            Buffer.BlockCopy(ApduResponse, 0, ApduData, 0, (int)RecvLength);

            return new APDUResponse(ApduData);
        }
예제 #13
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)
        {
            // Must verify that it works with all type of cards
            uint outputLength = (ApduCmd.Le == 0)
                ? APDUResponse.MAX_LENGHT
                : (ApduCmd.Le + APDUResponse.SW_LENGTH);
            byte[] ApduBuffer = null;
            byte[] ApduResponse = new byte[outputLength];

            PCSC.SCard_IO_Request ioRequest = new PCSC.SCard_IO_Request();
            ioRequest.Protocol = protocol;
            ioRequest.PciLength = (uint)Marshal.SizeOf(ioRequest);

            // Build the command APDU
            if (ApduCmd.Data == null)
            {
                ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + 1]; // Pass the Le = 0 as well
                ApduBuffer[4] = (byte)ApduCmd.Le;
            }
            else
            {
                ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + 1 + ApduCmd.Data.Length];
                Buffer.BlockCopy(ApduCmd.Data, 0, ApduBuffer, APDUCommand.APDU_MIN_LENGTH + 1, ApduCmd.Data.Length);
                ApduBuffer[APDUCommand.APDU_MIN_LENGTH] = (byte)ApduCmd.Data.Length;
            }

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

            lastError = PCSC.SCardTransmit(cardHandle, ref ioRequest, ApduBuffer, (uint)ApduBuffer.Length, IntPtr.Zero, ApduResponse, out outputLength);
            ThrowSmartcardException("SCardTransmit", lastError);

            byte[] ApduData = new byte[outputLength];
            Buffer.BlockCopy(ApduResponse, 0, ApduData, 0, (int)outputLength);

            return new APDUResponse(ApduData);
        }
예제 #14
0
 abstract public APDUResponse Transmit(APDUCommand ApduCmd);
예제 #15
0
        private void DisplayAPDUCommand(APDUCommand apduCmd)
        {
            if (apduCmd != null)
            {
                textClass.Text = string.Format("{0:X02}", apduCmd.Class);
                textIns.Text = string.Format("{0:X02}", apduCmd.Ins);
                textP1.Text = string.Format("{0:X02}", apduCmd.P1);
                textP2.Text = string.Format("{0:X02}", apduCmd.P2);
                textLe.Text = apduCmd.Le.ToString();

                if (apduCmd.Data != null)
                {
                    StringBuilder	sData = new StringBuilder(apduCmd.Data.Length * 2);
                    for (int nI = 0; nI < apduCmd.Data.Length; nI++)
                        sData.AppendFormat("{0:X02}", apduCmd.Data[nI]);

                    textData.Text = sData.ToString();
                }
                else
                    textData.Text = "";

                m_apduParam = new APDUParam();

                m_apduParam.P1 = apduCmd.P1;
                m_apduParam.P2 = apduCmd.P2;
                m_apduParam.Le = apduCmd.Le;
            }
        }
예제 #16
0
 public APDULog(APDUCommand apduCmd, APDUResponse apduResp)
 {
     m_apduCmd  = apduCmd;
     m_apduResp = apduResp;
 }