示例#1
0
        public void ReadCard()
        {
            //get processing options
            ReadGPO();

            //read all possible data and extract needed  info
            foreach (SFIRecords sfir in sfiRecords)
            {
                byte p2 = (byte)((sfir.sfi << 3) | 4);
                foreach (byte p1 in sfir.records)
                {
                    //read each record
                    APDUCommand  apduReadRecord = new APDUCommand(0x00, 0xB2, p1, p2, null, 0);
                    APDUResponse apduR          = this.cardUpdater.Transmit(apduReadRecord);
                    if (apduR.SW1 == 0x90)
                    {
                        if (apduR.Data[0] == 0x70 || apduR.Data[0] == 0x77)
                        {
                            ExtractData(ReadTagData(apduR.Data, 0));
                            //if (!String.IsNullOrEmpty(NumberString) && !String.IsNullOrEmpty(Name) &&
                            //    !String.IsNullOrEmpty(ExpiryString) && !String.IsNullOrEmpty(CardType) &&
                            //    !String.IsNullOrEmpty(Label))
                            //    return;  //we have all info we need
                        }
                        else
                        {
                            throw new Exception("Unrecognized data template");
                        }
                    }
                }
            }
        }
示例#2
0
        public bool SelectApplication()
        {
            System.Threading.Thread.Sleep(100);
            //dunno what the heck is this command
            APDUCommand  apduCmd = new APDUCommand(0, 0xa4, 1, 0, new byte[] { 1, 0x18 }, 0);
            APDUResponse apdu1   = iCard.Transmit(apduCmd);

            if (apdu1.SW1 != 0x90)
            {
                System.Threading.Thread.Sleep(100);
                apdu1 = iCard.Transmit(apduCmd);
                if (apdu1.SW1 != 0x90)
                {
                    return(false);
                }
            }

            System.Threading.Thread.Sleep(100);
            //dunno what the heck is this command, probably selecting something
            apduCmd = new APDUCommand(0, 0xa4, 2, 0, new byte[] { 0, 1 }, 0);
            apdu1   = iCard.Transmit(apduCmd);
            if (apdu1.SW1 != 0x90)
            {
                System.Threading.Thread.Sleep(100);
                apdu1 = iCard.Transmit(apduCmd);
                if (apdu1.SW1 != 0x90)
                {
                    return(false);
                }
            }
            System.Threading.Thread.Sleep(100);

            return(true);
        }
示例#3
0
        public bool SelectApplication()
        {
            APDUCommand  apduSelectPxyApl = new APDUCommand(0x00, 0xA4, 4, 0, m_JPNAID, 0);
            APDUResponse apdu1            = this.cardUpdater.Transmit(apduSelectPxyApl);

            byte[] apduRespByte = apdu1.Packet;
            return(checkExchangeApduResult(apduRespByte));
        }
示例#4
0
        private void ReadGPO()
        {
            //get processing options
            APDUCommand  apduGPO = new APDUCommand(0x80, 0xa8, 0, 0, new byte[] { 0x83, 0 }, 0);
            APDUResponse apdu1   = this.cardUpdater.Transmit(apduGPO);

            if (apdu1.SW1 != 0x90)
            {
                throw new Exception("Read GPO Data fail");
            }
            //two possible forms, 0x80 and 0x77
            if (apdu1.Data[0] == 0x80)
            {
                for (int i = 4; i < apdu1.Data.Length; i += 4)
                {
                    byte   sfi      = (byte)((apdu1.Data[i] >> 3) & 0xf);
                    byte   lowRange = apdu1.Data[i + 1];
                    byte   hiRange  = apdu1.Data[i + 2];
                    byte[] records  = new byte[hiRange - lowRange + 1];
                    for (int j = lowRange; j <= hiRange; j++)
                    {
                        records[j - lowRange] = (byte)j;
                    }
                    sfiRecords.Add(new SFIRecords(sfi, records));
                }
            }
            else if (apdu1.Data[0] == 0x77)
            {
                //look for the application file locator AFL
                int a, tag;
                for (a = 2; (tag = ReadTag(apdu1.Data, a)) != 0x94; a = SkipTag(apdu1.Data, a))
                {
                    ;
                }
                if (tag == 0x94)
                {
                    //found it
                    a++;
                    int len = apdu1.Data[a++];
                    for (int i = a; i < a + len; i += 4)
                    {
                        byte   sfi      = (byte)((apdu1.Data[i] >> 3) & 0xf);
                        byte   lowRange = apdu1.Data[i + 1];
                        byte   hiRange  = apdu1.Data[i + 2];
                        byte[] records  = new byte[hiRange - lowRange + 1];
                        for (int j = lowRange; j <= hiRange; j++)
                        {
                            records[j - lowRange] = (byte)j;
                        }
                        sfiRecords.Add(new SFIRecords(sfi, records));
                    }
                }
            }
            else
            {
                throw new Exception("Unknown GPO template");
            }
        }
示例#5
0
        public bool SelectApplication()
        {
            //select the PSE application
            APDUCommand  apduSelectPSEApl = new APDUCommand(0x00, 0xA4, 4, 0, m_PSEAID, 0);
            APDUResponse apduPSE          = this.cardUpdater.Transmit(apduSelectPSEApl);

            if (apduPSE.SW1 == 0x90)    //PSE supported
            {
                //send the Read Record command, record 1, SFI 1
                //P2 format:  MSB                  LSB
                //            7   6   5   4   3   2   1   0
                //            SFI SFI SFI SFI SFI 1   0   0
                //1 0 0 in the LSB bits means that P1 is a record number
                APDUCommand  apduReadRecord = new APDUCommand(0x00, 0xB2, 1, 0xc, null, 0);
                APDUResponse apdu1          = this.cardUpdater.Transmit(apduReadRecord);
                if (apdu1.SW1 == 0x90)
                {
                    m_EMVAID = new byte[apdu1.Data[5]];
                    Array.Copy(apdu1.Data, 6, m_EMVAID, 0, m_EMVAID.Length);

                    APDUCommand  apduSelectEMVApl = new APDUCommand(0x00, 0xA4, 4, 0, m_EMVAID, 0);
                    APDUResponse apdu2            = this.cardUpdater.Transmit(apduSelectEMVApl);
                    if (apdu2.SW1 == 0x90)
                    {
                        //Label = ASCIIEncoding.ASCII.GetString(apdu2.Data, 15, apdu2.Data[14]);
                        if (apdu2.Data[0] == 0x6f)  //fci template
                        {
                            ExtractData(ReadTagData(apdu2.Data, 0));
                        }
                        return(true);
                    }
                }
            }

            //PSE unsupported, need to try AID list
            foreach (byte[] aid in aidList)
            {
                APDUCommand  apduSelectEMVApl = new APDUCommand(0x00, 0xA4, 4, 0, aid, 0);
                APDUResponse apdu2            = this.cardUpdater.Transmit(apduSelectEMVApl);
                if (apdu2.SW1 == 0x90)
                {
                    //Label = ASCIIEncoding.ASCII.GetString(apdu2.Data, 15, apdu2.Data[14]);
                    //found it!
                    m_EMVAID = aid;
                    if (apdu2.Data[0] == 0x6f)  //fci template
                    {
                        ExtractData(ReadTagData(apdu2.Data, 0));
                    }
                    return(true);
                }
            }

            return(false);
        }
示例#6
0
        private void SetLength(short len)
        {
            byte[] paramBytes = new byte[] { 8, 0, 0, 0, 0 };
            byte[] lenBytes   = BitConverter.GetBytes(len);
            Array.Copy(lenBytes, 0, paramBytes, 3, 2);
            APDUCommand  setLengthAPdu = new APDUCommand(0xc8, 0x32, 0, 0, paramBytes, 0);
            APDUResponse apdu1         = this.cardUpdater.Transmit(setLengthAPdu);

            if (apdu1.SW1 != 0x91 || apdu1.SW2 != 8)
            {
                throw new Exception("Failed to read");
            }
            ;
        }
示例#7
0
        private byte[] ReadInfo(short len)
        {
            MemoryStream ms = new MemoryStream();

            while (len > 0)
            {
                byte         readLen      = (byte)(len < 255 ? len : 255);
                APDUCommand  readInfoApdu = new APDUCommand(0xcc, 6, 0, 0, null, readLen);
                APDUResponse apdu1        = this.cardUpdater.Transmit(readInfoApdu);
                if (apdu1.SW1 != 0x94 && apdu1.SW1 != 0x90)
                {
                    throw new Exception("Failed to read");
                }
                ;
                len -= readLen;
                ms.Write(apdu1.Data, 0, apdu1.Data.Length);
            }
            return(ms.ToArray());
        }
示例#8
0
        private void SelectInfo(short filen1, short filen2, short offset, short len)
        {
            byte[] paramBytes  = new byte[8];
            byte[] n1Bytes     = BitConverter.GetBytes(filen1);
            byte[] n2Bytes     = BitConverter.GetBytes(filen2);
            byte[] offsetBytes = BitConverter.GetBytes(offset);
            byte[] lenBytes    = BitConverter.GetBytes(len);
            Array.Copy(n2Bytes, 0, paramBytes, 0, 2);
            Array.Copy(n1Bytes, 0, paramBytes, 2, 2);
            Array.Copy(offsetBytes, 0, paramBytes, 4, 2);
            Array.Copy(lenBytes, 0, paramBytes, 6, 2);
            APDUCommand  setLengthAPdu = new APDUCommand(0xcc, 0, 0, 0, paramBytes, 0);
            APDUResponse apdu1         = this.cardUpdater.Transmit(setLengthAPdu);

            if (apdu1.SW1 != 0x94)
            {
                throw new Exception("Failed to read");
            }
            ;
        }
示例#9
0
 private byte[] mifareGetData(byte paramByte1, byte paramByte2, byte paramByte3)
 {
     /*int i = 0;
      * byte[] arrayOfByte1 = new byte[5 + this.m_proxyAppletAID.Length];
      * arrayOfByte1[0] = 0;
      * arrayOfByte1[1] = 0xa4;
      * arrayOfByte1[2] = 4;
      * arrayOfByte1[3] = 0;
      * arrayOfByte1[4] = (byte)this.m_proxyAppletAID.Length;
      * Array.Copy(this.m_proxyAppletAID, 0, arrayOfByte1, 5, this.m_proxyAppletAID.Length);
      * byte[] arrayOfByte2 = new byte[5];
      * byte[] arrayOfByte3 = null;
      * int j = 0;
      * arrayOfByte2[0] = 0x80;
      * arrayOfByte2[1] = paramByte1;
      * arrayOfByte2[2] = paramByte2;
      * arrayOfByte2[3] = paramByte3;
      * arrayOfByte2[4] = 0;*/
     try
     {
         byte[] arrayOfByte3;
         //APDUCommand apduSelectPxyApl = new APDUCommand(0x00, 0xA4, 4, 0, m_proxyAppletAID, 0);
         //APDUResponse apdu1 = this.cardUpdater.Transmit(apduSelectPxyApl);
         //arrayOfByte3 = apdu1.Packet;
         //if (!checkExchangeApduResult(arrayOfByte3))
         //return arrayOfByte3;
         APDUResponse apdu3 = this.cardUpdater.Transmit(new APDUCommand(0x80, paramByte1, paramByte2, paramByte3, null, 1));
         arrayOfByte3 = apdu3.Packet;
         checkExchangeApduResult(arrayOfByte3);
         return(arrayOfByte3);
         //j = arrayOfByte3.Length;
     }
     catch (Exception localException)
     {
         //localException.printStackTrace();
     }
     return(null);
 }
示例#10
0
        public void ReadCard()
        {
            //read balance   80 32 00 03 04 00 00 00 00
            //received:                                     Deposit(BCD)
            //                                              vvvvv
            // 05 11 11 25 02 03 12 15 37 20 00 25 09 08 60 00 00 0A 00 18 00 00 00 00 90 00
            //    ^^^^^^^^^^^^^^^^^^^^^^^          ^^^^^ ^^
            //            CAN                issue date  months of validity
            //                               2009/08     60 mths

            APDUCommand  apduCmd = new APDUCommand(0x80, 0x32, 0, 3, new byte[4], 0);
            APDUResponse apdu1   = iCard.Transmit(apduCmd);

            byte[] balanceBytes = new byte[4];
            balanceBytes[0] = apdu1.Data[3];
            balanceBytes[1] = apdu1.Data[2];
            balanceBytes[2] = apdu1.Data[1];
            balanceBytes[3] = apdu1.Data[0];
            //balance is in cents. divide by 100 to get dollars
            Balance = BitConverter.ToInt32(balanceBytes, 0) / 100.0f;

            //dunno what the heck is this command, probably selecting something
            apduCmd = new APDUCommand(0, 0xa4, 2, 0, new byte[] { 0, 1 }, 0);
            apdu1   = iCard.Transmit(apduCmd);

            //read CAN, expiry date, deposit 00 B0 00 00 18
            apduCmd = new APDUCommand(0x00, 0xb0, 0, 0, null, 0x18);
            apdu1   = iCard.Transmit(apduCmd);
            //card number (CAN)
            Number = ConvertBCDCardNumber(apdu1.Data, 1, 8);
            //get the string form XXXX-XXXX-XXXX-XXXX
            StringBuilder sb = new StringBuilder();

            sb.Append(ConvertBCDCardNumber(apdu1.Data, 1, 2).ToString("D4"));
            sb.Append("-");
            sb.Append(ConvertBCDCardNumber(apdu1.Data, 3, 2).ToString("D4"));
            sb.Append("-");
            sb.Append(ConvertBCDCardNumber(apdu1.Data, 5, 2).ToString("D4"));
            sb.Append("-");
            sb.Append(ConvertBCDCardNumber(apdu1.Data, 7, 2).ToString("D4"));
            NumberString = sb.ToString();
            //read expiry date
            int year = apdu1.Data[12]; //year, from 1900 or 2000

            if (year > 90 && year < 100)
            {
                year += 1900;
            }
            else
            {
                year += 2000;
            }
            byte     month     = apdu1.Data[13];
            byte     validity  = (byte)ConvertBCDCardNumber(apdu1.Data, 14, 1); //validity in months
            DateTime issueDate = new DateTime(year, month, 1);

            Expiry       = issueDate.AddMonths(validity);
            ExpiryString = Expiry.ToString("dd MMM yyyy");
            Deposit      = ConvertBCDCardNumber(apdu1.Data, 15, 2) / 100.0f;

            //get transaction log
            //read number of total entries in log
            apduCmd = new APDUCommand(0, 0xb0, 0, 2, null, 4);
            apdu1   = iCard.Transmit(apduCmd);
            if (apdu1.SW1 != 0x90)
            {
                throw new Exception("Read NETS log size fail");
            }
            short logSize = (short)ConvertBCDCardNumber(new byte[] { apdu1.Data[2], apdu1.Data[3] }, 0, 2);

            apduCmd = new APDUCommand(0, 0xa4, 2, 0, new byte[] { 0, 5 }, 0);
            apdu1   = iCard.Transmit(apduCmd);
            if (apdu1.SW1 != 0x90)
            {
                throw new Exception("Read NETS transaction fail");
            }

            //read the current log entry number
            short endOffs = (short)(logSize * 4);
            byte  endP1   = (byte)((endOffs >> 8) & 0xff);
            byte  endP2   = (byte)(endOffs & 0xff);

            apduCmd = new APDUCommand(0, 0xb0, endP1, endP2, null, 2);
            apdu1   = iCard.Transmit(apduCmd);
            if (apdu1.SW1 != 0x90)
            {
                throw new Exception("Read NETS current log number fail");
            }
            short currentLogNum = (short)ConvertBCDCardNumber(new byte[] { apdu1.Data[0], apdu1.Data[1] }, 0, 2);

            currentLogNum -= 2;

            //read each log entry from the ring buffer, starting from current
            for (byte n = 0; n < logSize; n++)
            {
                int i = currentLogNum - n;
                if (i < 0)
                {
                    i += logSize;
                }
                short logOffs = (short)(i * 4);
                byte  logP1   = (byte)((logOffs >> 8) & 0xff);
                byte  logP2   = (byte)(logOffs & 0xff);
                //read binary 0xb0, offset logOffs, size 16
                apduCmd = new APDUCommand(0, 0xb0, logP1, logP2, null, 16);
                apdu1   = iCard.Transmit(apduCmd);
                if (apdu1.SW1 != 0x90)
                {
                    throw new Exception("Read NETS log entry fail");
                }
                NETSTransaction logEntry = new NETSTransaction(apdu1.Data);
                if (logEntry.Type != 0)
                {
                    TransactionLog.Add(logEntry);
                }
            }
        }