diff --git a/NFC/Mifare DESFire/Enums/AccessRights.cs b/NFC/Mifare DESFire/Enums/AccessRights.cs new file mode 100644 index 0000000..0c91aa1 --- /dev/null +++ b/NFC/Mifare DESFire/Enums/AccessRights.cs @@ -0,0 +1,8 @@ +namespace NFC.Mifare_DESFire.Enums +{ + public enum AccessRights : byte + { + FREE = 0x0E, + NEVER = 0x0F + } +} diff --git a/NFC/Mifare DESFire/Enums/ChangeApplicationKey.cs b/NFC/Mifare DESFire/Enums/ChangeApplicationKey.cs new file mode 100644 index 0000000..18305e1 --- /dev/null +++ b/NFC/Mifare DESFire/Enums/ChangeApplicationKey.cs @@ -0,0 +1,21 @@ +namespace NFC.Mifare_DESFire.Enums +{ + /// + /// hold the Access Rights for changing application keys (Change Key command) + /// + public enum ChangeApplicationKey : byte + { + /// + /// Application master key authentication is necessary to change any key (default) + /// + MASTERKEY = 0x00, + /// + /// Authentication with the key to be changed (same Key#) is necessary to change a key + /// + SAMEKEY = 0x0E, + /// + /// All keys (except application master key, see Bit 0) within this application are frozen + /// + ALLKEYS = 0x0F + } +} diff --git a/NFC/Mifare DESFire/Enums/ChangeMasterKey.cs b/NFC/Mifare DESFire/Enums/ChangeMasterKey.cs new file mode 100644 index 0000000..ae16dd8 --- /dev/null +++ b/NFC/Mifare DESFire/Enums/ChangeMasterKey.cs @@ -0,0 +1,18 @@ +namespace NFC.Mifare_DESFire.Enums +{ + /// + /// codes whether the application master key is changeable + /// + public enum ChangeMasterKey : byte + { + /// + /// Application master key is not changeable anymore (frozen) + /// + FROZEN = 0x00, + + /// + /// Application master key is changeable (authentication with the current application master key necessary, default) + /// + CHANGEABLE = 0x01, + } +} diff --git a/NFC/Mifare DESFire/Enums/ChangeMasterKeySettings.cs b/NFC/Mifare DESFire/Enums/ChangeMasterKeySettings.cs new file mode 100644 index 0000000..75bae21 --- /dev/null +++ b/NFC/Mifare DESFire/Enums/ChangeMasterKeySettings.cs @@ -0,0 +1,19 @@ +namespace NFC.Mifare_DESFire.Enums +{ + /// + /// codes whether a change of the application master key settings is allowed + /// + public enum ChangeMasterKeySettings : byte + { + + /// + /// configuration not changeable anymore (frozen) + /// + FROZEN = 0x00, + + /// + /// this configuration is changeable if authenticated with the application master key (default) + /// + WITHMASTERKEY = 0x08 + } +} diff --git a/NFC/Mifare DESFire/Enums/CreateDeleteFile.cs b/NFC/Mifare DESFire/Enums/CreateDeleteFile.cs new file mode 100644 index 0000000..b50b7b8 --- /dev/null +++ b/NFC/Mifare DESFire/Enums/CreateDeleteFile.cs @@ -0,0 +1,18 @@ +namespace NFC.Mifare_DESFire.Enums +{ + /// + /// codes whether application master key authentication is needed before “Create File” / “Delete File” + /// + public enum CreateDeleteFile : byte + { + /// + /// “Create File”/ “Delete File”is permitted only with application master key authentication + /// + ONLYMASTERKEY = 0x00, + + /// + /// “Create File”/ “Delete File”is permitted also without application master key authentication (default) + /// + NOKEY = 0x04, + } +} diff --git a/NFC/Mifare DESFire/Enums/CryptoOperationsType.cs b/NFC/Mifare DESFire/Enums/CryptoOperationsType.cs new file mode 100644 index 0000000..d395466 --- /dev/null +++ b/NFC/Mifare DESFire/Enums/CryptoOperationsType.cs @@ -0,0 +1,12 @@ +namespace NFC.Mifare_DESFire.Enums +{ + /// + /// Crypto method of the application + /// + public enum CryptoOperationsType : byte + { + TDES = 0x00, + TKTDES = 0x40, + AES = 0x80, + } +} \ No newline at end of file diff --git a/NFC/Mifare DESFire/FileCommunication.cs b/NFC/Mifare DESFire/Enums/FileCommunication.cs similarity index 82% rename from NFC/Mifare DESFire/FileCommunication.cs rename to NFC/Mifare DESFire/Enums/FileCommunication.cs index efce035..47e976c 100644 --- a/NFC/Mifare DESFire/FileCommunication.cs +++ b/NFC/Mifare DESFire/Enums/FileCommunication.cs @@ -1,6 +1,6 @@ -namespace NFC.Mifare_DESFire +namespace NFC.Mifare_DESFire.Enums { - enum FileCommunication : byte + public enum FileCommunication : byte { /// /// "Plain communication" diff --git a/NFC/Mifare DESFire/Enums/FileDirectoryAccess.cs b/NFC/Mifare DESFire/Enums/FileDirectoryAccess.cs new file mode 100644 index 0000000..e2e9db4 --- /dev/null +++ b/NFC/Mifare DESFire/Enums/FileDirectoryAccess.cs @@ -0,0 +1,18 @@ +namespace NFC.Mifare_DESFire.Enums +{ + /// + /// codes whether application master key authentication is needed for file directory access + /// + public enum FileDirectoryAccess : byte + { + /// + /// Successful application master key authentication is required for executing the “Get FID List”, “Get File Settings”and “Get Key Settings”commands + /// + ONLYMASTERKEY = 0x00, + + /// + /// “Get FID List”, “Get File Settings” and “Get Key Settings” commands succeed independentlyof a preceding application master key authentication (default) + /// + NOKEY = 0x02, + } +} diff --git a/NFC/Mifare DESFire/Enums/FileIdentifies.cs b/NFC/Mifare DESFire/Enums/FileIdentifies.cs new file mode 100644 index 0000000..25873f1 --- /dev/null +++ b/NFC/Mifare DESFire/Enums/FileIdentifies.cs @@ -0,0 +1,11 @@ +namespace NFC.Mifare_DESFire.Enums +{ + /// + /// Indicates use of 2 byte ISO/IEC 7816-4 File Identifies for files within the Application + /// + public enum FileIdentifies : byte + { + NOTUSED = 0x00, + USED = 0x20 + } +} diff --git a/NFC/Mifare DESFire/MifareDESFire.cs b/NFC/Mifare DESFire/MifareDESFire.cs index 2a1ab65..14dd282 100644 --- a/NFC/Mifare DESFire/MifareDESFire.cs +++ b/NFC/Mifare DESFire/MifareDESFire.cs @@ -1,4 +1,5 @@ -using PCSC.Iso7816; +using NFC.Mifare_DESFire.Enums; +using PCSC.Iso7816; using System; using System.Collections.Generic; using System.Text; @@ -7,6 +8,13 @@ namespace NFC.Mifare_DESFire { public class MifareDESFire { + private ICard _Card; + + public MifareDESFire(ICard card) + { + _Card = card; + } + /// /// Create new Application with AID /// @@ -46,6 +54,16 @@ namespace NFC.Mifare_DESFire return applicationIDs.ToArray(); } + public void Format() + { + throw new NotImplementedException(); + } + + public void Authenticate(int v, byte[] aPP_MasterKey) + { + throw new NotImplementedException(); + } + /// /// Select Application by ID /// @@ -70,20 +88,9 @@ namespace NFC.Mifare_DESFire return cmd; } - public APDUCommand Authenticate_GetChallenge(byte keyid) + public void ChangeApplicationMasterKey(byte[] aPP_MasterKey) { - APDUCommand cmd = new APDUCommand(IsoCase.Case4Short) - { - CLA = 0x90, - INS = (byte)APDUInstructions., - Data = new byte[] - { - id_byte[0], - id_byte[1], - id_byte[2] - }, - Le = 0x00 - }; + throw new NotImplementedException(); } /// @@ -110,6 +117,11 @@ namespace NFC.Mifare_DESFire return cmd; } + public void ChangeApplicationKey(int v, byte[] aPP_Key_1) + { + throw new NotImplementedException(); + } + /// /// Select Application by ID /// @@ -136,6 +148,31 @@ namespace NFC.Mifare_DESFire return cmd; } + public void CreateFile(byte fabAccessIdentFileID, FileCommunication pLAIN, ushort fileAccessRight, int v) + { + throw new NotImplementedException(); + } + + public ushort GenerateFileAccessRight(AccessRights fREE, int v1, int v2, int v3) + { + throw new NotImplementedException(); + } + + public void WirteData(byte fabAccessIdentFileID, int v1, int v2, byte[] vs) + { + throw new NotImplementedException(); + } + + public void CreateFile(byte fabAccessIdentFileID, object plain, AccessRights fREE, int v1, int v2, int v3) + { + throw new NotImplementedException(); + } + + public byte[] ReadData(byte identFileID, int v1, int v2) + { + throw new NotImplementedException(); + } + /// /// Genearte KeySetting1 for Application Settings or PICC Setting /// @@ -163,7 +200,7 @@ namespace NFC.Mifare_DESFire /// /// Number of keys that can be stored within the application (0x01-0x0D) /// - public byte GenerateKeySetting2(CryptoOperations cryptoOperations, FileIdentifies fileIdentifies, byte numberOfKeys) + public byte GenerateKeySetting2(CryptoOperationsType cryptoOperations, FileIdentifies fileIdentifies, byte numberOfKeys) { if(numberOfKeys < 0x01 || numberOfKeys >= 0x0D) { @@ -172,108 +209,5 @@ namespace NFC.Mifare_DESFire return (byte)((byte)cryptoOperations | (byte)fileIdentifies | numberOfKeys); } - - /// - /// Crypto method of the application - /// - public enum CryptoOperations : byte - { - TDES = 0x00, - TKTDES = 0x40, - AES = 0x80, - } - - /// - /// Indicates use of 2 byte ISO/IEC 7816-4 File Identifies for files within the Application - /// - public enum FileIdentifies : byte - { - NOTUSED = 0x00, - USED = 0x20 - } - - /// - /// hold the Access Rights for changing application keys (Change Key command) - /// - public enum ChangeApplicationKey : byte - { - /// - /// Application master key authentication is necessary to change any key (default) - /// - MASTERKEY = 0x00, - /// - /// Authentication with the key to be changed (same Key#) is necessary to change a key - /// - SAMEKEY = 0x0E, - /// - /// All keys (except application master key, see Bit 0) within this application are frozen - /// - ALLKEYS = 0x0F - } - - /// - /// codes whether a change of the application master key settings is allowed - /// - public enum ChangeMasterKeySettings : byte - { - - /// - /// configuration not changeable anymore (frozen) - /// - FROZEN = 0x00, - - /// - /// this configuration is changeable if authenticated with the application master key (default) - /// - WITHMASTERKEY = 0x08 - } - - /// - /// codes whether application master key authentication is needed before “Create File” / “Delete File” - /// - public enum CreateDeleteFile : byte - { - /// - /// “Create File”/ “Delete File”is permitted only with application master key authentication - /// - ONLYMASTERKEY = 0x00, - - /// - /// “Create File”/ “Delete File”is permitted also without application master key authentication (default) - /// - NOKEY = 0x04, - } - - /// - /// codes whether application master key authentication is needed for file directory access - /// - public enum FileDirectoryAccess : byte - { - /// - /// Successful application master key authentication is required for executing the “Get FID List”, “Get File Settings”and “Get Key Settings”commands - /// - ONLYMASTERKEY = 0x00, - - /// - /// “Get FID List”, “Get File Settings” and “Get Key Settings” commands succeed independentlyof a preceding application master key authentication (default) - /// - NOKEY = 0x02, - } - - /// - /// codes whether the application master key is changeable - /// - public enum ChangeMasterKey : byte - { - /// - /// Application master key is not changeable anymore (frozen) - /// - FROZEN = 0x00, - - /// - /// Application master key is changeable (authentication with the current application master key necessary, default) - /// - CHANGEABLE = 0x01, - } } } diff --git a/NFC_Test/REAL_Windows.cs b/NFC_Test/REAL_Windows.cs index 1ec7d56..12f9701 100644 --- a/NFC_Test/REAL_Windows.cs +++ b/NFC_Test/REAL_Windows.cs @@ -6,6 +6,7 @@ using NFC; using NFC.Readers.PCSC; using System.Threading; using NFC.Mifare_DESFire; +using NFC.Mifare_DESFire.Enums; namespace NFC_Test { @@ -68,7 +69,7 @@ namespace NFC_Test { card.Connect(); - MifareDESFire desfire = new MifareDESFire(); + MifareDESFire desfire = new MifareDESFire(card); APDUCommand cmd = desfire.GetApplicationIDs(); @@ -110,7 +111,7 @@ namespace NFC_Test { card.Connect(); - MifareDESFire desfire = new MifareDESFire(); + MifareDESFire desfire = new MifareDESFire(card); APDUCommand cmd = desfire.SelectApplication(applicationID); @@ -147,7 +148,7 @@ namespace NFC_Test { card.Connect(); - MifareDESFire desfire = new MifareDESFire(); + MifareDESFire desfire = new MifareDESFire(card); APDUCommand cmd = desfire.DeleteApplication(applicationID); @@ -184,10 +185,10 @@ namespace NFC_Test { card.Connect(); - MifareDESFire desfire = new MifareDESFire(); + MifareDESFire desfire = new MifareDESFire(card); - byte keysetting1 = desfire.GenerateKeySetting1(MifareDESFire.ChangeApplicationKey.SAMEKEY, MifareDESFire.ChangeMasterKeySettings.WITHMASTERKEY, MifareDESFire.CreateDeleteFile.NOKEY, MifareDESFire.FileDirectoryAccess.NOKEY, MifareDESFire.ChangeMasterKey.CHANGEABLE); - byte keysetting2 = desfire.GenerateKeySetting2(MifareDESFire.CryptoOperations.AES, MifareDESFire.FileIdentifies.NOTUSED, 0x01); + byte keysetting1 = desfire.GenerateKeySetting1(ChangeApplicationKey.SAMEKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.NOKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE); + byte keysetting2 = desfire.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 0x01); APDUCommand cmd = desfire.CreateApplication(applicationID, keysetting1, keysetting2); diff --git a/NFC_Test/REAL_Windows_CardSetUp.cs b/NFC_Test/REAL_Windows_CardSetUp.cs new file mode 100644 index 0000000..67b9061 --- /dev/null +++ b/NFC_Test/REAL_Windows_CardSetUp.cs @@ -0,0 +1,191 @@ +using NFC; +using NFC.Mifare_DESFire; +using NFC.Mifare_DESFire.Enums; +using NFC.Readers.PCSC; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Text; + +namespace NFC_Test +{ + [TestFixture] + public class REAL_Windows_CardSetUp + { + public static UInt32 FabAccessAID = 0x001100; + public static string CardReaderID = "ACS ACR122U PICC Interface 0"; + public static byte[] PICC_MasterKey = new byte[] + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + public static byte[] APP_MasterKey = new byte[] + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + public static byte[] APP_Key_1 = new byte[] + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + public static byte[] APP_Key_2 = new byte[] + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + public static byte[] Empty_Key = new byte[] + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + public static byte FabAccessIdentFileID = 0x01; + public static string UserDomain = "user1@fabaccess.org"; + + [Test] + public void ResetCard() + { + IHardware hardware = new Hardware(); + IReader reader = hardware.OpenReader(CardReaderID); + + bool connected_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + MifareDESFire mifareDESFire = new MifareDESFire(card); + + mifareDESFire.Authenticate(0x01, APP_MasterKey); + + mifareDESFire.Format(); + + connected_successfully = true; + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, connected_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; + } + + [Test] + public void ProvisionCard() + { + IHardware hardware = new Hardware(); + IReader reader = hardware.OpenReader(CardReaderID); + + bool connected_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + MifareDESFire mifareDESFire = new MifareDESFire(card); + + mifareDESFire.Authenticate(0x01, APP_MasterKey); + mifareDESFire.CreateApplication(FabAccessAID); + mifareDESFire.SelectApplication(FabAccessAID); + + mifareDESFire.Authenticate(0x00, Empty_Key); + mifareDESFire.ChangeApplicationMasterKey(APP_MasterKey); + + mifareDESFire.Authenticate(0x00, APP_MasterKey); + mifareDESFire.ChangeApplicationKey(0x01, APP_Key_1); + + connected_successfully = true; + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, connected_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; + } + + + [Test] + public void SetUpUserCard() + { + IHardware hardware = new Hardware(); + IReader reader = hardware.OpenReader(CardReaderID); + + bool connected_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + MifareDESFire mifareDESFire = new MifareDESFire(card); + + mifareDESFire.SelectApplication(FabAccessAID); + mifareDESFire.Authenticate(0x00, Empty_Key); + UInt16 fileAccessRight = mifareDESFire.GenerateFileAccessRight(AccessRights.FREE, 0x00, 0x00, 0x00); + mifareDESFire.CreateFile(FabAccessIdentFileID, FileCommunication.PLAIN, fileAccessRight, (UInt32)0x90); + + System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); + + mifareDESFire.WirteData(FabAccessIdentFileID, 0x00000000, 0x00000000, enc.GetBytes(UserDomain)); + + connected_successfully = true; + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, connected_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; + } + + [Test] + public void AuthenticateCard() + { + IHardware hardware = new Hardware(); + IReader reader = hardware.OpenReader(CardReaderID); + + bool connected_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + MifareDESFire mifareDESFire = new MifareDESFire(card); + + mifareDESFire.SelectApplication(FabAccessAID); + byte[] filedata = mifareDESFire.ReadData(FabAccessIdentFileID, 0x00000000, 0x00000000); + + System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); + string userdomain = enc.GetString(filedata); + + Console.WriteLine(userdomain); + + mifareDESFire.Authenticate(0x01, APP_Key_1); + + connected_successfully = true; + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, connected_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; + } + } +}