diff --git a/NFC/Crypto/CipherKey.cs b/NFC/Crypto/CipherKey.cs
index 519ab2a..3280381 100644
--- a/NFC/Crypto/CipherKey.cs
+++ b/NFC/Crypto/CipherKey.cs
@@ -39,6 +39,17 @@ namespace NFC.Crypto
}
}
+ ///
+ /// Creates Key from String
+ ///
+ /// Key
+ /// Cipher for Key
+ /// Version of Key
+ public CipherKey(string key, CipherType cipher, byte keyVersion) : this(HexConverter.ConvertFromHexString(key), cipher, keyVersion)
+ {
+
+ }
+
///
/// Generates Empty Key
///
@@ -122,7 +133,7 @@ namespace NFC.Crypto
switch (cipher)
{
case CipherType.TDES:
- return 8;
+ return 16;
case CipherType.TDES_2K:
return 16;
case CipherType.TDES_3K:
diff --git a/NFC/NXP MIFARE DESFire/MIFARE_DESFire.cs b/NFC/NXP MIFARE DESFire/MIFARE_DESFire.cs
index 149d04e..5b053c3 100644
--- a/NFC/NXP MIFARE DESFire/MIFARE_DESFire.cs
+++ b/NFC/NXP MIFARE DESFire/MIFARE_DESFire.cs
@@ -7,6 +7,7 @@ using PCSC.Iso7816;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection;
namespace NFC.Mifare_DESFire
{
@@ -879,16 +880,32 @@ namespace NFC.Mifare_DESFire
INS = (byte)APDUInstructions.READ_DATA,
Data = Concatenate(data, offset_byte, length_byte)
};
- _Log.DebugFormat("APDU_CMD(cmd_ReadData): {0}", ConvertToHexString(cmd_ReadData.ToArray()));
- APDUResponse response = _Card.Transmit(cmd_ReadData);
- _Log.DebugFormat("APDU_RES(cmd_ReadData): {0}", ConvertToHexString(response.ToArray()));
+ APDUResponse response;
+ List read_data = new List();
- CheckAPDUResponse(response);
+ do
+ {
+ _Log.DebugFormat("APDU_CMD(cmd_ReadData): {0}", ConvertToHexString(cmd_ReadData.ToArray()));
+ response = _Card.Transmit(cmd_ReadData);
+ _Log.DebugFormat("APDU_RES(cmd_ReadData): {0}", ConvertToHexString(response.ToArray()));
+
+ if (response.SW1 == 0x91 && response.SW2 == 0xAF)
+ {
+ read_data.AddRange(response.Body);
+ }
+ else
+ {
+ CheckAPDUResponse(response);
+ }
+
+ cmd_ReadData.INS = 0xAF;
+ } while (response.SW1 == 0x91 && response.SW2 == 0xAF);
+
_Log.Debug("End ReadData");
- return response.Body;
+ return read_data.ToArray();
}
///
diff --git a/NFC_Test/FabAccess_OTA.cs b/NFC_Test/FabAccess_OTA.cs
new file mode 100644
index 0000000..80e580b
--- /dev/null
+++ b/NFC_Test/FabAccess_OTA.cs
@@ -0,0 +1,131 @@
+using NUnit.Framework;
+using NFC;
+using NFC.Readers.PCSC;
+using NFC.Mifare_DESFire;
+using NFC.Mifare_DESFire.Enums;
+using System;
+using System.Text;
+using NFC.Crypto;
+using System.Runtime.CompilerServices;
+using System.Drawing.Printing;
+
+namespace NFC_Test
+{
+ [TestFixture, Explicit]
+ public class FabAccess_OTA
+ {
+ private string _ReaderID = "ACS ACR122U PICC Interface 0";
+ private UInt32 _FabAccess_AID = 0x2A472D;
+ private byte _FabAccess_FID = 0x01;
+ private UInt32 _FabAccess_FSize = 0xF0;
+
+ private CipherKey _FabAccess_Card_MasterKey = new CipherKey("294A404E635266556A576E5A72347537", CipherType.AES, 0x10);
+ private CipherKey _FabAccess_Application_MasterKey = new CipherKey("50645367566B59703273357638792F42", CipherType.AES, 0x10);
+ private CipherKey _FabAccess_Application_AuthKey = new CipherKey("6D5A7134743677397A24432646294A40", CipherType.AES, 0x10);
+
+ private string _FabAccess_UserDomain = "thejoklla@fvm.fab-access.org";
+ private string _FabAccess_Domain = "fvm.fab-access.org";
+
+ private CipherKey _Default_DESKey = new CipherKey(CipherType.TDES);
+ private CipherKey _Default_AESKey = new CipherKey(CipherType.AES);
+
+ [Test]
+ public void Init_EmptyCard()
+ {
+ IHardware hardware = new Hardware();
+ IReader reader = hardware.OpenReader(_ReaderID);
+
+ bool transmit_successfully = false;
+
+ ReaderEventHandler handler = (sender, card) =>
+ {
+ card.Connect();
+
+ MIFARE_DESFire desfire = new MIFARE_DESFire(card);
+
+ desfire.SelectApplication(0x000000);
+ desfire.AuthenticateISO_DES(0x00, _Default_DESKey._Key);
+ desfire.Format();
+
+ desfire.AuthenticateISO_DES(0x00, _Default_DESKey._Key);
+
+ byte keySetting1 = desfire.GenerateKeySetting1(ChangeApplicationKey.MASTERKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.ONLYMASTERKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE);
+ byte keySetting2 = desfire.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 0x02);
+ desfire.CreateApplication(_FabAccess_AID, keySetting1, keySetting2);
+
+ desfire.SelectApplication(_FabAccess_AID);
+ desfire.AuthenticateISO_AES(0x00, _Default_DESKey._Key);
+
+ desfire.ChangeKey_AES(0x00, _FabAccess_Application_MasterKey._Key, _FabAccess_Application_MasterKey._KeyVersion);
+
+ desfire.AuthenticateISO_AES(0x00, _FabAccess_Application_MasterKey._Key);
+ desfire.ChangeOtherKey_AES(0x01, _FabAccess_Application_AuthKey._Key, _Default_AESKey._Key, _FabAccess_Application_AuthKey._KeyVersion);
+
+ UInt16 accesRights = desfire.GenerateFileAccessRights((byte)FileAccessRights.FREE, 0x00, 0x00, 0x00);
+ desfire.CreateFile_Standard(_FabAccess_FID, FileCommunication.PLAIN, accesRights, _FabAccess_FSize);
+
+ desfire.WriteData(0x01, 0, Encoding.ASCII.GetBytes(_FabAccess_UserDomain));
+
+ transmit_successfully = true;
+
+ card.Disconnect();
+ };
+
+ reader.CardDiscovered += handler;
+ reader.Start();
+
+ Assert.AreEqual(true, transmit_successfully);
+
+ reader.Stop();
+ reader.CardDiscovered -= handler;
+ }
+
+ [Test]
+ public void Authenticate()
+ {
+ IHardware hardware = new Hardware();
+ IReader reader = hardware.OpenReader(_ReaderID);
+
+ bool transmit_successfully = false;
+
+ ReaderEventHandler handler = (sender, card) =>
+ {
+ card.Connect();
+
+ MIFARE_DESFire desfire = new MIFARE_DESFire(card);
+
+ desfire.SelectApplication(_FabAccess_AID);
+ byte[] card_data = desfire.ReadData(_FabAccess_FID, 0x00, _FabAccess_FSize);
+ string userdomain = Encoding.ASCII.GetString(card_data).Replace("\u0000", "");
+
+ string domain = userdomain.Split('@')[1];
+ if(domain != _FabAccess_Domain)
+ {
+ throw new Exception("Incorrect Domain");
+ }
+
+ desfire.SelectApplication(_FabAccess_AID);
+ desfire.AuthenticateISO_AES(0x01, _FabAccess_Application_AuthKey._Key);
+
+ byte[] card_data_auth = desfire.ReadData(_FabAccess_FID, 0x00, _FabAccess_FSize);
+ string userdomain_auth = Encoding.ASCII.GetString(card_data).Replace("\u0000", "");
+ if(card_data_auth != card_data)
+ {
+ throw new Exception("Authentication failed");
+ }
+
+ transmit_successfully = true;
+
+ card.Disconnect();
+ };
+
+ reader.CardDiscovered += handler;
+ reader.Start();
+
+ Assert.AreEqual(true, transmit_successfully);
+
+ reader.Stop();
+ reader.CardDiscovered -= handler;
+ }
+ }
+}
diff --git a/NFC_Test/HexConverter_Test.cs b/NFC_Test/HexConverter_Test.cs
new file mode 100644
index 0000000..fba4be6
--- /dev/null
+++ b/NFC_Test/HexConverter_Test.cs
@@ -0,0 +1,34 @@
+using NFC;
+using NUnit.Framework;
+
+namespace NFC_Test
+{
+ public class HexConverter_Test
+ {
+ [Test]
+ public void ConvertFromHexString()
+ {
+ string s = "0180ff0a";
+
+ byte[] expected_s =
+ {
+ 0x01, 0x80, 0xFF, 0x0A
+ };
+
+ Assert.AreEqual(expected_s, HexConverter.ConvertFromHexString(s));
+ }
+
+ [Test]
+ public void ConvertToHexString()
+ {
+ byte[] s =
+ {
+ 0x01, 0x80, 0xFF, 0x0A
+ };
+
+ string expected_s = "0180ff0a";
+
+ Assert.AreEqual(expected_s, HexConverter.ConvertToHexString(s));
+ }
+ }
+}
diff --git a/NFC_Test/NXP MIFARE DESFire/Command_Card_Test.cs b/NFC_Test/NXP MIFARE DESFire/Command_Card_Test.cs
new file mode 100644
index 0000000..92e2c21
--- /dev/null
+++ b/NFC_Test/NXP MIFARE DESFire/Command_Card_Test.cs
@@ -0,0 +1,308 @@
+using NFC;
+using NFC.Crypto;
+using NFC.Mifare_DESFire;
+using NFC.Readers.PCSC;
+using NUnit.Framework;
+using NUnit.Framework.Constraints;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace NFC_Test.NXP_MIFARE_DESFire
+{
+ ///
+ /// Test all DESFire Commands with empty Card
+ ///
+ [Description("Test with real DESFire Card")]
+ [Explicit]
+ public class Command_Card_Test
+ {
+ public readonly string ReaderID = "";
+ public readonly UInt32 AID = 0xAAFFEE;
+ public readonly string AES_Key_Master = "25432A462D4A614E645267556B587032";
+ public readonly string AES_Key_1 = "50645367566B59703373367638792F42";
+
+ ///
+ /// Get ReaderIDs form PC/SC API
+ ///
+ [Test]
+ public void GetReaderIDs()
+ {
+ IHardware hardware = new Hardware();
+ string[] readers = hardware.GetReaders();
+
+ Console.WriteLine("Readers detected: {0}", readers.Length);
+
+ if (readers.Length > 0)
+ {
+ Console.WriteLine("List of ReaderIDs:");
+ foreach (string readerID in readers)
+ {
+ Console.WriteLine("{0}", readerID);
+ }
+ }
+ }
+
+ [Test]
+ public void Connect()
+ {
+ 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;
+ }
+
+ [Test]
+ public void Format()
+ {
+ IHardware hardware = new Hardware();
+ IReader reader = hardware.OpenReader(ReaderID);
+
+ bool test_successfully = false;
+
+ ReaderEventHandler handler = (sender, card) =>
+ {
+ card.Connect();
+
+ MIFARE_DESFire desfire = new MIFARE_DESFire(card);
+
+ desfire.Format();
+
+ test_successfully = true;
+
+ card.Disconnect();
+ };
+
+ reader.CardDiscovered += handler;
+ reader.Start();
+
+ Assert.AreEqual(true, test_successfully);
+
+ reader.Stop();
+ reader.CardDiscovered -= handler;
+ }
+
+ [Test]
+ public void SelectApplication()
+ {
+ IHardware hardware = new Hardware();
+ IReader reader = hardware.OpenReader(ReaderID);
+
+ bool test_successfully = false;
+
+ ReaderEventHandler handler = (sender, card) =>
+ {
+ card.Connect();
+
+ MIFARE_DESFire desfire = new MIFARE_DESFire(card);
+
+ desfire.SelectApplication(0x000000);
+
+ test_successfully = true;
+
+ card.Disconnect();
+ };
+
+ reader.CardDiscovered += handler;
+ reader.Start();
+
+ Assert.AreEqual(true, test_successfully);
+
+ reader.Stop();
+ reader.CardDiscovered -= handler;
+ }
+
+ [Test]
+ public void Authenticate_DES()
+ {
+ IHardware hardware = new Hardware();
+ IReader reader = hardware.OpenReader(ReaderID);
+
+ bool test_successfully = false;
+
+ ReaderEventHandler handler = (sender, card) =>
+ {
+ card.Connect();
+
+ MIFARE_DESFire desfire = new MIFARE_DESFire(card);
+
+ desfire.SelectApplication(0x000000);
+
+ CipherKey key = new CipherKey(CipherType.TDES);
+ desfire.AuthenticateISO_DES(0x00, key._Key);
+
+ test_successfully = true;
+
+ card.Disconnect();
+ };
+
+ reader.CardDiscovered += handler;
+ reader.Start();
+
+ Assert.AreEqual(true, test_successfully);
+
+ reader.Stop();
+ reader.CardDiscovered -= handler;
+ }
+
+
+ [Test]
+ public void CreateApplication()
+ {
+ IHardware hardware = new Hardware();
+ IReader reader = hardware.OpenReader(ReaderID);
+
+ bool test_successfully = false;
+
+ ReaderEventHandler handler = (sender, card) =>
+ {
+ card.Connect();
+
+ MIFARE_DESFire desfire = new MIFARE_DESFire(card);
+
+ CipherKey key = new CipherKey(CipherType.TDES);
+ desfire.AuthenticateISO_DES(0x00, key._Key);
+
+ byte keysetting1 = desfire.GenerateKeySetting1(NFC.Mifare_DESFire.Enums.ChangeApplicationKey.ALLKEYS, NFC.Mifare_DESFire.Enums.ChangeMasterKeySettings.WITHMASTERKEY, NFC.Mifare_DESFire.Enums.CreateDeleteFile.NOKEY, NFC.Mifare_DESFire.Enums.FileDirectoryAccess.NOKEY, NFC.Mifare_DESFire.Enums.ChangeMasterKey.CHANGEABLE);
+ byte keysetting2 = desfire.GenerateKeySetting2(NFC.Mifare_DESFire.Enums.CryptoOperationsType.AES, NFC.Mifare_DESFire.Enums.FileIdentifies.NOTUSED, 2);
+
+ desfire.CreateApplication(AID, keysetting1, keysetting2);
+
+ test_successfully = true;
+
+ card.Disconnect();
+ };
+
+ reader.CardDiscovered += handler;
+ reader.Start();
+
+ Assert.AreEqual(true, test_successfully);
+
+ reader.Stop();
+ reader.CardDiscovered -= handler;
+ }
+
+ [Test]
+ public void Authenticate_AES()
+ {
+ IHardware hardware = new Hardware();
+ IReader reader = hardware.OpenReader(ReaderID);
+
+ bool test_successfully = false;
+
+ ReaderEventHandler handler = (sender, card) =>
+ {
+ card.Connect();
+
+ MIFARE_DESFire desfire = new MIFARE_DESFire(card);
+
+ desfire.SelectApplication(AID);
+
+ CipherKey key = new CipherKey(CipherType.AES);
+ desfire.AuthenticateISO_AES(0x00, key._Key);
+
+ test_successfully = true;
+
+ card.Disconnect();
+ };
+
+ reader.CardDiscovered += handler;
+ reader.Start();
+
+ Assert.AreEqual(true, test_successfully);
+
+ reader.Stop();
+ reader.CardDiscovered -= handler;
+ }
+
+ [Test]
+ public void ChangeApplicationMasterKey()
+ {
+ IHardware hardware = new Hardware();
+ IReader reader = hardware.OpenReader(ReaderID);
+
+ bool test_successfully = false;
+
+ ReaderEventHandler handler = (sender, card) =>
+ {
+ card.Connect();
+
+ MIFARE_DESFire desfire = new MIFARE_DESFire(card);
+
+ desfire.SelectApplication(AID);
+
+ CipherKey key_default = new CipherKey(CipherType.AES);
+ desfire.AuthenticateISO_AES(0x00, key_default._Key);
+
+ CipherKey key = new CipherKey(AES_Key_Master, CipherType.AES, 0x10);
+ desfire.ChangeKey_AES(0x00, key._Key, key._KeyVersion);
+
+ test_successfully = true;
+
+ card.Disconnect();
+ };
+
+ reader.CardDiscovered += handler;
+ reader.Start();
+
+ Assert.AreEqual(true, test_successfully);
+
+ reader.Stop();
+ reader.CardDiscovered -= handler;
+ }
+
+ [Test]
+ public void ChangeApplicationKey_1()
+ {
+ IHardware hardware = new Hardware();
+ IReader reader = hardware.OpenReader(ReaderID);
+
+ bool test_successfully = false;
+
+ ReaderEventHandler handler = (sender, card) =>
+ {
+ card.Connect();
+
+ MIFARE_DESFire desfire = new MIFARE_DESFire(card);
+
+ desfire.SelectApplication(AID);
+
+ CipherKey key_master = new CipherKey(AES_Key_Master, CipherType.AES, 0x10);
+ desfire.AuthenticateISO_AES(0x00, key_master._Key);
+
+ CipherKey key_old = new CipherKey(AES_Key_1, CipherType.AES, 0x10);
+ CipherKey key_new = new CipherKey(AES_Key_1, CipherType.AES, 0x10);
+ desfire.ChangeOtherKey_AES(0x01, key_new._Key, key_old._Key, key_new._KeyVersion);
+
+ test_successfully = true;
+
+ card.Disconnect();
+ };
+
+ reader.CardDiscovered += handler;
+ reader.Start();
+
+ Assert.AreEqual(true, test_successfully);
+
+ reader.Stop();
+ reader.CardDiscovered -= handler;
+ }
+ }
+}
diff --git a/NFC_Test/NXP MIFARE DESFire/Command_Test.cs b/NFC_Test/NXP MIFARE DESFire/Command_Test.cs
new file mode 100644
index 0000000..f154e3f
--- /dev/null
+++ b/NFC_Test/NXP MIFARE DESFire/Command_Test.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace NFC_Test.NXP_MIFARE_DESFire
+{
+ class Command_Test
+ {
+ }
+}
diff --git a/NFC_Test/OTA.cs b/NFC_Test/OTA.cs
deleted file mode 100644
index 9e1cd36..0000000
--- a/NFC_Test/OTA.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-using NUnit.Framework;
-using NFC;
-using NFC.Readers.PCSC;
-using NFC.Mifare_DESFire;
-using NFC.Mifare_DESFire.Enums;
-using System;
-using System.Text;
-
-namespace NFC_Test
-{
- [TestFixture, Explicit]
- public class OTA
- {
- private string _ReaderID = "ACS ACR122U PICC Interface 0";
-
- [Test]
- public void Init()
- {
- IHardware hardware = new Hardware();
- IReader reader = hardware.OpenReader(_ReaderID);
-
- bool transmit_successfully = false;
-
- ReaderEventHandler handler = (sender, card) =>
- {
- card.Connect();
-
- MIFARE_DESFire desfire = new MIFARE_DESFire(card);
-
- desfire.SelectApplication(0x000000);
- desfire.AuthenticateISO_DES(0x00, desfire.GenerateEmptyKey(16));
- desfire.Format();
-
- desfire.AuthenticateISO_DES(0x00, desfire.GenerateEmptyKey(16));
-
- byte keySetting1 = desfire.GenerateKeySetting1(ChangeApplicationKey.MASTERKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.NOKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE);
- byte keySetting2 = desfire.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 0x03);
- desfire.CreateApplication(0xC0FFEE, keySetting1, keySetting2);
-
- desfire.SelectApplication(0xC0FFEE);
- desfire.AuthenticateISO_AES(0x00, desfire.GenerateEmptyKey(16));
-
- byte[] key_master = desfire.ConvertFromHexString("45eeb8338ae8f49a032e85bb11143530");
- byte[] key_1 = desfire.ConvertFromHexString("8db1f942f2d7cc82f6fa1486a30f8c12");
- byte[] key_2 = desfire.ConvertFromHexString("77611d170c449df6f294c48581ab315d");
- desfire.ChangeKey_AES(0x00, key_master, 0x10);
-
- desfire.AuthenticateISO_AES(0x00, key_master);
- desfire.ChangeOtherKey_AES(0x01, key_1, desfire.GenerateEmptyKey(16), 0x10);
-
- desfire.AuthenticateISO_AES(0x00, key_master);
- desfire.ChangeOtherKey_AES(0x02, key_2, desfire.GenerateEmptyKey(16), 0x10);
-
- UInt16 accesRights = desfire.GenerateFileAccessRights((byte)FileAccessRights.FREE, 0x00, 0x00, 0x00);
- desfire.CreateFile_Standard(0x01, FileCommunication.PLAIN, accesRights, 0x100);
-
- desfire.WriteData(0x01, 0, Encoding.ASCII.GetBytes("user@domain.org"));
-
- byte[] data = desfire.ReadData(0x01, 0, 32);
-
- Console.WriteLine(Encoding.ASCII.GetString(data));
-
- transmit_successfully = true;
-
- card.Disconnect();
- };
-
- reader.CardDiscovered += handler;
- reader.Start();
-
- Assert.AreEqual(true, transmit_successfully);
-
- reader.Stop();
- reader.CardDiscovered -= handler;
- }
- }
-}