Esempio n. 1
0
        private void HandleMifareUL(ICardReader reader)
        {
            var mifare = new PcscSdk.MifareUltralight.AccessHandler(reader);

            StatusMessage?.Invoke("Handling as Mifare Ultralight");

            byte[] uid = mifare.GetUid();
            StatusMessage?.Invoke("UID: " + BitConverter.ToString(uid));
            Array.Resize(ref uid, uid.Length + 1);
            uid[uid.Length - 1] = 0xAA;
            NewTagUid?.Invoke(uid);

            byte[] infoData = mifare.Read(0);
            StatusMessage?.Invoke("CC: " + BitConverter.ToString(infoData.Skip(12).ToArray()));

            try
            {
                byte[] versionData = mifare.GetVersion();
                StatusMessage?.Invoke("Mifare Version: " + BitConverter.ToString(versionData));

                int capacity    = versionData[6] >> 1;
                int capacityMax = capacity;
                if ((versionData[6] & 1) == 1)
                {
                    capacityMax += 1;
                }
                capacity    = (int)Math.Pow(2, capacity);
                capacityMax = (int)Math.Pow(2, capacityMax);
                StatusMessage?.Invoke("Capacity is between " + capacity + " and " + capacityMax + " bytes");
            }
            catch (ApduFailedException e)
            {
                StatusMessage?.Invoke("Failed getting Mifare Version: " + e.Message);
            }

            byte identMagic    = infoData[12];
            byte identVersion  = infoData[13];
            int  identCapacity = infoData[14] * 8;
            int  major         = identVersion >> 4;
            int  minor         = identVersion & 0x0F;

            if (identMagic != 0xE1 || identVersion < 0x10)
            {
                throw new NfcHandlerException("Tag format is unsupported");
            }

            StatusMessage?.Invoke("Found Type 2 Tag version " + major + "." + minor + " with " + identCapacity + " bytes capacity.");

            if (ndefDataToWrite != null)
            {
                WriteNdefToMifareUL(mifare, ndefDataToWrite);
                ndefDataToWrite = null;
            }
            else
            {
                byte[] data = DumpMifareUL(mifare);
                ParseTLVData(data);
            }
        }
Esempio n. 2
0
        private void HandleMifareStandard(ICardReader reader)
        {
            var mifare = new PcscSdk.MifareStandard.AccessHandler(reader);

            StatusMessage?.Invoke("Handling as Mifare Standard 1K");

            byte[] uid = mifare.GetUid();
            StatusMessage?.Invoke("UID: " + BitConverter.ToString(uid));
            Array.Resize(ref uid, uid.Length + 1);
            uid[uid.Length - 1] = 0xBB;
            NewTagUid?.Invoke(uid);

            byte gpByte = InitAndGetGPMifareStandard(mifare);

            bool usesMad    = (gpByte & 0x80) != 0;
            bool multiApp   = (gpByte & 0x40) != 0;
            int  madVersion = gpByte & 0x03;

            StatusMessage?.Invoke("Uses MAD: " + usesMad + "; Multi App: " + multiApp + "; Version: " + madVersion);

            if (ndefDataToWrite != null)
            {
                WriteNdefToMifareStandard(mifare, ndefDataToWrite);
                ndefDataToWrite = null;
            }
            else
            {
                if (!usesMad)
                {
                    throw new NfcHandlerException("No MAD in use");
                }
                if (madVersion != 1)
                {
                    throw new NfcHandlerException("Unsupported MAD version: " + madVersion + " (Only version 1 is supported)");
                }

                byte[] data = DumpMifareStandard(mifare);
                ParseTLVData(data);
            }
        }
Esempio n. 3
0
        private void HandleHCEClient(ICardReader reader)
        {
            StatusMessage?.Invoke("Attemtping to talk to Android HCE device.");

            var selectCmd = new Iso7816.SelectCommand(FLAGCARRIER_HCE_AID, 0);
            var res       = reader.Transceive(selectCmd);

            if (res.SW == 0x6a82)
            {
                ErrorMessage?.Invoke("Device has no idea who we are.");
                return;
            }
            else if (!res.Succeeded)
            {
                ErrorMessage?.Invoke("Failed communicating with device: " + res.ToString());
                return;
            }

            StatusMessage?.Invoke("Connected to FlagCarrier HCE device!");

            byte[] challengeToken = new byte[32];
            random.NextBytes(challengeToken, 0, challengeToken.Length);

            var updateCmd = new Iso7816.UpdateBinaryCommand(challengeToken);

            res = reader.Transceive(updateCmd);

            if (res.SW == 0x6A82)
            {
                ErrorMessage?.Invoke("HCE Device does not have any data for us.");
                return;
            }

            if (!res.Succeeded)
            {
                ErrorMessage?.Invoke("Failed sending challenge token: " + res.ToString());
                return;
            }

            StatusMessage?.Invoke("Sent challenge token.");

            byte[]    ndefData = new byte[0];
            const int len      = 250;
            int       offset   = 0;

            do
            {
                var readCmd = new Iso7816.ReadBinaryCommand(len, offset);
                res = reader.Transceive(readCmd);

                if (!res.Succeeded)
                {
                    ErrorMessage?.Invoke("Failed reading data at " + offset + ": " + res.ToString());
                    return;
                }

                if (res.ResponseData == null || res.ResponseData.Length == 0)
                {
                    break;
                }

                Array.Resize(ref ndefData, ndefData.Length + res.ResponseData.Length);
                res.ResponseData.CopyTo(ndefData, offset);
                offset += res.ResponseData.Length;
            } while (res.ResponseData.Length == len);

            StatusMessage?.Invoke("Read " + ndefData.Length + " bytes of ndef data from device.");

            NdefMessage msg = NdefMessage.FromByteArray(ndefData);

            NewTagUid?.Invoke(challengeToken);
            ReceiveNdefMessage?.Invoke(msg);

            var eraseCmd = new Iso7816.EraseBinaryCommand();

            res = reader.Transceive(eraseCmd);

            if (!res.Succeeded)
            {
                ErrorMessage?.Invoke("Failed confirming transaction to device.");
            }
        }