diff --git a/NFC/Mifare DESFire/MifareDESFire.cs b/NFC/Mifare DESFire/MifareDESFire.cs
index f6b5287..2a1ab65 100644
--- a/NFC/Mifare DESFire/MifareDESFire.cs
+++ b/NFC/Mifare DESFire/MifareDESFire.cs
@@ -70,18 +70,34 @@ namespace NFC.Mifare_DESFire
return cmd;
}
+ public APDUCommand Authenticate_GetChallenge(byte keyid)
+ {
+ 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
+ };
+ }
+
///
- /// Select Application by ID
+ /// Delete Application by ID
///
/// 3 Byte ID
- public APDUCommand CreateApplication(UInt32 id)
+ public APDUCommand DeleteApplication(UInt32 id)
{
byte[] id_byte = BitConverter.GetBytes(id);
APDUCommand cmd = new APDUCommand(IsoCase.Case4Short)
{
CLA = 0x90,
- INS = (byte)APDUInstructions.CREATE_APPLICATION,
+ INS = (byte)APDUInstructions.DELETE_APPLICATION,
Data = new byte[]
{
id_byte[0],
@@ -94,18 +110,170 @@ namespace NFC.Mifare_DESFire
return cmd;
}
- public byte GenerateKeySetting1()
+ ///
+ /// Select Application by ID
+ ///
+ /// 3 Byte ID
+ public APDUCommand CreateApplication(UInt32 id, byte keysetting1, byte keysetting2)
{
- return 0x00;
+ 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],
+ keysetting1,
+ keysetting2
+ },
+ Le = 0x00
+ };
+
+ return cmd;
}
///
- ///
+ /// Genearte KeySetting1 for Application Settings or PICC Setting
///
- public enum ChangeKey : byte
+ public byte GenerateKeySetting1(ChangeApplicationKey changeKey, ChangeMasterKeySettings changeMasterKeySettings, CreateDeleteFile createDeleteFile, FileDirectoryAccess fileDirectoryAccess, ChangeMasterKey changeMasterKey)
{
+ return (byte)(((byte)changeKey << 4) | (byte)changeMasterKeySettings | (byte)createDeleteFile | (byte)fileDirectoryAccess | (byte)changeMasterKey);
+ }
+
+ ///
+ /// Genearte KeySetting1 for Application Settings or PICC Setting
+ ///
+ /// ID of Key for changing Application Keys
+ ///
+ public byte GenerateKeySetting1(byte changeKey, ChangeMasterKeySettings changeMasterKeySettings, CreateDeleteFile createDeleteFile, FileDirectoryAccess fileDirectoryAccess, ChangeMasterKey changeMasterKey)
+ {
+ if(changeKey < 0x01 || changeKey >= 0x0E)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+ return GenerateKeySetting1(changeKey, changeMasterKeySettings, createDeleteFile, fileDirectoryAccess, changeMasterKey);
+ }
+
+ ///
+ /// Genearte KeySetting2 for Application Creation
+ ///
+ /// Number of keys that can be stored within the application (0x01-0x0D)
+ ///
+ public byte GenerateKeySetting2(CryptoOperations cryptoOperations, FileIdentifies fileIdentifies, byte numberOfKeys)
+ {
+ if(numberOfKeys < 0x01 || numberOfKeys >= 0x0D)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ 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/MifareDESFire_Commands.cs b/NFC_Test/MifareDESFire_Commands.cs
new file mode 100644
index 0000000..79207bd
--- /dev/null
+++ b/NFC_Test/MifareDESFire_Commands.cs
@@ -0,0 +1,33 @@
+using NFC;
+using NFC.Mifare_DESFire;
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace NFC_Test
+{
+ [TestFixture]
+ public class MifareDESFire_Commands
+ {
+ private MifareDESFire _MifareDESFire;
+
+ [SetUp]
+ public void SetUp()
+ {
+ _MifareDESFire = new MifareDESFire();
+ }
+
+ [Test]
+ public void GetApplicationIDs()
+ {
+
+ }
+
+ [Test]
+ public void GenerateKeySetting1()
+ {
+ Assert.AreEqual(0xEF, _MifareDESFire.GenerateKeySetting1(MifareDESFire.ChangeApplicationKey.SAMEKEY, MifareDESFire.ChangeMasterKeySettings.WITHMASTERKEY, MifareDESFire.CreateDeleteFile.NOKEY, MifareDESFire.FileDirectoryAccess.NOKEY, MifareDESFire.ChangeMasterKey.CHANGEABLE));
+ }
+ }
+}
diff --git a/NFC_Test/REAL_Windows.cs b/NFC_Test/REAL_Windows.cs
index fdb6f2f..1ec7d56 100644
--- a/NFC_Test/REAL_Windows.cs
+++ b/NFC_Test/REAL_Windows.cs
@@ -134,5 +134,82 @@ namespace NFC_Test
reader.Stop();
reader.CardDiscovered -= handler;
}
+
+ [TestCase("ACS ACR122U PICC Interface 0", (UInt32)0xC0FFEE)]
+ public void DeleteApplication(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.DeleteApplication(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;
+ }
+
+ [TestCase("ACS ACR122U PICC Interface 0", (UInt32)0xC0FFEE)]
+ public void CreateApplication(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();
+
+ 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);
+
+ APDUCommand cmd = desfire.CreateApplication(applicationID, keysetting1, keysetting2);
+
+ Console.WriteLine(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;
+ }
}
}