From 2e68052008bef77b9b955429a63bbca94817508e Mon Sep 17 00:00:00 2001 From: TheJoKlLa Date: Thu, 17 Sep 2020 16:07:58 +0200 Subject: [PATCH] Added: GetApplication --- NFC/APDUCommand.cs | 56 +------------- NFC/APDUStatusWords.cs | 7 +- NFC/IReader.cs | 4 +- NFC/Mifare DESFire/MifareDESFire.cs | 111 ++++++++++++++++++++++++++++ NFC/Readers/PCSC/Card.cs | 13 +--- NFC/Readers/PCSC/Reader.cs | 6 +- NFC_Test/REAL_Windows.cs | 105 +++++++++++++++++++++++++- 7 files changed, 230 insertions(+), 72 deletions(-) create mode 100644 NFC/Mifare DESFire/MifareDESFire.cs diff --git a/NFC/APDUCommand.cs b/NFC/APDUCommand.cs index c568298..7a22e30 100644 --- a/NFC/APDUCommand.cs +++ b/NFC/APDUCommand.cs @@ -1,61 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Text; +using PCSC; +using PCSC.Iso7816; namespace NFC { - public class APDUCommand + public class APDUCommand : CommandApdu { - /// - /// ISO 7816 - CLA - Class - /// - public byte Class { get; set; } - - /// - /// ISO 7816 - INS - Instruction - /// - public byte Instruction { get; set; } - - /// - /// ISO 7816 - P1 - Parameter 1 - /// - public byte Parameter1 { get; set; } - - /// - /// ISO 7816 - P2 - Parameter 2 - /// - public byte Parameter2 { get; set; } - - /// - /// ISO 7816 - Lc - Length Command - /// - public byte LengthCommand + public APDUCommand(IsoCase isoCase) : base(isoCase, SCardProtocol.Any) { - get - { - throw new NotImplementedException(); - } - } - /// - /// ISO 7816 - Data - Data - /// - public byte[] Data { get; set; } - - /// - /// ISO 7816 - Le - Length expected - /// - public byte LengthExpected - { - get - { - throw new NotImplementedException(); - } - } - - public byte[] APDUCommandMessage() - { - throw new NotImplementedException(); } } } diff --git a/NFC/APDUStatusWords.cs b/NFC/APDUStatusWords.cs index b0680cd..a9c4bd8 100644 --- a/NFC/APDUStatusWords.cs +++ b/NFC/APDUStatusWords.cs @@ -204,6 +204,11 @@ namespace NFC.Mifare_DESFire /// /// Kommando erfolgreich ausgeführt /// - SUCCESS = 0x9000, + SUCCESS = 0x9000, + + /// + /// OK + /// + OK = 0x9100, } } diff --git a/NFC/IReader.cs b/NFC/IReader.cs index d068f9e..447a543 100644 --- a/NFC/IReader.cs +++ b/NFC/IReader.cs @@ -41,9 +41,9 @@ namespace NFC /// event ReaderEventHandler CardLost; - void start(); + void Start(); - void stop(); + void Stop(); } public interface ICard diff --git a/NFC/Mifare DESFire/MifareDESFire.cs b/NFC/Mifare DESFire/MifareDESFire.cs new file mode 100644 index 0000000..f6b5287 --- /dev/null +++ b/NFC/Mifare DESFire/MifareDESFire.cs @@ -0,0 +1,111 @@ +using PCSC.Iso7816; +using System; +using System.Collections.Generic; +using System.Text; + +namespace NFC.Mifare_DESFire +{ + public class MifareDESFire + { + /// + /// Create new Application with AID + /// + /// Appilication ID + public APDUCommand CreateApplication(UInt64 aid) + { + throw new NotImplementedException(); + } + + public APDUCommand GetApplicationIDs() + { + APDUCommand cmd = new APDUCommand(IsoCase.Case2Short) + { + CLA = 0x90, + INS = (byte)APDUInstructions.GET_APPLICATION_IDS + }; + + return cmd; + } + + public UInt32[] ConvertApplicationIDs(APDUResponse response) + { + if(response.Body.Length % 3 != 0) + { + throw new Exception("Invalid Body Length."); + } + + List applicationIDs = new List(); + + for(int i = 0; i < response.Body.Length; i += 3) + { + UInt32 new_applicationID = 0; + new_applicationID = (UInt32)((response.Body[i] << 16) + (response.Body[i + 1] << 8) + response.Body[i + 2]); + applicationIDs.Add(new_applicationID); + } + + return applicationIDs.ToArray(); + } + + /// + /// Select Application by ID + /// + /// 3 Byte ID + public APDUCommand SelectApplication(UInt32 id) + { + byte[] id_byte = BitConverter.GetBytes(id); + + APDUCommand cmd = new APDUCommand(IsoCase.Case4Short) + { + CLA = 0x90, + INS = (byte)APDUInstructions.SELECT_APPLICATION, + Data = new byte[] + { + id_byte[0], + id_byte[1], + id_byte[2] + }, + Le = 0x00 + }; + + return cmd; + } + + /// + /// Select Application by ID + /// + /// 3 Byte ID + public APDUCommand CreateApplication(UInt32 id) + { + byte[] id_byte = BitConverter.GetBytes(id); + + APDUCommand cmd = new APDUCommand(IsoCase.Case4Short) + { + CLA = 0x90, + INS = (byte)APDUInstructions.CREATE_APPLICATION, + Data = new byte[] + { + id_byte[0], + id_byte[1], + id_byte[2] + }, + Le = 0x00 + }; + + return cmd; + } + + public byte GenerateKeySetting1() + { + return 0x00; + } + + /// + /// + /// + public enum ChangeKey : byte + { + MASTERKEY = 0x00, + + } + } +} diff --git a/NFC/Readers/PCSC/Card.cs b/NFC/Readers/PCSC/Card.cs index cd70e1b..4b38a7a 100644 --- a/NFC/Readers/PCSC/Card.cs +++ b/NFC/Readers/PCSC/Card.cs @@ -31,18 +31,7 @@ namespace NFC.Readers.PCSC public CommandApdu Convert(APDUCommand apdu_cmd) { - CommandApdu apdu = new CommandApdu(IsoCase.Case2Short, _ISOReader.ActiveProtocol) - { - CLA = apdu_cmd.Class, - INS = apdu_cmd.Instruction, - P1 = apdu_cmd.Parameter1, - P2 = apdu_cmd.Parameter2, - - Data = apdu_cmd.Data, - - Le = apdu_cmd.LengthExpected - }; - + CommandApdu apdu = (CommandApdu)apdu_cmd; return apdu; } diff --git a/NFC/Readers/PCSC/Reader.cs b/NFC/Readers/PCSC/Reader.cs index d3e9686..dfb440d 100644 --- a/NFC/Readers/PCSC/Reader.cs +++ b/NFC/Readers/PCSC/Reader.cs @@ -25,10 +25,10 @@ namespace NFC.Readers.PCSC public void Dispose() { - stop(); + Stop(); } - public void start() + public void Start() { _ContextFactory = ContextFactory.Instance; _SCardContext = _ContextFactory.Establish(SCardScope.System); @@ -40,7 +40,7 @@ namespace NFC.Readers.PCSC CardDiscovered?.Invoke(this, _Card); } - public void stop() + public void Stop() { CardLost?.Invoke(this, _Card); diff --git a/NFC_Test/REAL_Windows.cs b/NFC_Test/REAL_Windows.cs index f144ee8..fdb6f2f 100644 --- a/NFC_Test/REAL_Windows.cs +++ b/NFC_Test/REAL_Windows.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using System.Text; using NFC; using NFC.Readers.PCSC; +using System.Threading; +using NFC.Mifare_DESFire; namespace NFC_Test { @@ -13,7 +15,7 @@ namespace NFC_Test [Test] public void GetReaders() { - Hardware hardware = new Hardware(); + IHardware hardware = new Hardware(); string[] readers = hardware.GetReaders(); Console.WriteLine("Readers detected: {0}", readers.Length); @@ -28,10 +30,109 @@ namespace NFC_Test } } - [TestCase("")] + [TestCase("ACS ACR122U PICC Interface 0")] public void Connect(string readerID) { + IHardware hardware = new Hardware(); + IReader reader = hardware.OpenReader(readerID); + bool connected_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + connected_successfully = true; + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, connected_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; + } + + [TestCase("ACS ACR122U PICC Interface 0")] + public void GetApplicationIDs(string readerID) + { + IHardware hardware = new Hardware(); + IReader reader = hardware.OpenReader(readerID); + + bool transmit_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + MifareDESFire desfire = new MifareDESFire(); + + APDUCommand cmd = desfire.GetApplicationIDs(); + + APDUResponse response = card.Transmit(cmd); + + if (response.StatusWord == NFC.Mifare_DESFire.APDUStatusWords.OK) + { + UInt32[] ApplicationIDs = desfire.ConvertApplicationIDs(response); + + foreach(UInt32 id in ApplicationIDs) + { + Console.WriteLine("0x{0:X3}", id); + } + + transmit_successfully = true; + } + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, transmit_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; + } + + [TestCase("ACS ACR122U PICC Interface 0", (UInt32)0xC0FFEE)] + public void SelectApplication(string readerID, UInt32 applicationID) + { + IHardware hardware = new Hardware(); + IReader reader = hardware.OpenReader(readerID); + + bool transmit_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + MifareDESFire desfire = new MifareDESFire(); + + APDUCommand cmd = desfire.SelectApplication(applicationID); + + cmd.ToArray(); + + APDUResponse response = card.Transmit(cmd); + + if (response.StatusWord == NFC.Mifare_DESFire.APDUStatusWords.OK) + { + transmit_successfully = true; + } + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, transmit_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; } } }