Exemplo n.º 1
0
            public bool authenticate(byte[] key, byte block)
            {
                byte[] card_uid = uid();
                if (card_uid == null)
                {
                    return(false);
                }
                //Send authentication command
                byte[] d1 = new byte[] { 0xD4, 0x40, 0x01, 0x60, block, key[0], key[1], key[2], key[3], key[4], key[5],
                                         card_uid[0], card_uid[1], card_uid[2], card_uid[3] };
                APDUCommand a1 = new APDUCommand(0xFF, 0x00, 0x00, 0x00, d1, 0x0F);

                try{
                    APDUResponse r1 = this.iCard.Transmit(a1);
                }catch (System.Exception) {
                    return(false);
                }
                //Status code 61 05 is valid


                //Read response
                APDUCommand a2 = new APDUCommand(0xFF, 0xC0, 0x00, 0x00, null, 0x05);

                try{
                    APDUResponse r2 = this.iCard.Transmit(a2);
                }catch (System.Exception) {
                    return(false);
                }
                //Status code 90 00 is valid, else error
                return(true);
            }
Exemplo n.º 2
0
            public byte[] readBlock(byte block)
            {
                byte[]      d1 = new Byte[] { 0xD4, 0x40, 0x01, 0x30, block };
                APDUCommand a1 = new APDUCommand(0xFF, 0x00, 0x00, 0x00, d1, 0x05);

                try{
                    APDUResponse r1 = this.iCard.Transmit(a1);
                }catch (System.Exception) {
                    return(null);
                }
                //Status code 61 15

                APDUCommand  a2 = new APDUCommand(0xFF, 0xC0, 0x00, 0x00, null, 0x15);
                APDUResponse r2;

                try{
                    r2 = this.iCard.Transmit(a2);
                }catch (System.Exception) {
                    return(null);
                }

                //Status Code ??
                _connected = false;

                return(r2.Data);
            }
Exemplo n.º 3
0
        public async Task PutKeyAsync(DaplugKeySet key, byte mode = 0x81)
        {
            var putKeyCommandAPDUBytes = new List <byte> {
                0x80, 0xD8, key.Version, mode, 0x00
            };                                                                                   //header

            // Key version
            putKeyCommandAPDUBytes.Add(key.Version);


            //Add the keys to the command data
            var encKeyData = PrepareKeyToPutKeyCommand(key.EncKey, (byte)key.Usage, key.Access);

            putKeyCommandAPDUBytes.AddRange(encKeyData);

            var macKeyData = PrepareKeyToPutKeyCommand(key.MacKey, (byte)key.Usage, key.Access);

            putKeyCommandAPDUBytes.AddRange(macKeyData);

            var keKeyData = PrepareKeyToPutKeyCommand(key.DeKey, (byte)key.Usage, key.Access);

            putKeyCommandAPDUBytes.AddRange(keKeyData);

            var putKeyCommand = new APDUCommand(putKeyCommandAPDUBytes.ToArray());

            var response = await ExchangeAPDUAsync(putKeyCommand);

            if (!response.IsSuccessfulResponse)
            {
                throw new DaplugAPIException("Error: " + response.SW1 + response.SW2);
            }
        }
Exemplo n.º 4
0
        private byte[] invokeSmartcard()
        {
            //i blanked the commands, and parameters - i am not sure if i am allowed to publish them
            APDUCommand  apduEcard1 = new APDUCommand(0x00, 0x00, 04, 0x00, null, 0);
            APDUCommand  apduEcard2 = new APDUCommand(0x00, 0x00, 0, 0, null, 0);
            APDUCommand  apduEcard3 = new APDUCommand(0x00, 0x00, 00, 0x00, null, 255);
            APDUResponse apduResp;

            CardNative iCard = new CardNative();

            iCard.Connect(reader, SHARE.Shared, PROTOCOL.T0orT1); //connected
            // Ecard1
            byte[]    data1     = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
            APDUParam apduParam = new APDUParam();

            apduParam.Data = data1;
            apduEcard1.Update(apduParam);
            apduResp = iCard.Transmit(apduEcard1);
            // Ecard2
            apduParam.Data = new byte[] { 0x00, 0x00 };
            apduEcard2     = new APDUCommand(0x00, 0x00, 00, 0x0C, apduParam.Data, 0);
            apduEcard2.Update(apduParam);
            apduResp = iCard.Transmit(apduEcard2);
            // Ecard3
            apduParam.Data = new byte[] { 0 };
            apduEcard3     = new APDUCommand(0x00, 0x00, 00, 0x00, null, 255);
            apduResp       = iCard.Transmit(apduEcard3);
            return(apduResp.Data);
        }
Exemplo n.º 5
0
        public async Task CreateDirectoryAsync(ushort directoryId, byte deleteSelfAccessCondition, byte createDirAccessCondition, byte createFileAccessCondition)
        {
            //Check if this device has a FILE license
            await CheckLicencedOptionAsync(DaplugLicensing.FILE);


            var createDirCommandAPDUBytes = new List <byte> {
                0x80, 0xE0, 0x00, 0x00, 0x10
            };                                                                               //header

            var createDirCommandAPDUData = new List <byte> {
                0x62, 0x0E, 0x82, 0x02, 0x32, 0x21, 0x83, 0x02
            };

            createDirCommandAPDUData.AddRange(Helpers.UShortToByteArray(directoryId));

            createDirCommandAPDUData.AddRange(new List <byte> {
                0x8c, 0x04, 0x00, deleteSelfAccessCondition, createDirAccessCondition, createFileAccessCondition
            });

            createDirCommandAPDUBytes.AddRange(createDirCommandAPDUData);

            var createDirCommand = new APDUCommand(createDirCommandAPDUBytes.ToArray());

            var response = await ExchangeAPDUAsync(createDirCommand);

            if (!response.IsSuccessfulResponse)
            {
                throw new DaplugAPIException("An error ocurred while creating the directory.", response.SW1, response.SW2);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Считывает число из 4 байт карты
        /// </summary>
        private int ReadData()
        {
            APDUCommand  apduCmd2  = new APDUCommand(0xFF, 0xb0, 0x00, 0x01, null, 0x10);
            APDUResponse apduResp2 = _card.Transmit(apduCmd2);

            byte[] data = { apduResp2.Data[0], apduResp2.Data[1], apduResp2.Data[2], apduResp2.Data[3] };
            return(BitConverter.ToInt32(data, 0));
        }
Exemplo n.º 7
0
        public static byte[] EncryptAPDUData(DaplugSessionKeys keyset, APDUCommand apdu)
        {
            byte[] paddedData = AddPadding(apdu.CommandData);

            byte[] encryptedData = Crypto.TripleDESEncrypt(keyset.SEncKey, paddedData);

            return(encryptedData);
        }
Exemplo n.º 8
0
        public async Task <bool> HaltAsync()
        {
            var haltCommand = new byte[] { 0xD0, 0x52, 0x02, 0x00, 0x00 };

            var command = new APDUCommand(haltCommand);

            var response = await ExchangeAPDUAsync(command);

            return(response.IsSuccessfulResponse);
        }
Exemplo n.º 9
0
        public async Task <bool> UsbToHidAsync()
        {
            var usbToHidCommand = new byte[] { 0xD0, 0x52, 0x08, 0x01, 0x00 };

            var command = new APDUCommand(usbToHidCommand);

            var response = await ExchangeAPDUAsync(command);

            return(response.IsSuccessfulResponse);
        }
Exemplo n.º 10
0
        public bool disconnect()
        {
            APDUCommand  c1 = new APDUCommand(0xFF, 0x00, 0x00, 0x00, new byte[] { 0xD4, 0x44, 0x01 }, 0x03);
            APDUResponse r1 = iCard.Transmit(c1);

            APDUCommand  c2 = new APDUCommand(0xFF, 0xC0, 0x00, 0x00, null, 0x05);
            APDUResponse r2 = iCard.Transmit(c2);

            this.iCard.Disconnect(DISCONNECT.Reset);
            _connected = false;
            return(true);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Записывает число в 4 байта карты
        /// </summary>
        private int WriteData(int num)
        {
            byte[] numData = BitConverter.GetBytes(num);
            byte[] data    =
            {
                numData[0], numData[1], numData[2], numData[3], 0x00, 0x00, 0x00, numData[0], numData[1], numData[2],
                0x00,             0x00,       0x00,       0x00, 0x00, 0x00
            };
            APDUCommand  apduCmd4  = new APDUCommand(0xFF, 0xd6, 0x00, 0x01, data, 0x10);
            APDUResponse apduResp4 = _card.Transmit(apduCmd4);

            return(num);
        }
Exemplo n.º 12
0
            public byte[] readBlock(byte block)
            {
                //Read block
                APDUCommand cc3 = new APDUCommand(0xFF, 0xB0, 0x00, 0x08, null, 0x10);

                try{
                    APDUResponse rr3 = this.iCard.Transmit(cc3);
                    return(rr3.Data);
                }catch (System.Exception) {
                    Debug.WriteLine("ACR112_v2:: Transmit Error, " + cc3.ToString());
                    return(null);
                }
                return(null);
            }
Exemplo n.º 13
0
            public void select()
            {
                //Firmware
                //APDUCommand c_f = new APDUCommand( 0xFF, 0x00, 0x48, 0x00, null, 0x00);
                //APDUResponse r_f = this.iCard.Transmit(c_f);

                //Select?
                APDUCommand cc0 = new APDUCommand(0xFF, 0xCA, 0x00, 0x00, null, 0x04);

                try{
                    APDUResponse rr0 = this.iCard.Transmit(cc0);
                }catch (System.Exception) {
                    Debug.WriteLine("ACR112_v2:: Transmit Error, " + cc0.ToString());
                }
            }
Exemplo n.º 14
0
        public async Task <byte[]> GetSerialAsync()
        {
            var getSerialCommand = new byte[] { 0x80, 0xE6, 0x00, 0x00, 0x00 };

            var command = new APDUCommand(getSerialCommand);

            var response = await ExchangeAPDUAsync(command);

            if (!response.IsSuccessfulResponse)
            {
                throw new DaplugAPIException("Error: " + response.SW1 + response.SW2);
            }

            return(response.ResponseData);
        }
Exemplo n.º 15
0
        public async Task <DaplugStatus> GetStatusAsync()
        {
            var getStatusCommand = new byte[] { 0x80, 0xF2, 0x40, 0x00, 0x00 };

            var command = new APDUCommand(getStatusCommand);

            var response = await ExchangeAPDUAsync(command);

            if (!response.IsSuccessfulResponse)
            {
                throw new DaplugAPIException("Error: " + response.SW1 + response.SW2);
            }

            return((DaplugStatus)response.ResponseData[9]);
        }
Exemplo n.º 16
0
        public async Task DeleteFileOrDirAsync(ushort fileID)
        {
            var fileIDBytes = Helpers.UShortToByteArray(fileID);

            var deleteFileCommandBytes = new byte[] { 0x80, 0xE4, 0x00, 0x00, 0x02 };

            var command = new APDUCommand(deleteFileCommandBytes, fileIDBytes);

            var response = await ExchangeAPDUAsync(command);

            if (!response.IsSuccessfulResponse)
            {
                throw new DaplugAPIException("Unable to delete the file.", response.SW1, response.SW2);
            }
        }
Exemplo n.º 17
0
        public async Task <APDUResponse> SendApduAsync(APDUCommand command)
        {
            var response = await SendRawApduAsync(command);

            switch (response.SW1)
            {
            case 0x61:
                return(await SendRawApduAsync(new APDUCommand { Instruction = 0XC0, ExpectedLength = response.SW2 }));

            case 0x6c:
                command.ExpectedLength = response.SW2;
                return(await SendRawApduAsync(command));
            }

            return(response);
        }
Exemplo n.º 18
0
        public async Task <byte[]> SelectFileAsync(ushort fileID)
        {
            var fileIDBytes = Helpers.UShortToByteArray(fileID);

            var selectFileCommand = new byte[] { 0x80, 0xA4, 0x00, 0x00, 0x00 };

            var command = new APDUCommand(selectFileCommand, fileIDBytes);

            var response = await ExchangeAPDUAsync(command);

            if (!response.IsSuccessfulResponse)
            {
                throw new DaplugAPIException("Error selecting file.", response.SW1, response.SW2);
            }

            return(response.ResponseData);
        }
Exemplo n.º 19
0
            public void select()
            {
                //Make the request
                byte[] d1 = new byte[9] {
                    0xD4, 0x60, 0x01, 0x01, 0x20, 0x23, 0x11, 0x04, 0x10
                };
                APDUCommand  a1 = new APDUCommand(0xFF, 0x00, 0x00, 0x00, d1, 0x09);
                APDUResponse r1;

                try{
                    r1 = this.iCard.Transmit(a1);
                }catch (System.Exception) {
                    return;
                }
                //Retrieve the result
                APDUCommand  a2 = new APDUCommand(0XFF, 0xC0, 0x00, 0x00, null, r1.SW2);
                APDUResponse r2;

                try{
                    r2 = this.iCard.Transmit(a2);
                }catch (System.Exception) {
                    return;
                }
                int data_len = r2.Data.Length;


                //Exceptions: No tags found, tag type not mifare (Schema?) Wrong type of tag
                if (data_len == 3)
                {
                    return;
                }
                //Retrieve the UID from the data returned
                _uid = new byte[4];
                Array.Copy(r2.Data, data_len - 4, _uid, 0, 4);

                //Store card information
                _numCards = r2.Data[2];
                _tagType  = new Byte[] {
                    r2.Data[3],
                    r2.Data[4]
                };
                _tag = r2.Data[7];
            }
Exemplo n.º 20
0
        private async Task <List <byte> > ReadFileDataInternalAsync(ushort offset, byte length)
        {
            var offsetBytes = Helpers.UShortToByteArray(offset);

            //header
            var readDataCommandAPDUBytes = new List <byte> {
                0x80, 0xB0, offsetBytes[0], offsetBytes[1], (SessionKeys != null) ? (byte)0x00 : length
            };

            var command = new APDUCommand(readDataCommandAPDUBytes);

            var response = await ExchangeAPDUAsync(command);

            if (!response.IsSuccessfulResponse)
            {
                throw new DaplugAPIException("Error reading data: " + response.SW1 + response.SW2);
            }

            return(new List <byte>(response.ResponseData));
        }
Exemplo n.º 21
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;
            }
        }
Exemplo n.º 22
0
        private async Task WriteFileDataInternalAsync(ushort offset, List <byte> data, ushort seek, byte count)
        {
            var offsetBytes = Helpers.UShortToByteArray(offset);

            //header
            var writeDataCommandAPDUBytes = new List <byte> {
                0x80, 0xD6, offsetBytes[0], offsetBytes[1], (byte)count
            };

            //append data
            writeDataCommandAPDUBytes.AddRange(data.Skip(seek).Take(count));

            var command = new APDUCommand(writeDataCommandAPDUBytes);

            var response = await ExchangeAPDUAsync(command);

            if (!response.IsSuccessfulResponse)
            {
                throw new DaplugAPIException("Error writing data: " + response.SW1 + response.SW2);
            }
        }
Exemplo n.º 23
0
        private async Task <APDUResponse> SendRawApduAsync(APDUCommand command)
        {
            var commandToSend = new List <byte> {
                command.Class, command.Instruction, command.Parameter1, command.Parameter2
            };

            if (command.Data != null && command.Data.Length > 0)
            {
                commandToSend.Add((byte)command.Data.Length);
                commandToSend.AddRange(command.Data);
            }

            commandToSend.Add(command.ExpectedLength);

            byte[] response = null;
            try
            {
                response = await this.cardChip.TransmitCommandAsync(commandToSend.ToArray());
            }
            catch (Exception e)
            {
                throw new APDUException("Unable to transmit command", e);
            }
            if (response is null)
            {
                throw  new APDUException("Unable to get a response", command);
            }

            if (response.Length == 2)
            {
                return new APDUResponse {
                           SW1 = response[0], SW2 = response[1]
                }
            }
            ;
            return(new APDUResponse {
                Body = response.Take(response.Length - 2).ToArray(), SW1 = response[response.Length - 2], SW2 = response[response.Length - 1]
            });
        }
Exemplo n.º 24
0
            public bool authenticate(byte[] key, byte block)
            {
                //Load authentication
                APDUCommand cc1 = new APDUCommand(0xFF, 0x82, 0x00, 0x00, key, 0x06);

                try{
                    APDUResponse rr1 = this.iCard.Transmit(cc1);
                }catch (System.Exception) {
                    Debug.WriteLine("ACR112_v2:: Transmit Error, " + cc1.ToString());
                    return(false);
                }
                //Authenticate
                APDUCommand cc2 = new APDUCommand(0xFF, 0x86, 0x00, 0x00, new byte[] { 0x01, 0x00, block, 0x60, 0x00 }, 0x05);

                try{
                    APDUResponse rr2 = this.iCard.Transmit(cc2);
                }catch (System.Exception) {
                    Debug.WriteLine("ACR112_v2:: Transmit Error, " + cc2.ToString());
                    return(false);
                }
                return(true);
            }
Exemplo n.º 25
0
        public Task <APDUResponse> ExchangeAPDU(APDUCommand apdu)
        {
            int bytesWritten;
            var errorCode = daplugWriter.Write(apdu.ToByteArray(), 5000, out bytesWritten);

            if (errorCode != ErrorCode.None)
            {
                throw new DaplugCommunicationException("Error while sendind command: " + errorCode + ". " + UsbDevice.LastErrorString);
            }

            int bytesRead;

            byte[] readBuffer   = new byte[512];
            var    receiveError = daplugReader.Read(readBuffer, 1000, out bytesRead);

            if (receiveError != ErrorCode.None)
            {
                throw new DaplugCommunicationException("Error while receiving response: " + receiveError + ". " + UsbDevice.LastErrorString);
            }

            Array.Resize(ref readBuffer, bytesRead);

            APDUResponse response;

            //if response starts with 0x61, the next byte is the response length
            if (readBuffer[0] == 0x61)
            {
                byte[] responseData = new byte[readBuffer[1] + 2]; //we add 2 to the response length to account for the SW bytes
                Array.Copy(readBuffer, 2, responseData, 0, responseData.Length);
                response = new APDUResponse(responseData);
            }
            //else the response constains only the 2 SW bytes
            else
            {
                response = new APDUResponse(readBuffer);
            }
            return(Task.FromResult(response));
        }
Exemplo n.º 26
0
        public async Task <byte[]> GenerateRandomAsync(byte length)
        {
            if (length > MAX_IO_DATA_SIZE)
            {
                throw new ArgumentException("Length must be between 0 and " + MAX_IO_DATA_SIZE, "length");
            }

            var generateRandomCommandAPDUBytes = new byte[] { 0xD0, 0x24, 0x00, 0x00, length };

            // append <length> bytes to the command APDU so that Le matches the Lc
            generateRandomCommandAPDUBytes = generateRandomCommandAPDUBytes.Concat(new byte[length]).ToArray();

            var generateRandomCommand = new APDUCommand(generateRandomCommandAPDUBytes);

            var response = await ExchangeAPDUAsync(generateRandomCommand);

            if (!response.IsSuccessfulResponse)
            {
                throw new DaplugAPIException("An error ocurred while generating random bytes.", response.SW1, response.SW2);
            }

            return(response.ResponseData);
        }
Exemplo n.º 27
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);
            }
        }
Exemplo n.º 28
0
        private void ReadCard(object o)
        {
            UseHourglass(true);
            string selectedReader = o as string;

            UpdateStatusLabel("Reading card...");

            TreeView treeView = new TreeView();
            TreeNode cardNode = new TreeNode("Card");

            cardNode.ImageIndex         = 0;
            cardNode.SelectedImageIndex = 0;
            treeView.Nodes.Add(cardNode);

            // Tree nodes
            TreeNode      pseNode                = null;
            TreeNode      fciNode                = null;
            ASN1          fci                    = null;
            List <byte[]> pseIdentifiers         = new List <byte[]>();
            List <byte[]> applicationIdentifiers = new List <byte[]>();
            ASCIIEncoding encoding               = new ASCIIEncoding();
            APDUCommand   apdu                   = null;
            APDUResponse  response               = null;
            bool          pseFound               = false;

            if (!skipPSEToolStripMenuItem.Checked)
            {
                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)
                {
                    cardReader.Connect(selectedReader);

                    foreach (byte[] pse in pseIdentifiers)
                    {
                        apdu     = new APDUCommand(0x00, 0xA4, 0x04, 0x00, pse, (byte)pse.Length);
                        response = cardReader.Transmit(apdu);

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

                        // PSE application read found ok
                        if (response.SW1 == 0x90)
                        {
                            pseFound = true;

                            pseNode                    = new TreeNode(String.Format("Application {0}", encoding.GetString(pse)));
                            pseNode.ImageIndex         = 1;
                            pseNode.SelectedImageIndex = 1;
                            pseNode.Tag                = pse;
                            cardNode.Nodes.Add(pseNode);

                            fciNode                    = new TreeNode("File Control Information");
                            fciNode.ImageIndex         = 3;
                            fciNode.SelectedImageIndex = 3;
                            fciNode.Tag                = "fci";
                            pseNode.Nodes.Add(fciNode);

                            fci = new ASN1(response.Data);
                            AddRecordNodes(fci, fciNode);

                            byte sfi          = new ASN1(response.Data).Find(0x88).Value[0];
                            byte recordNumber = 0x01;
                            byte p2           = (byte)((sfi << 3) | 4);

                            TreeNode efDirNode = new TreeNode(String.Format("EF Directory - {0:X2}", sfi));
                            efDirNode.ImageIndex         = 2;
                            efDirNode.SelectedImageIndex = 2;
                            efDirNode.Tag = sfi;
                            pseNode.Nodes.Add(efDirNode);


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

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

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

                                if (response.Data != null)
                                {
                                    TreeNode recordNode = new TreeNode(String.Format("Record - {0:X2}", recordNumber));
                                    recordNode.ImageIndex         = 4;
                                    recordNode.SelectedImageIndex = 4;
                                    recordNode.Tag = recordNumber;
                                    efDirNode.Nodes.Add(recordNode);

                                    ASN1 aef = new ASN1(response.Data);
                                    AddRecordNodes(aef, recordNode);

                                    foreach (ASN1 appTemplate in aef)
                                    {
                                        // Check we really have an Application Template
                                        if (appTemplate.Tag[0] == 0x61)
                                        {
                                            applicationIdentifiers.Add(appTemplate.Find(0x4f).Value);
                                        }
                                    }
                                }

                                recordNumber++;
                            }
                        }

                        if (pseFound)
                        {
                            break;
                        }
                    }

                    cardReader.Disconnect();
                }

                // We couldn't read the AID's from the PSE, so we'll just try querying all ADI's we know about
                if (!pseFound)
                {
                    // From http://www.darkc0de.com/others/ChAP.py
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000003"));         // VISA
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000031010"));     // VISA Debit/Credit
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000003101001"));   // VISA Credit
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000003101002"));   // VISA Debit
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000032010"));     // VISA Electron
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000033010"));     // VISA Interlink
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000038010"));     // VISA Plus
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000003999910"));   // VISA ATM

                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000041010"));     // Mastercard
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000048010"));     // Cirrus
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000043060"));     // Maestro
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000050001"));     // Maestro UK
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A00000002401"));       // Self Service
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000025"));         // American Express
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000025010104"));   // American Express
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000025010701"));   // ExpressPay
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000291010"));     // Link

                    applicationIdentifiers.Add(Helpers.HexStringToBytes("B012345678"));         // Maestro TEST

                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000651010"));     // JCB
                }

                // Now lets process all of the AID's we found
                if (applicationIdentifiers.Count > 0)
                {
                    foreach (byte[] AID in applicationIdentifiers)
                    {
                        List <ApplicationFileLocator> applicationFileLocators = new List <ApplicationFileLocator>();
                        StringBuilder sb = new StringBuilder();

                        cardReader.Connect(selectedReader);

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

                        // Get response nescesary
                        if (response.SW1 == 0x61)
                        {
                            apdu     = new APDUCommand(0x00, 0xC0, 0x00, 0x00, null, response.SW2);
                            response = cardReader.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);
                            }

                            TreeNode applicationNode = new TreeNode(String.Format("Application {0}", sb.ToString()));
                            applicationNode.ImageIndex         = 1;
                            applicationNode.SelectedImageIndex = 1;
                            applicationNode.Tag = AID;
                            cardNode.Nodes.Add(applicationNode);

                            fciNode                    = new TreeNode("File Control Information");
                            fciNode.ImageIndex         = 3;
                            fciNode.SelectedImageIndex = 3;
                            fciNode.Tag                = "fci";
                            applicationNode.Nodes.Add(fciNode);

                            fci = new ASN1(response.Data);
                            AddRecordNodes(fci, fciNode);

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

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

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

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

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

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

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

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

                                TreeNode aipaflNode = new TreeNode("Application Interchange Profile - Application File Locator");
                                aipaflNode.ImageIndex         = 3;
                                aipaflNode.SelectedImageIndex = 3;
                                aipaflNode.Tag = "aip";
                                applicationNode.Nodes.Add(aipaflNode);

                                ASN1 aipafl = new ASN1(response.Data);
                                AddRecordNodes(aipafl, aipaflNode);

                                foreach (ApplicationFileLocator file in applicationFileLocators)
                                {
                                    int r  = file.FirstRecord;// +afl.OfflineRecords;     // We'll read SDA records too
                                    int lr = file.LastRecord;

                                    byte p2 = (byte)((file.SFI << 3) | 4);

                                    TreeNode efNode = new TreeNode(String.Format("Elementary File - {0:X2}", file.SFI));
                                    efNode.ImageIndex         = 2;
                                    efNode.SelectedImageIndex = 2;
                                    efNode.Tag = file.SFI;
                                    applicationNode.Nodes.Add(efNode);

                                    while (r <= lr)
                                    {
                                        apdu     = new APDUCommand(0x00, 0xB2, (byte)r, p2, null, 0x00);
                                        response = cardReader.Transmit(apdu);

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

                                        TreeNode recordNode = new TreeNode(String.Format(" Record - {0:X2}", r));

                                        if (r <= file.OfflineRecords)
                                        {
                                            recordNode.ImageIndex         = 5;
                                            recordNode.SelectedImageIndex = 5;
                                        }
                                        else
                                        {
                                            recordNode.ImageIndex         = 4;
                                            recordNode.SelectedImageIndex = 4;
                                        }

                                        recordNode.Tag = r;
                                        efNode.Nodes.Add(recordNode);

                                        ASN1 record = new ASN1(response.Data);
                                        AddRecordNodes(record, recordNode);

                                        r++;
                                    }
                                }

                                //IEnumerable<XElement> tags = tagsDocument.Descendants().Where(el => el.Name == "Tag");
                                //foreach (XElement element in tags)
                                //{
                                //    string tag = element.Attribute("Tag").Value;

                                //    // Only try GET_DATA on two byte tags
                                //    if (tag.Length == 4)
                                //    {
                                //        byte p1 = byte.Parse(tag.Substring(0, 2), NumberStyles.HexNumber);
                                //        byte p2 = byte.Parse(tag.Substring(2, 2), NumberStyles.HexNumber);

                                //        apdu = new APDUCommand(0x80, 0xCA, p1, p2, null, 0);
                                //        response = cardReader.Transmit(apdu);

                                //        if (response.SW1 == 0x90)
                                //        {
                                //            Debug.WriteLine(response.ToString());
                                //        }
                                //    }
                                //}

                                apdu     = new APDUCommand(0x80, 0xCA, 0x9f, 0x13, null, 0);
                                response = cardReader.Transmit(apdu);
                                Debug.WriteLine(response.ToString());
                                apdu     = new APDUCommand(0x80, 0xCA, 0x9f, 0x17, null, 0);
                                response = cardReader.Transmit(apdu);
                                Debug.WriteLine(response.ToString());
                                apdu     = new APDUCommand(0x80, 0xCA, 0x9f, 0x36, null, 0);
                                response = cardReader.Transmit(apdu);
                                Debug.WriteLine(response.ToString());
                            }
                            else
                            {
                                // Unexpected status word
                                UpdateStatusLabel(String.Format("Unexpected response from GET PROCESSING OPTIONS command: 0x{0:X2}{1:X2}", response.SW1, response.SW2));
                            }
                        }
                        else
                        {
                            // Unexpected status word
                            UpdateStatusLabel(String.Format("Unexpected response from SELECT command: 0x{0:X2}{1:X2}", response.SW1, response.SW2));
                        }

                        cardReader.Disconnect();
                    }
                }

                treeViewData.Invoke(new UpdateTreeViewDelegate(UpdateTreeView), new object[] { treeView });
            }
            catch (PCSCException ex)
            {
                UpdateStatusLabel(ex.Message);
                return;
            }
            finally
            {
                UseHourglass(false);
                UpdateStatusLabel("Ready");
            }
        }
Exemplo n.º 29
0
        public async Task <APDUResponse> ExchangeAPDUAsync(APDUCommand apdu)
        {
            var finalAPDU = new APDUCommand(apdu.ToByteArray());

            if (SessionKeys != null)
            {
                byte[] apduMac = null;

                if (SessionKeys.SecurityLevel.HasFlag(DaplugSecurityLevel.COMMAND_MAC))
                {
                    finalAPDU.InstructionClass |= 0x04;
                    var apduBytes = finalAPDU.ToByteArray();
                    apduBytes[4] += 0x08;
                    apduMac       = DaplugCrypto.CalculateApduMac(SessionKeys.CMacKey, apduBytes, SessionKeys.CMac);
                    Array.Copy(apduMac, 0, SessionKeys.CMac, 0, 8);
                }
                if ((apdu.InstructionClass == 0x80 && apdu.InstructionCode == 0x82) == false) // Do not encrypt EXTERNAL_AUTHENTICATE APDU
                {
                    if (SessionKeys.SecurityLevel.HasFlag(DaplugSecurityLevel.COMMAND_ENC))
                    {
                        finalAPDU.CommandData = DaplugCrypto.EncryptAPDUData(SessionKeys, apdu);
                    }
                }
                if (apduMac != null)
                {
                    finalAPDU.CommandData = finalAPDU.CommandData.Concat(apduMac).ToArray();
                }
            }

            Debug.WriteLine("=> " + BitConverter.ToString(finalAPDU.ToByteArray()));

            var response = await dongle.ExchangeAPDU(finalAPDU);


            if (SessionKeys != null && response.HasData)
            {
                byte[] responseMac = null;
                if (SessionKeys.SecurityLevel.HasFlag(DaplugSecurityLevel.RESPONSE_MAC))
                {
                    // extract MAC from the response (the last 8 bytes)
                    responseMac = new byte[8];
                    Array.Copy(response.ResponseData, response.ResponseData.Length - 8, responseMac, 0, 8);

                    //resize the response data to exclude the last 8 bytes (MAC)
                    var tmpData = response.ResponseData;
                    Array.Resize(ref tmpData, response.ResponseData.Length - 8);
                    response.ResponseData = tmpData;
                }

                if (SessionKeys.SecurityLevel.HasFlag(DaplugSecurityLevel.RESPONSE_DEC))
                {
                    response.ResponseData = DaplugCrypto.DecryptAPDUResponse(SessionKeys, response.ResponseData);
                }

                if (SessionKeys.SecurityLevel.HasFlag(DaplugSecurityLevel.RESPONSE_MAC))
                {
                    //construct MAC input
                    var apduCommandBytes = apdu.ToByteArray();
                    //command bytes + data length + data + sw1 & sw2
                    //var macInput = new byte[apduCommandBytes.Length + 1 + response.ResponseData.Length + 2];
                    byte[] macInput = apduCommandBytes.Concat(new byte[] { (byte)response.ResponseData.Length })
                                      .Concat(response.ResponseData).Concat(new byte[] { response.SW1, response.SW2 }).ToArray();

                    byte[] calculatedResponseMac = DaplugCrypto.CalculateApduMac(SessionKeys.RMacKey, macInput, SessionKeys.RMac, true);

                    if (calculatedResponseMac.SequenceEqual(responseMac) == false)
                    {
                        throw new DaplugAPIException("Secure Channel error: Invalid RMAC.");
                    }

                    Array.Copy(calculatedResponseMac, SessionKeys.RMac, 8);
                }
            }

            Debug.WriteLine("<= " + BitConverter.ToString(response.ToByteArray()));

            return(response);
        }
Exemplo n.º 30
0
 /// <summary>
 /// Загрузка ключа FFFFFFFFFFFF
 /// </summary>
 private void LoadKey()
 {
     byte[]       data     = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
     APDUCommand  apduCmd  = new APDUCommand(0xFF, 0x82, 0x20, 0x00, data, 0x06);
     APDUResponse apduResp = _card.Transmit(apduCmd);
 }
Exemplo n.º 31
0
        private void ReadCard(object o)
        {
            UseHourglass(true);
            string selectedReader = o as string;
            UpdateStatusLabel("Reading card...");

            TreeView treeView = new TreeView();
            TreeNode cardNode = new TreeNode("Card");
            cardNode.ImageIndex = 0;
            cardNode.SelectedImageIndex = 0;
            treeView.Nodes.Add(cardNode);

            // Tree nodes
            TreeNode pseNode = null;
            TreeNode fciNode = null;
            ASN1 fci = null;
            List<byte[]> pseIdentifiers = new List<byte[]>();
            List<byte[]> applicationIdentifiers = new List<byte[]>();
            ASCIIEncoding encoding = new ASCIIEncoding();
            APDUCommand apdu = null;
            APDUResponse response = null;
            bool pseFound = false;

            if (!skipPSEToolStripMenuItem.Checked)
            {
                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)
                {
                    cardReader.Connect(selectedReader);

                    foreach (byte[] pse in pseIdentifiers)
                    {
                        apdu = new APDUCommand(0x00, 0xA4, 0x04, 0x00, pse, (byte)pse.Length);
                        response = cardReader.Transmit(apdu);

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

                        // PSE application read found ok
                        if (response.SW1 == 0x90)
                        {
                            pseFound = true;

                            pseNode = new TreeNode(String.Format("Application {0}", encoding.GetString(pse)));
                            pseNode.ImageIndex = 1;
                            pseNode.SelectedImageIndex = 1;
                            pseNode.Tag = pse;
                            cardNode.Nodes.Add(pseNode);

                            fciNode = new TreeNode("File Control Information");
                            fciNode.ImageIndex = 3;
                            fciNode.SelectedImageIndex = 3;
                            fciNode.Tag = "fci";
                            pseNode.Nodes.Add(fciNode);

                            fci = new ASN1(response.Data);
                            AddRecordNodes(fci, fciNode);

                            byte sfi = new ASN1(response.Data).Find(0x88).Value[0];
                            byte recordNumber = 0x01;
                            byte p2 = (byte)((sfi << 3) | 4);

                            TreeNode efDirNode = new TreeNode(String.Format("EF Directory - {0:X2}", sfi));
                            efDirNode.ImageIndex = 2;
                            efDirNode.SelectedImageIndex = 2;
                            efDirNode.Tag = sfi;
                            pseNode.Nodes.Add(efDirNode);

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

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

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

                                if (response.Data != null)
                                {
                                    TreeNode recordNode = new TreeNode(String.Format("Record - {0:X2}", recordNumber));
                                    recordNode.ImageIndex = 4;
                                    recordNode.SelectedImageIndex = 4;
                                    recordNode.Tag = recordNumber;
                                    efDirNode.Nodes.Add(recordNode);

                                    ASN1 aef = new ASN1(response.Data);
                                    AddRecordNodes(aef, recordNode);

                                    foreach (ASN1 appTemplate in aef)
                                    {
                                        // Check we really have an Application Template
                                        if (appTemplate.Tag[0] == 0x61)
                                        {
                                            applicationIdentifiers.Add(appTemplate.Find(0x4f).Value);
                                        }
                                    }
                                }

                                recordNumber++;
                            }
                        }

                        if (pseFound)
                            break;
                    }

                    cardReader.Disconnect();
                }

                // We couldn't read the AID's from the PSE, so we'll just try querying all ADI's we know about
                if (!pseFound)
                {
                    // From http://www.darkc0de.com/others/ChAP.py
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000003"));         // VISA
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000031010"));     // VISA Debit/Credit
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000003101001"));   // VISA Credit
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000003101002"));   // VISA Debit
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000032010"));     // VISA Electron
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000033010"));     // VISA Interlink
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000038010"));     // VISA Plus
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000003999910"));   // VISA ATM

                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000041010"));     // Mastercard
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000048010"));     // Cirrus
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000043060"));     // Maestro
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000050001"));     // Maestro UK
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A00000002401"));       // Self Service
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000025"));         // American Express
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000025010104"));   // American Express
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000025010701"));   // ExpressPay
                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000291010"));     // Link

                    applicationIdentifiers.Add(Helpers.HexStringToBytes("B012345678"));         // Maestro TEST

                    applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000651010"));     // JCB
                }

                // Now lets process all of the AID's we found
                if (applicationIdentifiers.Count > 0)
                {
                    foreach (byte[] AID in applicationIdentifiers)
                    {
                        List<ApplicationFileLocator> applicationFileLocators = new List<ApplicationFileLocator>();
                        StringBuilder sb = new StringBuilder();

                        cardReader.Connect(selectedReader);

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

                        // Get response nescesary
                        if (response.SW1 == 0x61)
                        {
                            apdu = new APDUCommand(0x00, 0xC0, 0x00, 0x00, null, response.SW2);
                            response = cardReader.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);
                            }

                            TreeNode applicationNode = new TreeNode(String.Format("Application {0}", sb.ToString()));
                            applicationNode.ImageIndex = 1;
                            applicationNode.SelectedImageIndex = 1;
                            applicationNode.Tag = AID;
                            cardNode.Nodes.Add(applicationNode);

                            fciNode = new TreeNode("File Control Information");
                            fciNode.ImageIndex = 3;
                            fciNode.SelectedImageIndex = 3;
                            fciNode.Tag = "fci";
                            applicationNode.Nodes.Add(fciNode);

                            fci = new ASN1(response.Data);
                            AddRecordNodes(fci, fciNode);

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

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

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

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

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

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

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

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

                                TreeNode aipaflNode = new TreeNode("Application Interchange Profile - Application File Locator");
                                aipaflNode.ImageIndex = 3;
                                aipaflNode.SelectedImageIndex = 3;
                                aipaflNode.Tag = "aip";
                                applicationNode.Nodes.Add(aipaflNode);

                                ASN1 aipafl = new ASN1(response.Data);
                                AddRecordNodes(aipafl, aipaflNode);

                                foreach (ApplicationFileLocator file in applicationFileLocators)
                                {
                                    int r = file.FirstRecord;// +afl.OfflineRecords;     // We'll read SDA records too
                                    int lr = file.LastRecord;

                                    byte p2 = (byte)((file.SFI << 3) | 4);

                                    TreeNode efNode = new TreeNode(String.Format("Elementary File - {0:X2}", file.SFI));
                                    efNode.ImageIndex = 2;
                                    efNode.SelectedImageIndex = 2;
                                    efNode.Tag = file.SFI;
                                    applicationNode.Nodes.Add(efNode);

                                    while (r <= lr)
                                    {
                                        apdu = new APDUCommand(0x00, 0xB2, (byte)r, p2, null, 0x00);
                                        response = cardReader.Transmit(apdu);

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

                                        TreeNode recordNode = new TreeNode(String.Format(" Record - {0:X2}", r));

                                        if (r <= file.OfflineRecords)
                                        {
                                            recordNode.ImageIndex = 5;
                                            recordNode.SelectedImageIndex = 5;
                                        }
                                        else
                                        {
                                            recordNode.ImageIndex = 4;
                                            recordNode.SelectedImageIndex = 4;
                                        }

                                        recordNode.Tag = r;
                                        efNode.Nodes.Add(recordNode);

                                        ASN1 record = new ASN1(response.Data);
                                        AddRecordNodes(record, recordNode);

                                        r++;
                                    }
                                }

                                //IEnumerable<XElement> tags = tagsDocument.Descendants().Where(el => el.Name == "Tag");
                                //foreach (XElement element in tags)
                                //{
                                //    string tag = element.Attribute("Tag").Value;

                                //    // Only try GET_DATA on two byte tags
                                //    if (tag.Length == 4)
                                //    {
                                //        byte p1 = byte.Parse(tag.Substring(0, 2), NumberStyles.HexNumber);
                                //        byte p2 = byte.Parse(tag.Substring(2, 2), NumberStyles.HexNumber);

                                //        apdu = new APDUCommand(0x80, 0xCA, p1, p2, null, 0);
                                //        response = cardReader.Transmit(apdu);

                                //        if (response.SW1 == 0x90)
                                //        {
                                //            Debug.WriteLine(response.ToString());
                                //        }
                                //    }
                                //}

                                apdu = new APDUCommand(0x80, 0xCA, 0x9f, 0x13, null, 0);
                                response = cardReader.Transmit(apdu);
                                Debug.WriteLine(response.ToString());
                                apdu = new APDUCommand(0x80, 0xCA, 0x9f, 0x17, null, 0);
                                response = cardReader.Transmit(apdu);
                                Debug.WriteLine(response.ToString());
                                apdu = new APDUCommand(0x80, 0xCA, 0x9f, 0x36, null, 0);
                                response = cardReader.Transmit(apdu);
                                Debug.WriteLine(response.ToString());
                            }
                            else
                            {
                                // Unexpected status word
                                UpdateStatusLabel(String.Format("Unexpected response from GET PROCESSING OPTIONS command: 0x{0:X2}{1:X2}", response.SW1, response.SW2));
                            }
                        }
                        else
                        {
                            // Unexpected status word
                            UpdateStatusLabel(String.Format("Unexpected response from SELECT command: 0x{0:X2}{1:X2}", response.SW1, response.SW2));
                        }

                        cardReader.Disconnect();
                    }
                }

                treeViewData.Invoke(new UpdateTreeViewDelegate(UpdateTreeView), new object[] { treeView });
            }
            catch (PCSCException ex)
            {
                UpdateStatusLabel(ex.Message);
                return;
            }
            finally
            {
                UseHourglass(false);
                UpdateStatusLabel("Ready");
            }
        }
Exemplo n.º 32
0
 /// <summary>
 /// Авторизация карты
 /// </summary>
 private void Authorize()
 {
     byte[]       data      = { 0x01, 0x00, 0x01, 0x60, 0x00 };
     APDUCommand  apduCmd1  = new APDUCommand(0xFF, 0x86, 0x00, 0x00, data, 0x05);
     APDUResponse apduResp1 = _card.Transmit(apduCmd1);
 }