예제 #1
0
파일: Form1.cs 프로젝트: priyankarrani/EMV
        public void ReadCard(object ob)
        {
            string selectedReader = ob as string;
            ASN1 daTa = null;
            List<String[]> la = new List<string[]>();
            List<byte[]> pseIdentifiers = new List<byte[]>();
            List<byte[]> applicationIdentifiers = new List<byte[]>();
            ASCIIEncoding encoding = new ASCIIEncoding();
            APDUCmd apdu = null;
            APDURes response = null;
            bool pseFound = false;

            pseIdentifiers.Add(encoding.GetBytes("1PAY.SYS.DDF01"));
            pseIdentifiers.Add(encoding.GetBytes("2PAY.SYS.DDF01"));

            try
            {
                // Now lets process all Payment System Environments
                if (pseIdentifiers.Count > 0)
                {
                    cardReaderList.Connect(selectedReader);
                    foreach (byte[] pse in pseIdentifiers)
                    {
                        apdu = new APDUCmd(0x00, 0xA4, 0x04, 0x00, pse, (byte)pse.Length);
                        response = cardReaderList.Transmit(apdu);

                        // Get response nescesary
                        if (response.SW1 == 0x61)
                        {
                            apdu = new APDUCmd(0x00, 0xC0, 0x00, 0x00, null, response.SW2);
                            response = cardReaderList.Transmit(apdu);
                        }

                        // PSE application read found ok
                        if (response.SW1 == 0x90)
                        {
                            pseFound = true;
                          daTa = new ASN1(response.Data);
                            byte sfi = new ASN1(response.Data).Find(0x88).Value[0];
                            byte recordNumber = 0x01;
                            byte p2 = (byte)((sfi << 3) | 4);

                            while (response.SW1 != 0x6A && response.SW2 != 0x83)
                            {
                                apdu = new APDUCmd(0x00, 0xB2, recordNumber, p2, null, 0x00);
                                response = cardReaderList.Transmit(apdu);

                                // Retry with correct length
                                if (response.SW1 == 0x6C)
                                {
                                    apdu = new APDUCmd(0x00, 0xB2, recordNumber, p2, null, response.SW2);
                                    response = cardReaderList.Transmit(apdu);
                                }

                                if (response.SW1 == 0x61)
                                {
                                    apdu = new APDUCmd(0x00, 0xC0, 0x00, 0x00, null, response.SW2);
                                    response = cardReaderList.Transmit(apdu);
                                }

                                if (response.Data != null)
                                {
                                    ASN1 aefVal = new ASN1(response.Data);

                                    foreach (ASN1 appTemplate in aefVal)
                                    {
                                        // Check we really have an Application Template
                                        if (appTemplate.Tag[0] == 0x61)
                                        {
                                            applicationIdentifiers.Add(appTemplate.Find(0x4f).Value);
                                        }
                                    }
                                }
                                recordNumber++;
                            }
                        }
                        if (pseFound)
                            break;
                    }
                    cardReaderList.Disconnect();
                }

                if (applicationIdentifiers.Count > 0)
                {
                    foreach (byte[] AID in applicationIdentifiers)
                    {
                        List<AppliFileLoc> applicationFileLocators = new List<AppliFileLoc>();
                        StringBuilder sb = new StringBuilder();
                        cardReaderList.Connect(selectedReader);

                        // Select AID
                        apdu = new APDUCmd(0x00, 0xA4, 0x04, 0x00, AID, (byte)AID.Length);
                        response = cardReaderList.Transmit(apdu);

                        // Get response nescesary
                        if (response.SW1 == 0x61)
                        {
                            apdu = new APDUCmd(0x00, 0xC0, 0x00, 0x00, null, response.SW2);
                            response = cardReaderList.Transmit(apdu);
                        }

                        // Application not found
                        if (response.SW1 == 0x6A && response.SW2 == 0x82)
                            continue;

                        if (response.SW1 == 0x90)
                        {
                            foreach (byte b in AID)
                            {
                                sb.AppendFormat("{0:X2}", b);
                            }

                            daTa = new ASN1(response.Data);

                            // Get processing options (with empty PDOL)
                            apdu = new APDUCmd(0x80, 0xA8, 0x00, 0x00, new byte[] { 0x83, 0x00 }, 0x02);
                            response = cardReaderList.Transmit(apdu);

                            // Get response nescesary
                            if (response.SW1 == 0x61)
                            {
                                apdu = new APDUCmd(0x00, 0xC0, 0x00, 0x00, null, response.SW2);
                                response = cardReaderList.Transmit(apdu);
                            }

                            if (response.SW1 == 0x90)
                            {
                                ASN1 template = new ASN1(response.Data);
                                ASN1 aipVal = null;
                                ASN1 aflVal = null;

                                // Primative response (Template Format 1)
                                if (template.Tag[0] == 0x80)
                                {
                                    byte[] tempAIP = new byte[2];
                                    Buffer.BlockCopy(template.Value, 0, tempAIP, 0, 2);
                                    aipVal = new ASN1(0x82, tempAIP);

                                    byte[] tempAFL = new byte[template.Length - 2];
                                    Buffer.BlockCopy(template.Value, 2, tempAFL, 0, template.Length - 2);
                                    aflVal = new ASN1(0x94, tempAFL);
                                }

                                // constructed data object response (Template Format 2)
                                if (template.Tag[0] == 0x77)
                                {
                                    aipVal = template.Find(0x82);
                                    aflVal = template.Find(0x94);
                                }

                                // Chop up AFL's
                                for (int i = 0; i < aflVal.Length; i += 4)
                                {
                                    byte[] AFL = new byte[4];
                                    Buffer.BlockCopy(aflVal.Value, i, AFL, 0, 4);

                                    AppliFileLoc fileLocator = new AppliFileLoc(AFL);
                                    applicationFileLocators.Add(fileLocator);
                                }

                                ASN1 aipafl = new ASN1(response.Data);

                                foreach (AppliFileLoc file in applicationFileLocators)
                                {
                                    int rec = file.FirstRecord;// read SDA records
                                    int lrec = file.LastRecord;
                                    byte p2 = (byte)((file.SFI << 3) | 4);

                                    while (rec <= lrec)
                                    {
                                        apdu = new APDUCmd(0x00, 0xB2, (byte)rec, p2, null, 0x00);
                                        response = cardReaderList.Transmit(apdu);

                                        // Retry with correct length
                                        if (response.SW1 == 0x6C)
                                        {
                                            apdu = new APDUCmd(0x00, 0xB2, (byte)rec, p2, null, response.SW2);
                                            response = cardReaderList.Transmit(apdu);
                                        }

                                        ASN1 record = new ASN1(response.Data);
                                        s_Card(record);
                                        getVal(record);

                                        rec++;
                                    }
                                }
                            }
                            else
                            {

                                UpdateStatusLabel(String.Format("Record not found."));
                            }
                        }
                        else
                        {
                            UpdateStatusLabel(String.Format("File not selected."));
                        }
                        cardReaderList.Disconnect();
                        UpdateStatusLabel(String.Format("Process Complete."));
                    }
                }
            }
            catch (CardDExcep ex)
            {
                UpdateStatusLabel(ex.Message);
                return;
            }
        }
예제 #2
0
        public APDURes Transmit(APDUCmd apdu)
        {
            byte[] recvBuffer = new byte[256];
            int    recvLength = recvBuffer.Length;
            IntPtr sendPci    = IntPtr.Zero;

            switch ((WinConCard.Protocol)activeProtocol)
            {
            case WinConCard.Protocol.SCARD_PROTOCOL_T0:
                sendPci = WinConCard.SCARD_PCI_T0;
                break;

            case WinConCard.Protocol.SCARD_PROTOCOL_T1:
                sendPci = WinConCard.SCARD_PCI_T1;
                break;
            }

            #region Debug output
#if DEBUG
            if (outputDebugString)
            {
                StringBuilder sb = new StringBuilder();

                foreach (byte b in apdu.ToArray())
                {
                    sb.AppendFormat("{0:X2}", b);
                }

                Debug.WriteLine(sb.ToString());
            }
#endif
            #endregion

            int result = WinConCard.SCardTransmit(card, sendPci, apdu.ToArray(), apdu.ToArray().Length, IntPtr.Zero, recvBuffer, ref recvLength);

            if (result != WinConCard.SCARD_S_SUCCESS)
            {
                throw new CardDExcep(result);
            }

            #region Debug output
#if DEBUG
            if (outputDebugString)
            {
                StringBuilder sb = new StringBuilder();

                for (int i = 0; i < recvLength; i++)
                {
                    sb.AppendFormat("{0:X2}", recvBuffer[i]);
                }

                Debug.WriteLine(sb.ToString());
            }
#endif
            #endregion

            byte[] response = new byte[recvLength];
            Buffer.BlockCopy(recvBuffer, 0, response, 0, recvLength);

            return(new APDURes(response));
        }