Exemple #1
0
        internal static FreefareTag Build(IntPtr ptrTag, bool dispose, NfcDevice device, NfcTarget target)
        {
            TagType type = NativeMethods.freefare_get_tag_type(ptrTag);

            Console.WriteLine("  type={0}", type);

            FreefareTag tag;

            switch (type)
            {
            case TagType.NTAG_21x:
                tag = new NTAG21xTag(ptrTag, dispose, device, target);
                Console.WriteLine("  subtype={0}", ((NTAG21xTag)tag).SubType);
                break;

            case TagType.MIFARE_CLASSIC_1K:
                tag = new MifareClassic1kTag(ptrTag, dispose, device, target);
                break;

            case TagType.MIFARE_CLASSIC_4K:
                tag = new MifareClassic4kTag(ptrTag, dispose, device, target);
                break;

            //TODO other tag types
            default:
                tag = new GenericTag(ptrTag, dispose, device, target);
                break;
            }
            return(tag);
        }
Exemple #2
0
 internal FreefareTag(IntPtr ptr, bool dispose, NfcDevice device, NfcTarget target)
 {
     this.m_ptr     = ptr;
     this.m_dispose = dispose;
     this.m_device  = device;
     this.m_target  = target;
 }
        internal NTAG21xTag(IntPtr ptr, bool dispose, NfcDevice device, NfcTarget target) : base(ptr, dispose, device, target)
        {
            int code = NativeMethods.ntag21x_get_info(ptr);

            if (code < 0)
            {
                throw new FreefareException(string.Format("Can't read tag info. ret={0} lastError={1}", code, this.LastError()));
            }
        }
        public static void MainSelfLibNfc(string[] args)
        {
            Console.WriteLine("Hello");
            Console.WriteLine("Using libnfc {0}", NfcContext.Version);

            //CancellationTokenSource cts = new CancellationTokenSource();
            //Console.CancelKeyPress += (s, e) =>
            //{
            //    if (cts.IsCancellationRequested)
            //    {
            //        //Hard break, let it go
            //    }
            //    else
            //    {
            //        //soft break, handle it
            //        e.Cancel = true;
            //        cts.Cancel();
            //    }
            //};

            byte pollNr      = 1;
            byte period      = 1;
            var  modulations = new[]
            {
                new NfcModulation(NfcModulationType.ISO14443A, NfcBaudRate.BR106),
                new NfcModulation(NfcModulationType.ISO14443B, NfcBaudRate.BR106),
                new NfcModulation(NfcModulationType.Felica, NfcBaudRate.BR212),
                new NfcModulation(NfcModulationType.Felica, NfcBaudRate.BR424),
                new NfcModulation(NfcModulationType.Jewel, NfcBaudRate.BR106),
            };

            Console.WriteLine("Opening libnfc context. sizeof(NfcModulation)={0}", Marshal.SizeOf <NfcModulation>());
            using (NfcContext context = new NfcContext())
            {
                string[] devices = context.ListDevices();
                Console.WriteLine("Found devices: [{0}]", string.Join(";", devices));
                Console.WriteLine("Opening default device");
                using (NfcDevice device = context.Open(null))
                {
                    Console.WriteLine("Device opened");
                    Console.WriteLine("  name={0} constring={1}", device.Name, device.ConnectionString);
                    Console.WriteLine("  info={0}", device.GetInfo());
                    Console.WriteLine("Initializing as initiator");
                    INfcInitiator initiator = device.InitInitiator(false);
                    Console.WriteLine("NFC reader opened");
                    Console.WriteLine("NFC reader name: {0}", device.Name);

                    while (true)
                    {
                        PollTagsAndDisplayInfo(initiator);
                    }
                }
            }
        }
        static async Task Main(string[] args)
        {
            Console.WriteLine("Using libnfc {0}", NfcContext.Version);

            CancellationTokenSource cts = new CancellationTokenSource();

            Console.CancelKeyPress += (s, e) =>
            {
                if (cts.IsCancellationRequested)
                {
                    //Hard break, let it go
                }
                else
                {
                    //soft break, handle it
                    e.Cancel = true;
                    cts.Cancel();
                }
            };

            byte pollNr      = 20;
            byte period      = 2;
            var  modulations = new[]
            {
                new NfcModulation(NfcModulationType.ISO14443A, NfcBaudRate.BR106),
                new NfcModulation(NfcModulationType.ISO14443B, NfcBaudRate.BR106),
                new NfcModulation(NfcModulationType.Felica, NfcBaudRate.BR212),
                new NfcModulation(NfcModulationType.Felica, NfcBaudRate.BR424),
                new NfcModulation(NfcModulationType.Jewel, NfcBaudRate.BR106),
            };

            using (NfcContext context = new NfcContext())
                using (NfcDevice device = context.Open(null))
                {
                    NfcInitiator initiator = device.InitInitiator(false);
                    Console.WriteLine("NFC reader: {0} opened", device.Name);
                    Console.WriteLine($"NFC device will poll during {pollNr * modulations.Length * period * 150}ms ({pollNr} pollings of {period * 150}ms for {modulations.Length} modulations)");

                    //NfcInitiatorTarget target = await initiator.PollAsync(modulations, pollNr, period);
                }
        }
Exemple #6
0
        public void NfcManager_ConnectAndDisconnectDevice()
        {
            var dummyAdapter = new DummyNfcAdapter();

            var bm     = new NfcManager(new[] { dummyAdapter }, null);
            var device = new NfcDevice
            {
                Id   = "some-device-id",
                Name = "Some-device-Uuid"
            };

            dummyAdapter.RaiseDeviceArriveddEvent(device);
            var devices = bm.GetDiscoveredDevices();

            devices.Count().ShouldBe(1);
            var d = devices.First();

            d.Name = device.Name;
            d.Id   = device.Id;

            dummyAdapter.RaiseDeviceDepartedEvent(device);
            devices = bm.GetDiscoveredDevices();
            devices.Count().ShouldBe(0);
        }
Exemple #7
0
 internal FreefareTagList(IntPtr ptr, NfcDevice device) : base(ptr, true)
 {
     this.m_device = device;
 }
Exemple #8
0
 public MifareClassic(NfcDevice device)
 {
     Device = device;
 }
Exemple #9
0
        static void Main(string[] args)
        {
            byte[] abtRawUid = new byte[12];
            byte[] abtAtqa   = new byte[2];
            byte   abtSak    = 0;

            byte[] abtAts          = new byte[MAX_FRAME_LEN];
            uint   szAts           = 0;
            bool   isoAtsSupported = false;
            bool   forceRats       = false;
            uint   szCL            = 1;

            try
            {
                using (var context = new NfcContext())
                    using (device = context.OpenDevice()) // Try to open the NFC reader
                    {
                        // Initialise NFC device as "initiator"
                        device.InitiatorInit();
                        // Configure the CRC
                        device.DeviceSetPropertyBool(NfcProperty.HandleCrc, false);
                        // Use raw send/receive methods
                        device.DeviceSetPropertyBool(NfcProperty.EasyFraming, false);
                        // Disable 14443-4 autoswitching
                        device.DeviceSetPropertyBool(NfcProperty.AutoIso14443_4, false);
                        WriteLine("NFC reader: {0} opened", device.Name);
                        WriteLine();
                        // Send the 7 bits request command specified in ISO 14443A (0x26)
                        TransmitBits(abtReqa, 7);
                        Array.Copy(abtRx, abtAtqa, 2);
                        // Anti-collision
                        TransmitBytes(abtSelectAll, 2);
                        // Check answer
                        if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0)
                        {
                            WriteLine("WARNING: BCC check failed!");
                        }
                        // Save the UID CL1
                        Array.Copy(abtRx, abtRawUid, 4);


                        //Prepare and send CL1 Select-Command
                        Array.Copy(abtRx, 0, abtSelectTag, 2, 5);
                        Iso14443aCrcAppend(abtSelectTag, 7);
                        TransmitBytes(abtSelectTag, 9);
                        abtSak = abtRx[0];

                        #region CL
                        // Test if we are dealing with a CL2
                        if ((abtSak & CASCADE_BIT) != 0)
                        {
                            szCL = 2; // or more
                                      // Check answer
                            if (abtRawUid[0] != 0x88)
                            {
                                WriteLine("WARNING: Cascade bit set but CT != 0x88!");
                            }
                        }

                        if (szCL == 2)
                        {
                            // We have to do the anti-collision for cascade level 2

                            // Prepare CL2 commands
                            abtSelectAll[0] = 0x95;

                            // Anti-collision
                            TransmitBytes(abtSelectAll, 2);

                            // Check answer
                            if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0)
                            {
                                WriteLine("WARNING: BCC check failed!");
                            }

                            // Save UID CL2
                            Array.Copy(abtRx, 0, abtRawUid, 4, 4);

                            // Selection
                            abtSelectTag[0] = 0x95;
                            Array.Copy(abtRx, 0, abtSelectTag, 2, 5);
                            Iso14443aCrcAppend(abtSelectTag, 7);
                            TransmitBytes(abtSelectTag, 9);
                            abtSak = abtRx[0];

                            // Test if we are dealing with a CL3
                            if ((abtSak & CASCADE_BIT) != 0)
                            {
                                szCL = 3;
                                // Check answer
                                if (abtRawUid[0] != 0x88)
                                {
                                    WriteLine("WARNING: Cascade bit set but CT != 0x88!");
                                }
                            }

                            if (szCL == 3)
                            {
                                // We have to do the anti-collision for cascade level 3

                                // Prepare and send CL3 AC-Command
                                abtSelectAll[0] = 0x97;
                                TransmitBytes(abtSelectAll, 2);

                                // Check answer
                                if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0)
                                {
                                    WriteLine("WARNING: BCC check failed!");
                                }

                                // Save UID CL3
                                Array.Copy(abtRx, 0, abtRawUid, 8, 4);

                                // Prepare and send final Select-Command
                                abtSelectTag[0] = 0x97;
                                Array.Copy(abtRx, 0, abtSelectTag, 2, 5);
                                Iso14443aCrcAppend(abtSelectTag, 7);
                                TransmitBytes(abtSelectTag, 9);
                                abtSak = abtRx[0];
                            }
                        }
                        #endregion

                        // Request ATS, this only applies to tags that support ISO 14443A-4
                        if ((abtRx[0] & SAK_FLAG_ATS_SUPPORTED) != 0)
                        {
                            isoAtsSupported = true;
                        }
                        if ((abtRx[0] & SAK_FLAG_ATS_SUPPORTED) != 0 || forceRats)
                        {
                            Iso14443aCrcAppend(abtRats, 2);
                            int szRx = TransmitBytes(abtRats, 4);
                            if (szRx >= 0)
                            {
                                Array.Copy(abtRx, abtAts, szRx);
                                szAts = (uint)szRx;
                            }
                        }

                        WriteLine();
                        WriteLine("驗證Block 0");
                        // 驗證 Block 0
                        Iso14443aCrcAppend(abtAuthA, 2);
                        TransmitBytes(abtAuthA, 4);
                        // 自己控制 Parity bit
                        device.DeviceSetPropertyBool(NfcProperty.HandleParity, false);

                        var nt  = abtRx.ToUInt32();
                        var uid = abtRawUid.ToUInt32();
                        Write("           Nt: ");
                        PrintHex(abtRx, 4);
                        var crapto1 = new Crypto1(0xFFFFFFFFFFFFu);
                        // 初始化 crapto1 狀態 feed in uid^nt and drop keystream in the first round
                        crapto1.Crypto1Word(uid ^ nt);
                        // 自訂讀卡機端nonce
                        var nr = 0x01020304u;
                        // Ar 為 suc2(nt)
                        var ar = PrngSuccessor(nt, 64);
                        // 加密 Nr,suc2(Nt) 和 parity bit
                        var enNrAr       = nr.GetBytes().Concat(ar.GetBytes()).ToArray();
                        var enNrArParity = new byte[8];
                        crapto1.Encrypt(enNrAr, enNrArParity, 0, 4, true);
                        crapto1.Encrypt(enNrAr, enNrArParity, 4, 4);
                        Write("[Nr,suc2(Nt)]: ");
                        PrintHex(enNrAr, 8);
                        // 送出[Nr,suc2(Nt)]
                        device.InitiatorTransceiveBits(enNrAr, 64, enNrArParity, abtRx, MAX_FRAME_LEN, null);
                        var enAt = new byte[4];
                        Array.Copy(abtRx, enAt, 4);
                        Write("   [suc3(Nt)]: ");
                        PrintHex(enAt, 4);
                        // 解密[at]
                        var at = enAt.ToUInt32() ^ crapto1.Crypto1Word();
                        WriteLine("At: {0:x8} == suc3(Nt):{1:x8}", at, PrngSuccessor(nt, 96));
                        // 讀取 Block
                        for (byte i = 0; i < 4; i++)
                        {
                            ReadBlock(crapto1, i);
                        }
                        WriteLine();
                        WriteLine("Nested驗證 Block 4");
                        // Nested驗證 Block 4
                        abtAuthA[1] = 4;
                        Iso14443aCrcAppend(abtAuthA, 2);
                        var enAuth       = abtAuthA.ToArray();
                        var enAuthParity = new byte[4];
                        crapto1.Encrypt(enAuth, enAuthParity, 0, 4);
                        device.InitiatorTransceiveBits(enAuth, 32, enAuthParity, abtRx, MAX_FRAME_LEN, null);

                        // 開始Nested驗證的新crypto1密鑰
                        crapto1 = new Crypto1(0xFFFFFFFFFFFFu);
                        Write("     未解密Nt: ");
                        PrintHex(abtRx, 4);
                        var enNt = abtRx.ToUInt32();
                        // 初始化 crapto1 狀態 用加密的Nt,並解出明文nt
                        nt = enNt ^ crapto1.Crypto1Word(uid ^ enNt, true);
                        Write("           Nt: ");
                        PrintHex(nt.GetBytes(), 4);
                        // 自訂讀卡機端nonce
                        nr = 0x01020304u;
                        // Ar 為 suc2(nt)
                        ar = PrngSuccessor(nt, 64);
                        // 加密 Nr,suc2(Nt) 和 parity bit
                        enNrAr       = nr.GetBytes().Concat(ar.GetBytes()).ToArray();
                        enNrArParity = new byte[8];
                        crapto1.Encrypt(enNrAr, enNrArParity, 0, 4, true);
                        crapto1.Encrypt(enNrAr, enNrArParity, 4, 4);
                        Write("[Nr,suc2(Nt)]: ");
                        PrintHex(enNrAr, 8);
                        // 送出[Nr,suc2(Nt)]
                        var res = device.InitiatorTransceiveBits(enNrAr, 64, enNrArParity, abtRx, MAX_FRAME_LEN, null);
                        enAt = new byte[4];
                        Array.Copy(abtRx, enAt, 4);
                        Write("   [suc3(Nt)]: ");
                        PrintHex(enAt, 4);
                        // 解密[at]
                        at = enAt.ToUInt32() ^ crapto1.Crypto1Word();
                        WriteLine("At: {0:x8} == suc3(Nt):{1:x8}", at, PrngSuccessor(nt, 96));

                        // 寫入 Block4
                        WriteBlock(crapto1, 4, new byte[16] {
                            65, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
                        });

                        // 讀取 Block
                        for (byte i = 4; i < 8; i++)
                        {
                            ReadBlock(crapto1, i);
                        }

                        WriteLine();

                        // device.DeviceSetPropertyBool(NfcProperty.HandleParity, true);
                        // Done, halt the tag now
                        Iso14443aCrcAppend(abtHalt, 2);
                        TransmitBytes(abtHalt, 4);
                    }
            }
            catch (Exception ex)
            {
                WriteLine(ex.Message);
                Environment.Exit(1);
            }
            WriteLine();
            WriteLine("Found tag with");
            Write(" UID: ");
            switch (szCL)
            {
            case 1:
                Write("{0:x2}{1:x2}{2:x2}{3:x2}", abtRawUid[0], abtRawUid[1], abtRawUid[2], abtRawUid[3]);
                break;

            case 2:
                Write("{0:x2}{1:x2}{2:x2}", abtRawUid[1], abtRawUid[2], abtRawUid[3]);
                Write("{0:x2}{1:x2}{2:x2}{3:x2}", abtRawUid[4], abtRawUid[5], abtRawUid[6], abtRawUid[7]);
                break;

            case 3:
                Write("{0:x2}{1:x2}{2:x2}", abtRawUid[1], abtRawUid[2], abtRawUid[3]);
                Write("{0:x2}{1:x2}{2:x2}", abtRawUid[5], abtRawUid[6], abtRawUid[7]);
                Write("{0:x2}{1:x2}{2:x2}{3:x2}", abtRawUid[8], abtRawUid[9], abtRawUid[10], abtRawUid[11]);
                break;
            }
            WriteLine();
            WriteLine("ATQA: {0:x2}{1:x2}", abtAtqa[1], abtAtqa[0]);
            WriteLine(" SAK: {0:x2}", abtSak);
            if (szAts > 1)
            { // if = 1, it's not actual ATS but error code
                if (forceRats && !isoAtsSupported)
                {
                    WriteLine(" RATS forced");
                }
                Write(" ATS: ");
                PrintHex(abtAts, szAts);
            }

            ReadLine();
        }
 internal MifareClassicTag(IntPtr ptr, bool dispose, NfcDevice device, NfcTarget target) : base(ptr, dispose, device, target)
 {
 }
Exemple #11
0
 public NfcDeviceEventArgs(NfcDevice device)
 {
     Device = device;
 }
 internal GenericTag(IntPtr ptr, bool dispose, NfcDevice device, NfcTarget target) : base(ptr, dispose, device, target)
 {
 }
Exemple #13
0
            internal void RaiseDeviceDepartedEvent(NfcDevice device)
            {
                var dea = new NfcDeviceEventArgs(device);

                DeviceDeparted(this, dea);
            }
Exemple #14
0
            internal void RaiseDeviceArriveddEvent(NfcDevice device)
            {
                var args = new NfcDeviceEventArgs(device);

                DeviceArrived(this, args);
            }
Exemple #15
0
 public ProxiedNfcDevice(INfcAdapter adapter, NfcDevice device)
 {
     Device  = device;
     Adapter = adapter;
 }