diff --git a/NFC.sln b/NFC.sln index c47b140..4cdbb32 100644 --- a/NFC.sln +++ b/NFC.sln @@ -5,6 +5,14 @@ VisualStudioVersion = 16.0.30717.126 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFC", "NFC\NFC.csproj", "{1D12BCDF-033F-40DE-ABA9-8BA5ABE0CA3A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFC_PCSC", "NFC_PCSC\NFC_PCSC.csproj", "{62DE4EBC-6F35-4D31-8717-DBC62D46035C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFC_Android", "NFC_Android\NFC_Android.csproj", "{B2609012-9D21-42F0-A2F9-3FE97D356392}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFC_iOS", "NFC_iOS\NFC_iOS.csproj", "{C56A1E1A-976C-42ED-B7A2-08C6111AA0E8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFC_Test", "NFC_Test\NFC_Test.csproj", "{FE8A1426-8B19-4CDF-A75E-80397E55BA95}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +23,22 @@ Global {1D12BCDF-033F-40DE-ABA9-8BA5ABE0CA3A}.Debug|Any CPU.Build.0 = Debug|Any CPU {1D12BCDF-033F-40DE-ABA9-8BA5ABE0CA3A}.Release|Any CPU.ActiveCfg = Release|Any CPU {1D12BCDF-033F-40DE-ABA9-8BA5ABE0CA3A}.Release|Any CPU.Build.0 = Release|Any CPU + {62DE4EBC-6F35-4D31-8717-DBC62D46035C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62DE4EBC-6F35-4D31-8717-DBC62D46035C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62DE4EBC-6F35-4D31-8717-DBC62D46035C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62DE4EBC-6F35-4D31-8717-DBC62D46035C}.Release|Any CPU.Build.0 = Release|Any CPU + {B2609012-9D21-42F0-A2F9-3FE97D356392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2609012-9D21-42F0-A2F9-3FE97D356392}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2609012-9D21-42F0-A2F9-3FE97D356392}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2609012-9D21-42F0-A2F9-3FE97D356392}.Release|Any CPU.Build.0 = Release|Any CPU + {C56A1E1A-976C-42ED-B7A2-08C6111AA0E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C56A1E1A-976C-42ED-B7A2-08C6111AA0E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C56A1E1A-976C-42ED-B7A2-08C6111AA0E8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C56A1E1A-976C-42ED-B7A2-08C6111AA0E8}.Release|Any CPU.Build.0 = Release|Any CPU + {FE8A1426-8B19-4CDF-A75E-80397E55BA95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE8A1426-8B19-4CDF-A75E-80397E55BA95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE8A1426-8B19-4CDF-A75E-80397E55BA95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE8A1426-8B19-4CDF-A75E-80397E55BA95}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/NFC/APDUCommand.cs b/NFC/APDUCommand.cs index 1630965..b504df2 100644 --- a/NFC/APDUCommand.cs +++ b/NFC/APDUCommand.cs @@ -4,18 +4,17 @@ namespace NFC { public class APDUCommand { - private IsoCase case4Short; - - public APDUCommand(IsoCase case4Short) + public APDUCommand(IsoCase isoCase) { - this.case4Short = case4Short; + Case = isoCase; } - public int CLA { get; internal set; } - public byte INS { get; internal set; } - public byte[] Data { get; internal set; } + public IsoCase Case { get; set; } + public byte CLA { get; set; } + public byte INS { get; set; } + public byte[] Data { get; set; } - internal byte[] ToArray() + public byte[] ToArray() { throw new NotImplementedException(); } diff --git a/NFC/APDUResponse.cs b/NFC/APDUResponse.cs index 8fc8bac..4b98a3c 100644 --- a/NFC/APDUResponse.cs +++ b/NFC/APDUResponse.cs @@ -2,8 +2,8 @@ { public class APDUResponse { - public byte SW1 { get; internal set; } - public byte SW2 { get; internal set; } - public byte[] Body { get; internal set; } + public byte SW1 { get; set; } + public byte SW2 { get; set; } + public byte[] Body { get; set; } } } diff --git a/NFC/IsoCase.cs b/NFC/IsoCase.cs index 7903691..caa61de 100644 --- a/NFC/IsoCase.cs +++ b/NFC/IsoCase.cs @@ -3,6 +3,8 @@ public enum IsoCase { Case4Short, - Case2Short + Case2Short, + Case3Short, + Case1 } } diff --git a/NFC_Android/NFC_Android.csproj b/NFC_Android/NFC_Android.csproj new file mode 100644 index 0000000..cb63190 --- /dev/null +++ b/NFC_Android/NFC_Android.csproj @@ -0,0 +1,7 @@ + + + + netcoreapp3.1 + + + diff --git a/NFC_PCSC/Card_PCSC.cs b/NFC_PCSC/Card_PCSC.cs new file mode 100644 index 0000000..f45ac9a --- /dev/null +++ b/NFC_PCSC/Card_PCSC.cs @@ -0,0 +1,75 @@ +using PCSC; +using PCSC.Iso7816; +using NFC.Interfaces; +using NFC; +using System; + +namespace NFC_PCSC +{ + public class Card_PCSC : ICard + { + private IsoReader _ISOReader; + private string _ReaderID; + + public Card_PCSC(IsoReader isoreader, string readerID) + { + _ISOReader = isoreader; + _ReaderID = readerID; + } + public void Connect() + { + _ISOReader.Connect(_ReaderID, SCardShareMode.Shared, SCardProtocol.Any); + } + + public void Disconnect() + { + _ISOReader.Disconnect(SCardReaderDisposition.Eject); + } + + public APDUResponse Transmit(APDUCommand apdu_cmd) + { + Response response = _ISOReader.Transmit(Convert(apdu_cmd)); + return Convert(response); + } + + public CommandApdu Convert(APDUCommand apdu_cmd) + { + throw new NotImplementedException(); + return new CommandApdu(ConvertISOCase(apdu_cmd.Case), SCardProtocol.Any) + { + + }; + } + + public PCSC.Iso7816.IsoCase ConvertISOCase(NFC.IsoCase isoCase) + { + switch(isoCase) + { + case NFC.IsoCase.Case1: + return PCSC.Iso7816.IsoCase.Case1; + case NFC.IsoCase.Case2Short: + return PCSC.Iso7816.IsoCase.Case2Short; + case NFC.IsoCase.Case3Short: + return PCSC.Iso7816.IsoCase.Case3Short; + case NFC.IsoCase.Case4Short: + return PCSC.Iso7816.IsoCase.Case4Short; + default: + throw new Exception("Unknown IsoCase"); + } + } + + public APDUResponse Convert(Response response) + { + ResponseApdu responseApdu = response.Get(0); + + APDUResponse apduResponse = new APDUResponse() + { + SW1 = responseApdu.SW1, + SW2 = responseApdu.SW2, + Body = responseApdu.GetData() + }; + + return apduResponse; + } + } +} diff --git a/NFC_PCSC/Hardware_PCSC.cs b/NFC_PCSC/Hardware_PCSC.cs new file mode 100644 index 0000000..b5f184d --- /dev/null +++ b/NFC_PCSC/Hardware_PCSC.cs @@ -0,0 +1,34 @@ +using NFC.Interfaces; +using PCSC; + +namespace NFC_PCSC +{ + public class Hardware_PCSC : IHardware + { + public string[] GetReaders() + { + var contextFactory = ContextFactory.Instance; + using (var context = contextFactory.Establish(SCardScope.System)) + { + return context.GetReaders(); + } + } + + public bool IsAvailable() + { + if(GetReaders().Length == 0) + { + return false; + } + else + { + return true; + } + } + + public IReader OpenReader(string readerID) + { + return new Reader_PCSC(readerID); + } + } +} diff --git a/NFC_PCSC/NFC_PCSC.csproj b/NFC_PCSC/NFC_PCSC.csproj new file mode 100644 index 0000000..56d2f70 --- /dev/null +++ b/NFC_PCSC/NFC_PCSC.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp3.1 + + + + + + + + + + + + diff --git a/NFC_PCSC/Reader_PCSC.cs b/NFC_PCSC/Reader_PCSC.cs new file mode 100644 index 0000000..599da4e --- /dev/null +++ b/NFC_PCSC/Reader_PCSC.cs @@ -0,0 +1,50 @@ +using NFC.Interfaces; +using PCSC; +using PCSC.Iso7816; +using System; + +namespace NFC_PCSC +{ + + public class Reader_PCSC : IReader, IDisposable + { + private string _ReaderID; + private IContextFactory _ContextFactory; + private ISCardContext _SCardContext; + private IsoReader _ISOReader; + private ICard _Card; + + public Reader_PCSC(string readerID) + { + _ReaderID = readerID; + } + + public event ReaderEventHandler CardDiscovered; + public event ReaderEventHandler CardLost; + + public void Dispose() + { + Stop(); + } + + public void Start() + { + _ContextFactory = ContextFactory.Instance; + _SCardContext = _ContextFactory.Establish(SCardScope.System); + + _ISOReader = new IsoReader(_SCardContext); + + _Card = new Card_PCSC(_ISOReader, _ReaderID); + + CardDiscovered?.Invoke(this, _Card); + } + + public void Stop() + { + CardLost?.Invoke(this, _Card); + + _ISOReader.Dispose(); + _SCardContext.Dispose(); + } + } +} diff --git a/NFC_Test/APDUCommand_Test.cs b/NFC_Test/APDUCommand_Test.cs new file mode 100644 index 0000000..75dbafb --- /dev/null +++ b/NFC_Test/APDUCommand_Test.cs @@ -0,0 +1,118 @@ +using System; +using NFC; +using NUnit.Framework; + +namespace NFC_Test.Helper +{ + [TestFixture] + public class APDUCommand_Test + { + [Test] + public void Compare() + { + APDUCommand command1 = new APDUCommand(IsoCase.Case4Short) + { + CLA = 0x90, + INS = 0xAA, + Data = new byte[] + { + 0x01, 0x02, 0x03 + } + }; + + APDUCommand command2 = new APDUCommand(IsoCase.Case4Short) + { + CLA = 0x90, + INS = 0xAA, + Data = new byte[] + { + 0x01, 0x02, 0x03 + } + }; + + Assert.IsTrue(command1 == command2); + } + + [Test] + public void Compare_Diff() + { + APDUCommand command1 = new APDUCommand(IsoCase.Case4Short) + { + CLA = 0x90, + INS = 0xAA, + Data = new byte[] + { + 0x01, 0x02, 0x03 + } + }; + + APDUCommand command2 = new APDUCommand(IsoCase.Case4Short) + { + CLA = 0x90, + INS = 0x1A, + Data = new byte[] + { + 0x01, 0x02, 0x03 + } + }; + + Assert.IsFalse(command1 == command2); + } + + [Test] + public void ToString_Case1() + { + APDUCommand command = new APDUCommand(IsoCase.Case1) + { + CLA = 0x90, + INS = 0x1A + }; + + Console.WriteLine(command.ToString()); + } + + [Test] + public void ToString_Case2() + { + APDUCommand command = new APDUCommand(IsoCase.Case2Short) + { + CLA = 0x90, + INS = 0x1A + }; + + Console.WriteLine(command.ToString()); + } + + [Test] + public void ToString_Case3() + { + APDUCommand command = new APDUCommand(IsoCase.Case3Short) + { + CLA = 0x90, + INS = 0x1A, + Data = new byte[] + { + 0x01, 0x02, 0x03 + } + }; + + Console.WriteLine(command.ToString()); + } + + [Test] + public void ToString_Case4() + { + APDUCommand command = new APDUCommand(IsoCase.Case4Short) + { + CLA = 0x90, + INS = 0x1A, + Data = new byte[] + { + 0x01, 0x02, 0x03 + } + }; + + Console.WriteLine(command.ToString()); + } + } +} diff --git a/NFC_Test/Cards/MIFARE_DESFire_Test.cs b/NFC_Test/Cards/MIFARE_DESFire_Test.cs new file mode 100644 index 0000000..bf4d6fa --- /dev/null +++ b/NFC_Test/Cards/MIFARE_DESFire_Test.cs @@ -0,0 +1,1136 @@ +using NFC; +using NFC.Cards.NXP_MIFARE_DESFire; +using NFC.Cards.NXP_MIFARE_DESFire.Enums; +using NFC.Cards.NXP_MIFARE_DESFire.Exceptions; +using NFC.Helper; +using NFC.Interfaces; +using NSubstitute; +using NUnit.Framework; +using System; +using System.Text; + +namespace NFC_Test.Cards +{ + [TestFixture] + public class MIFARE_DESFire_Test + { + #region Helper Methods + [Test] + public void GenerateEmptyArray() + { + uint i = 16; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + byte[] data = desfire.GenerateEmptyArray(i); + + for (int e = 0; e < i; e++) + { + if (data[e] != 0x00) + { + Assert.Fail("Data is not 0x00"); + } + } + } + + [Test] + public void GetSubArray() + { + byte[] array = new byte[] + { + 0x01, 0x02, 0x03, 0x04, 0x05 + }; + + byte[] expected_subarray = new byte[] + { + 0x02, 0x03, 0x04 + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.AreEqual(expected_subarray, desfire.GetSubArray(array, 1, 3)); + } + + [Test] + public void CheckAPDUResponse__NULL() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(null); + }); + } + + [Test] + public void CheckAPDUResponse__UNKNOWN() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x00, + SW2 = 0x00 + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(response); + }); + } + + [Test] + public void CheckAPDUResponse__OPERATION_OK() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00 + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + desfire.CheckAPDUResponse(response); + } + + [Test] + public void CheckAPDUResponse__NO_CHANGES() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x0C + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + desfire.CheckAPDUResponse(response); + } + + [Test] + public void CheckAPDUResponse__ILLEGAL_COMMAND_CODE() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x1C + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(response); + }); + } + + [Test] + public void CheckAPDUResponse__INTEGRITY_ERROR() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x1E + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(response); + }); + } + + [Test] + public void CheckAPDUResponse__NO_SUCH_KEY() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x40 + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(response); + }); + } + + [Test] + public void CheckAPDUResponse__LENGTH_ERROR() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x7E + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(response); + }); + } + + [Test] + public void CheckAPDUResponse__PERMISSION_DENIED() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x9D + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(response); + }); + } + + [Test] + public void CheckAPDUResponse__PARAMETER_ERROR() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x9E + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(response); + }); + } + + [Test] + public void CheckAPDUResponse__AUTHENTICATION_DELAY() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0xAD + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(response); + }); + } + + [Test] + public void CheckAPDUResponse__AUTHENTICATION_ERROR() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0xAE + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(response); + }); + } + + [Test] + public void CheckAPDUResponse__ADDITIONAL_FRAME() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0xAF + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + desfire.CheckAPDUResponse(response); + } + + [Test] + public void CheckAPDUResponse__BOUNDARY_ERROR() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0xBE + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(response); + }); + } + + [Test] + public void CheckAPDUResponse__COMMAND_ABORTED() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0xCA + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(response); + }); + } + + [Test] + public void CheckAPDUResponse__DUPLICATE_ERROR() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0xDE + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(response); + }); + } + + [Test] + public void CheckAPDUResponse__FILE_NOT_FOUND() + { + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0xF0 + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.CheckAPDUResponse(response); + }); + } + #endregion + + #region Crypto Operation + [Test] + public void ExtractLastBlock() + { + byte[] data = new byte[] + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + }; + + byte[] expected_lastblock = new byte[] + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + byte[] lastblock = desfire.ExtractLastBlock(data, 8); + + Assert.AreEqual(expected_lastblock, lastblock); + } + + [Test] + public void ExtractLastBlock_WrongBlocksize() + { + byte[] data = new byte[] + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + byte[] lastblock = desfire.ExtractLastBlock(data, 7); + }); + } + + [Test] + public void ExtractLastBlock_Null() + { + byte[] data = null; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + byte[] lastblock = desfire.ExtractLastBlock(data, 7); + }); + } + + [Test] + public void ExpandToBlockSize() + { + byte[] data = new byte[] + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + }; + + byte[] expected_lastblock = new byte[] + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + byte[] lastblock = desfire.ExpandToBlockSize(data, 8); + + Assert.AreEqual(expected_lastblock, lastblock); + } + + [Test] + public void ExpandToBlockSize_Null() + { + byte[] data = null; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + byte[] lastblock = desfire.ExpandToBlockSize(data, 8); + }); + } + + [Test] + public void RotateLeft() + { + byte[] data = new byte[] + { + 0x01, 0x02, 0x03, 0x04 + }; + + byte[] expected_data_left = new byte[] + { + 0x02, 0x03, 0x04, 0x01 + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + byte[] data_left = desfire.RotateLeft(data); + + Assert.AreEqual(expected_data_left, data_left); + } + + [Test] + public void RotateLeft_Null() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + byte[] lastblock = desfire.RotateLeft(null); + }); + } + + [Test] + public void RotateRight() + { + byte[] data = new byte[] + { + 0x01, 0x02, 0x03, 0x04 + }; + + byte[] expected_data_left = new byte[] + { + 0x04, 0x01, 0x02, 0x03 + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + byte[] data_left = desfire.RotateRight(data); + + Assert.AreEqual(expected_data_left, data_left); + } + + [Test] + public void RotateRight_Null() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + byte[] lastblock = desfire.RotateRight(null); + }); + } + + [Test] + public void Concatenate() + { + byte[] data_a = new byte[] + { + 0x01, 0x02, 0x03, 0x04 + }; + + byte[] data_b = new byte[] + { + 0x05, 0x06, 0x07, 0x08 + }; + + byte[] expected_data_c = new byte[] + { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + byte[] data_c = desfire.Concatenate(data_a, data_b); + + Assert.AreEqual(expected_data_c, data_c); + } + + [Test] + public void Concatenate_ABC() + { + byte[] data_a = new byte[] + { + 0x01, 0x02, 0x03, 0x04 + }; + + byte[] data_b = new byte[] + { + 0x05, 0x06, 0x07, 0x08 + }; + + byte[] data_c = new byte[] + { + 0x09, 0xA0, 0xB0, 0xC0 + }; + + byte[] expected_data_d = new byte[] + { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xA0, 0xB0, 0xC0 + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + byte[] data_d = desfire.Concatenate(data_a, data_b, data_c); + + Assert.AreEqual(expected_data_d, data_d); + } + + [Test] + public void Concatenate_Null() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + byte[] lastblock = desfire.Concatenate(null, null); + }); + } + + [Test] + public void XOR() + { + byte[] data_a = new byte[] + { + 0x00, 0xF0, 0x00, 0xF0 + }; + + byte[] data_b = new byte[] + { + 0x0F, 0x00, 0x0F, 0x00 + }; + + byte[] expected_data_c = new byte[] + { + 0x0F, 0xF0, 0x0F, 0xF0 + }; + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + byte[] data_c = desfire.XOR(data_a, data_b); + + Assert.AreEqual(expected_data_c, data_c); + } + + [Test] + public void XOR_null() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + byte[] lastblock = desfire.XOR(null, null); + }); + } + + [Test] + public void GenerateSessionKey_DES() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + byte[] rndA = HexConverter.ConvertFromHexString("a541a9dc9138df07"); + Console.WriteLine(HexConverter.ConvertToHexString(rndA)); + byte[] rndB = HexConverter.ConvertFromHexString("cbe55aa893b2da25"); + Console.WriteLine(HexConverter.ConvertToHexString(rndB)); + + byte[] expected_sessionkey = HexConverter.ConvertFromHexString("a541a9dccbe55aa8a541a9dccbe55aa8"); + Console.WriteLine(HexConverter.ConvertToHexString(expected_sessionkey)); + + byte[] sessionkey = desfire.GenerateSesionKey_DES(rndA, rndB); + Console.WriteLine(HexConverter.ConvertToHexString(sessionkey)); + Assert.AreEqual(expected_sessionkey, sessionkey); + } + + [Test] + public void GenerateSessionKey_AES() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + byte[] rndA = HexConverter.ConvertFromHexString("bc14dfde20074617e45a8822f06fdd91"); + Console.WriteLine(HexConverter.ConvertToHexString(rndA)); + byte[] rndB = HexConverter.ConvertFromHexString("482ddc54426e6dee560413b8d95471f5"); + Console.WriteLine(HexConverter.ConvertToHexString(rndB)); + + byte[] expected_sessionkey = HexConverter.ConvertFromHexString("bc14dfde482ddc54f06fdd91d95471f5"); + Console.WriteLine(HexConverter.ConvertToHexString(expected_sessionkey)); + + byte[] sessionkey = desfire.GenerateSesionKey_AES(rndA, rndB); + Console.WriteLine(HexConverter.ConvertToHexString(sessionkey)); + Assert.AreEqual(expected_sessionkey, sessionkey); + } + #endregion + + #region Configuration Generator + [Test] + public void GenerateKeySetting1() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.AreEqual(0x0B, desfire.GenerateKeySetting1(ChangeApplicationKey.MASTERKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.ONLYMASTERKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE)); + } + + [Test] + public void GenerateKeySetting1_ChangeKey() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + Assert.AreEqual(0x1B, desfire.GenerateKeySetting1(0x01, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.ONLYMASTERKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE)); + } + + [Test] + public void GenerateKeySetting1_Wrong_KeyID() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.GenerateKeySetting1(0x10, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.ONLYMASTERKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE); + }); + } + + [Test] + public void GenerateKeySetting2() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.AreEqual(0x82, desfire.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 0x02)); + } + + [Test] + public void GenerateKeySetting2_Wrong_KeyNumbers() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 0x10); + }); + } + + + [Test] + public void GenerateFileAccessRights() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.AreEqual(0x1234, desfire.GenerateFileAccessRights(0x01, 0x02, 0x03, 0x04)); + } + + [Test] + public void GenerateFileAccessRights_OutOfRange() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.GenerateFileAccessRights(0x10, 0x00, 0x00, 0x00); + }); + } + #endregion + + #region DESFire Commands + [Test] + public void SelectApplication() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00 + }; + + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "905a00000333221100")).Returns(response); + + desfire.SelectApplication(0x112233); + } + + [Test] + public void SelectApplication_InvalidAID() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.SelectApplication(0xFF000000); + }); + } + + [Test] + public void AuthenticateISO_DES() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + APDUResponse response_challenge_request = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0xAF, + Body = HexConverter.ConvertFromHexString("2bf9a938ecca02e2") + }; + + APDUResponse response_challenge_response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00, + Body = HexConverter.ConvertFromHexString("07d825607a552e2e") + }; + + byte[] rndA = HexConverter.ConvertFromHexString("5f7d1dd12d979173"); + byte[] key = HexConverter.ConvertFromHexString("00000000000000000000000000000000"); + + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "901a0000010000")).Returns(response_challenge_request); + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "90af000010f8cdb2eaa42a3167dfcb53852ce267fd00")).Returns(response_challenge_response); + + desfire.AuthenticateISO_DES(0x00, key, rndA); + + byte[] expected_sessionkey = HexConverter.ConvertFromHexString("5f7d1dd1f449db5c5f7d1dd1f449db5c"); + byte[] expected_iv = HexConverter.ConvertFromHexString("0000000000000000"); + + Assert.AreEqual(expected_sessionkey, desfire._SessionKey); + Assert.AreEqual(expected_iv, desfire._IV); + } + + [Test] + public void AuthenticateISO_DES_InvalidKeyNo() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.AuthenticateISO_DES(0x0F, null); + }); + } + + [Test] + public void Format() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00 + }; + + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "90fc000000")).Returns(response); + + desfire.Format(); + } + + [Test] + public void CreateApplication() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00 + }; + + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "90ca000005eeffaa0b8200")).Returns(response); + + desfire.CreateApplication(0xAAFFEE, 0x0b, 0x82); + } + + [Test] + public void CreateApplication_InvalidAID() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.CreateApplication(0xFF000000, 0x00, 0x00); + }); + } + + [Test] + public void AuthenticateISO_AES() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + APDUResponse response_challenge_request = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0xAF, + Body = HexConverter.ConvertFromHexString("a33856932308775cf464610c2b17a558") + }; + + APDUResponse response_challenge_response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00, + Body = HexConverter.ConvertFromHexString("8fdc476f6bac44fe9150e285abd68d48") + }; + + byte[] rndA = HexConverter.ConvertFromHexString("2176770e7a6eb4bef00d5e4b201d1e57"); + byte[] key = HexConverter.ConvertFromHexString("00000000000000000000000000000000"); + + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "90aa0000010000")).Returns(response_challenge_request); + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "90af000020cbe9726faf54bc76b2055d0b9700e7dc97ecad5627f1d1702a16e8408d2a0ada00")).Returns(response_challenge_response); + + desfire.AuthenticateISO_AES(0x00, key, rndA); + + byte[] expected_sessionkey = HexConverter.ConvertFromHexString("2176770e11c512ca201d1e57fde6e15a"); + byte[] expected_iv = HexConverter.ConvertFromHexString("00000000000000000000000000000000"); + + Assert.AreEqual(expected_sessionkey, desfire._SessionKey); + Assert.AreEqual(expected_iv, desfire._IV); + } + + [Test] + public void AuthenticateISO_AES_InvalidKeyNo() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.AuthenticateISO_AES(0x0F, null); + }); + } + + [Test] + public void ChangeKey_AES() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00 + }; + + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "90c400002100c2b54a718d0251845653199909bb32e8e38bd6719e8dc21799c29c922a0984fc00")).Returns(response); + + byte[] new_key = HexConverter.ConvertFromHexString("25432a462d4a614e645267556b587032"); + + byte[] sessionkey = HexConverter.ConvertFromHexString("a8514dd0350f3dfbc86e80744bcc9b57"); + byte[] iv = HexConverter.ConvertFromHexString("00000000000000000000000000000000"); + + desfire._SessionKey = sessionkey; + desfire._IV = iv; + + desfire.ChangeKey_AES(0x00, new_key, 0x10); + } + + [Test] + public void ChangeKey_AES_InvalidKeyNo() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.ChangeKey_AES(0x0F, null, 0x10); + }); + } + + [Test] + public void ChangeOtherKey_AES() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00 + }; + + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "90c400002101a8c5a61a06f56f38dc91266fed2e87dc00a5ad72a634ff0e62c8d6d80707dd6000")).Returns(response); + + byte[] new_key = HexConverter.ConvertFromHexString("25432a462d4a614e645267556b587032"); + byte[] old_key = HexConverter.ConvertFromHexString("00000000000000000000000000000000"); + + byte[] sessionkey = HexConverter.ConvertFromHexString("1677623e1e158a62dc3d128db55f947d"); + byte[] iv = HexConverter.ConvertFromHexString("00000000000000000000000000000000"); + + desfire._SessionKey = sessionkey; + desfire._IV = iv; + + desfire.ChangeOtherKey_AES(0x01, new_key, old_key, 0x10); + } + + [Test] + public void ChangeOtherKey_AES_InvalidKeyNo() + { + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null); + + Assert.Throws( + delegate + { + desfire.ChangeKey_AES(0x0F, null, 0x10); + }); + } + + [Test] + public void CreateFile_Standard() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00 + }; + + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "90cd000007010000e0f0000000")).Returns(response); + + UInt16 accesRights = desfire.GenerateFileAccessRights((byte)FileAccessRights.FREE, 0x00, 0x00, 0x00); + desfire.CreateFile_Standard(0x01, FileCommunication.PLAIN, accesRights, 0xF0); + } + + [Test] + public void CreateFile_Standard_InvalidFID() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + Assert.Throws( + delegate + { + desfire.CreateFile_Standard(0x21, FileCommunication.PLAIN, 0x0000, 0xF0); + }); + } + + [Test] + public void WriteData() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00 + }; + + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "903d00000f01000000080000546573743132333400")).Returns(response); + + desfire.WriteData(0x01, 0, Encoding.ASCII.GetBytes("Test1234")); + } + + [Test] + public void WriteData_Long() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00 + }; + + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "903d000036010000002f0000546573743132333454657374313233345465737431323334546573743132333454657374313233345465737431323300")).Returns(response); + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "903d000036012f00002f0000345465737431323334546573743132333454657374313233345465737431323334546573743132333454657374313200")).Returns(response); + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "903d000019015e000012000033345465737431323334546573743132333400")).Returns(response); + + desfire.WriteData(0x01, 0, Encoding.ASCII.GetBytes("Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234")); + } + + [Test] + public void WriteData_InvalidFileID() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + Assert.Throws( + delegate + { + desfire.WriteData(0x21, 0x00, Encoding.ASCII.GetBytes("Test1234")); + }); + } + + [Test] + public void ReadData() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00, + Body = HexConverter.ConvertFromHexString("54657374313233340000000000000000000000000000000000000000000000009100") + }; + + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "90bd0000070100000020000000")).Returns(response); + + byte[] data = desfire.ReadData(0x01, 0x00, 0x20); + + Assert.AreEqual("Test1234", Encoding.ASCII.GetString(data).Replace("\u0000", "")); + } + + [Test] + public void ReadData_CMAC() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00, + Body = HexConverter.ConvertFromHexString("5465737431323334000000000000000000000000000000000000000000000000809a9bedbc559a5b9100") + }; + + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "90bd0000070100000020000000")).Returns(response); + + byte[] data = desfire.ReadData(0x01, 0x00, 0x20); + + Assert.AreEqual("Test1234", Encoding.ASCII.GetString(data).Replace("\u0000", "")); + } + + [Test] + public void ReadData_Long() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + APDUResponse response_1 = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00, + Body = HexConverter.ConvertFromHexString("54657374313233340000000000000000000000000000000000000000000000000000000000000000000000000000009100") + }; + + APDUResponse response_2 = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00, + Body = HexConverter.ConvertFromHexString("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009100") + }; + + APDUResponse response_3 = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00, + Body = HexConverter.ConvertFromHexString("00009100") + }; + + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "90bd000007010000002f000000")).Returns(response_1); + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "90bd000007012f00002f000000")).Returns(response_2); + card.Transmit(Arg.Is(x => HexConverter.ConvertToHexString(x.ToArray()) == "90bd000007015e000002000000")).Returns(response_3); + + byte[] data = desfire.ReadData(0x01, 0x00, 0x60); + + Assert.AreEqual("Test1234", Encoding.ASCII.GetString(data).Replace("\u0000", "")); + } + + [Test] + public void ReadData_InvalidFileID() + { + ICard card = Substitute.For(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + Assert.Throws( + delegate + { + desfire.ReadData(0x21, 0x00, 0x20); + }); + } + #endregion + } +} diff --git a/NFC_Test/Helper/AES_Test.cs b/NFC_Test/Helper/AES_Test.cs new file mode 100644 index 0000000..0a79ad6 --- /dev/null +++ b/NFC_Test/Helper/AES_Test.cs @@ -0,0 +1,24 @@ +using NFC.Helper; +using NFC.Helper.Crypto.Cipher; +using NUnit.Framework; + +namespace NFC_Test.Helper +{ + [TestFixture] + public class AES_Test + { + [Test] + public void Encrypt() + { + byte[] data = HexConverter.ConvertFromHexString("8db1f942f2d7cc82f6fa1486a30f8c12104a3b07e8eb77a7ac00000000000000"); + byte[] key = HexConverter.ConvertFromHexString("e7aff3361c3e85347993c3219a87d24b"); + byte[] iv = HexConverter.ConvertFromHexString("00000000000000000000000000000000"); + + AES aes = new AES(); + byte[] data_enc = aes.Encrypt(data, key, iv); + + byte[] data_enc_expected = HexConverter.ConvertFromHexString("3c79d74a4969ba7123e5d8f6df24493112d221fd131a4617d0eda5d92ccc1b46"); + Assert.AreEqual(data_enc_expected, data_enc); + } + } +} \ No newline at end of file diff --git a/NFC_Test/Helper/CRC16_Test.cs b/NFC_Test/Helper/CRC16_Test.cs new file mode 100644 index 0000000..879e0aa --- /dev/null +++ b/NFC_Test/Helper/CRC16_Test.cs @@ -0,0 +1,23 @@ +using NFC.Helper; +using NFC.Helper.Crypto.CRC; +using NUnit.Framework; + +namespace NFC_Test.Helper +{ + [TestFixture] + public class CRC16_Test + { + [Test] + [Ignore("Unknown Expected Data")] + public void Caluclate() + { + byte[] data = HexConverter.ConvertFromHexString(""); + byte[] crc_expected = HexConverter.ConvertFromHexString(""); + + CRC16 crc16 = new CRC16(); + byte[] crc = crc16.Calculate(data); + + Assert.AreEqual(crc_expected, crc); + } + } +} diff --git a/NFC_Test/Helper/CRC32_Test.cs b/NFC_Test/Helper/CRC32_Test.cs new file mode 100644 index 0000000..c355188 --- /dev/null +++ b/NFC_Test/Helper/CRC32_Test.cs @@ -0,0 +1,22 @@ +using NFC.Helper; +using NFC.Helper.Crypto.CRC; +using NUnit.Framework; + +namespace NFC_Test.Helper +{ + [TestFixture] + public class CRC32_Test + { + [Test] + public void Caluclate() + { + byte[] data = HexConverter.ConvertFromHexString("c40045eeb8338ae8f49a032e85bb1114353010"); + byte[] crc_expected = HexConverter.ConvertFromHexString("95c3894b"); + + CRC32 crc32 = new CRC32(); + byte[] crc = crc32.Calculate(data); + + Assert.AreEqual(crc_expected, crc); + } + } +} diff --git a/NFC_Test/Helper/HexConverter_Test.cs b/NFC_Test/Helper/HexConverter_Test.cs new file mode 100644 index 0000000..069f150 --- /dev/null +++ b/NFC_Test/Helper/HexConverter_Test.cs @@ -0,0 +1,34 @@ +using NFC.Helper; +using NUnit.Framework; + +namespace NFC_Test.Helper +{ + 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/Helper/TDES_Test.cs b/NFC_Test/Helper/TDES_Test.cs new file mode 100644 index 0000000..85dc12b --- /dev/null +++ b/NFC_Test/Helper/TDES_Test.cs @@ -0,0 +1,55 @@ +using NFC.Helper; +using NFC.Helper.Crypto.Cipher; +using NUnit.Framework; + +namespace NFC_Test.Helper +{ + [TestFixture] + public class TDES_Test + { + [Test] + [Ignore("Unknown Expected Data")] + public void Encrypt_TDES() + { + byte[] data = HexConverter.ConvertFromHexString(""); + byte[] key = HexConverter.ConvertFromHexString(""); + byte[] iv = HexConverter.ConvertFromHexString("0000000000000000"); + + TDES des = new TDES(); + byte[] data_enc = des.Encrypt(data, key, iv); + + byte[] data_enc_expected = HexConverter.ConvertFromHexString(""); + Assert.AreEqual(data_enc_expected, data_enc); + } + + [Test] + [Ignore("Unknown Expected Data")] + public void Encrypt_TDES_2K() + { + byte[] data = HexConverter.ConvertFromHexString(""); + byte[] key = HexConverter.ConvertFromHexString(""); + byte[] iv = HexConverter.ConvertFromHexString("0000000000000000"); + + TDES_2K des = new TDES_2K(); + byte[] data_enc = des.Encrypt(data, key, iv); + + byte[] data_enc_expected = HexConverter.ConvertFromHexString(""); + Assert.AreEqual(data_enc_expected, data_enc); + } + + [Test] + [Ignore("Unknown Expected Data")] + public void Encrypt_TDES_3K() + { + byte[] data = HexConverter.ConvertFromHexString(""); + byte[] key = HexConverter.ConvertFromHexString(""); + byte[] iv = HexConverter.ConvertFromHexString("0000000000000000"); + + TDES_3K des = new TDES_3K(); + byte[] data_enc = des.Encrypt(data, key, iv); + + byte[] data_enc_expected = HexConverter.ConvertFromHexString(""); + Assert.AreEqual(data_enc_expected, data_enc); + } + } +} \ No newline at end of file diff --git a/NFC_Test/NFC_Test.csproj b/NFC_Test/NFC_Test.csproj new file mode 100644 index 0000000..78f0b6d --- /dev/null +++ b/NFC_Test/NFC_Test.csproj @@ -0,0 +1,18 @@ + + + + netcoreapp3.1 + + + + + + + + + + + + + + diff --git a/NFC_Test/NamespaceSetUp.cs b/NFC_Test/NamespaceSetUp.cs new file mode 100644 index 0000000..97d4b99 --- /dev/null +++ b/NFC_Test/NamespaceSetUp.cs @@ -0,0 +1,34 @@ +using log4net.Config; +using NUnit.Framework; + +namespace NFC_Test +{ + /// + /// Add log4net Output to Console Out + /// + [SetUpFixture] + public class NamespaceSetUp + { + [OneTimeSetUp] + public void OneTimeSetUp() + { + BasicConfigurator.Configure(); + } + } +} + +namespace NFC_Real_Test +{ + /// + /// Add log4net Output to Console Out + /// + [SetUpFixture] + public class NamespaceSetUp + { + [OneTimeSetUp] + public void OneTimeSetUp() + { + BasicConfigurator.Configure(); + } + } +} diff --git a/NFC_Test/REAL/REAL_DESFireCommands.cs b/NFC_Test/REAL/REAL_DESFireCommands.cs new file mode 100644 index 0000000..b64fdf7 --- /dev/null +++ b/NFC_Test/REAL/REAL_DESFireCommands.cs @@ -0,0 +1,477 @@ +using NFC.Cards.NXP_MIFARE_DESFire; +using NFC.Cards.NXP_MIFARE_DESFire.Enums; +using NFC.Helper.Crypto; +using NFC.Interfaces; +using NFC_PCSC; +using NUnit.Framework; +using System; +using System.Text; + +namespace NFC_Test.REAL +{ + /// + /// Test all DESFire Commands with an Empty Card + /// The Test are ordered to check the Commands one by one + /// + [TestFixture, Explicit] + public class REAL_DESFireCommands + { + /// + /// Set ReaderID for PCSC Interface + /// You can get the ID from REAL_Reader_PCSC + /// + public readonly string ReaderID = "ACS ACR122U PICC Interface 0"; + + #region Fixed Config Properties + public readonly UInt32 ApplicationID = 0xAAFFEE; + public readonly string ApplicationMasterKey = "25432A462D4A614E645267556B587032"; + public readonly string ApplicationKey_1 = "25432A462D4A614E645267556B587032"; + public readonly byte FileID = 0x01; + public readonly byte FileSize = 0xF0; + #endregion + + [Test, Order(1)] + public void SelectApplication() + { + IHardware hardware = new Hardware_PCSC(); + IReader reader = hardware.OpenReader(ReaderID); + + bool test_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + NXP_MIFARE_DESFire desfire = new NXP_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, Order(2)] + public void Authenticate_DES() + { + IHardware hardware = new Hardware_PCSC(); + IReader reader = hardware.OpenReader(ReaderID); + + bool test_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + NXP_MIFARE_DESFire desfire = new NXP_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, Order(3)] + public void Format() + { + IHardware hardware = new Hardware_PCSC(); + IReader reader = hardware.OpenReader(ReaderID); + + bool test_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + desfire.SelectApplication(0x000000); + + CipherKey key = new CipherKey(CipherType.TDES); + desfire.AuthenticateISO_DES(0x00, key._Key); + + desfire.Format(); + + test_successfully = true; + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, test_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; + } + + [Test, Order(4)] + public void CreateApplication() + { + IHardware hardware = new Hardware_PCSC(); + IReader reader = hardware.OpenReader(ReaderID); + + bool test_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + desfire.SelectApplication(0x000000); + + CipherKey key = new CipherKey(CipherType.TDES); + desfire.AuthenticateISO_DES(0x00, key._Key); + + desfire.Format(); + + desfire.AuthenticateISO_DES(0x00, key._Key); + + byte keysetting1 = desfire.GenerateKeySetting1(ChangeApplicationKey.MASTERKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.ONLYMASTERKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE); + byte keysetting2 = desfire.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 2); + + desfire.CreateApplication(ApplicationID, keysetting1, keysetting2); + + test_successfully = true; + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, test_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; + } + + [Test, Order(5)] + public void Authenticate_AES() + { + IHardware hardware = new Hardware_PCSC(); + IReader reader = hardware.OpenReader(ReaderID); + + bool test_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + desfire.SelectApplication(0x000000); + + CipherKey key = new CipherKey(CipherType.TDES); + desfire.AuthenticateISO_DES(0x00, key._Key); + + desfire.Format(); + + desfire.AuthenticateISO_DES(0x00, key._Key); + + byte keysetting1 = desfire.GenerateKeySetting1(ChangeApplicationKey.MASTERKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.ONLYMASTERKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE); + byte keysetting2 = desfire.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 2); + + desfire.CreateApplication(ApplicationID, keysetting1, keysetting2); + + desfire.SelectApplication(ApplicationID); + + CipherKey key_aes = new CipherKey(CipherType.AES); + desfire.AuthenticateISO_AES(0x00, key_aes._Key); + + test_successfully = true; + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, test_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; + } + + [Test, Order(6)] + public void ChangeApplicationMasterKey() + { + IHardware hardware = new Hardware_PCSC(); + IReader reader = hardware.OpenReader(ReaderID); + + bool test_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + desfire.SelectApplication(0x000000); + + CipherKey key = new CipherKey(CipherType.TDES); + desfire.AuthenticateISO_DES(0x00, key._Key); + + desfire.Format(); + + desfire.AuthenticateISO_DES(0x00, key._Key); + + byte keysetting1 = desfire.GenerateKeySetting1(ChangeApplicationKey.MASTERKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.ONLYMASTERKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE); + byte keysetting2 = desfire.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 2); + + desfire.CreateApplication(ApplicationID, keysetting1, keysetting2); + + desfire.SelectApplication(ApplicationID); + + CipherKey key_aes = new CipherKey(CipherType.AES); + desfire.AuthenticateISO_AES(0x00, key_aes._Key); + + CipherKey key_aes_new = new CipherKey(ApplicationMasterKey, CipherType.AES, 0x10); + desfire.ChangeKey_AES(0x00, key_aes_new._Key, key_aes_new._KeyVersion); + + test_successfully = true; + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, test_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; + } + + [Test, Order(7)] + public void ChangeApplicationKey_1() + { + IHardware hardware = new Hardware_PCSC(); + IReader reader = hardware.OpenReader(ReaderID); + + bool test_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + desfire.SelectApplication(0x000000); + + CipherKey key = new CipherKey(CipherType.TDES); + desfire.AuthenticateISO_DES(0x00, key._Key); + + desfire.Format(); + + desfire.AuthenticateISO_DES(0x00, key._Key); + + byte keysetting1 = desfire.GenerateKeySetting1(ChangeApplicationKey.MASTERKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.ONLYMASTERKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE); + byte keysetting2 = desfire.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 2); + + desfire.CreateApplication(ApplicationID, keysetting1, keysetting2); + + desfire.SelectApplication(ApplicationID); + + CipherKey key_aes = new CipherKey(CipherType.AES); + desfire.AuthenticateISO_AES(0x00, key_aes._Key); + + CipherKey key_new = new CipherKey(ApplicationKey_1, CipherType.AES, 0x10); + desfire.ChangeOtherKey_AES(0x01, key_new._Key, key_aes._Key, key_new._KeyVersion); + + test_successfully = true; + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, test_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; + } + + [Test, Order(8)] + public void CreateFile() + { + IHardware hardware = new Hardware_PCSC(); + IReader reader = hardware.OpenReader(ReaderID); + + bool test_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + desfire.SelectApplication(0x000000); + + CipherKey key = new CipherKey(CipherType.TDES); + desfire.AuthenticateISO_DES(0x00, key._Key); + + desfire.Format(); + + desfire.AuthenticateISO_DES(0x00, key._Key); + + byte keysetting1 = desfire.GenerateKeySetting1(ChangeApplicationKey.MASTERKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.ONLYMASTERKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE); + byte keysetting2 = desfire.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 2); + + desfire.CreateApplication(ApplicationID, keysetting1, keysetting2); + + desfire.SelectApplication(ApplicationID); + + CipherKey key_aes = new CipherKey(CipherType.AES); + desfire.AuthenticateISO_AES(0x00, key_aes._Key); + + UInt16 accesRights = desfire.GenerateFileAccessRights((byte)FileAccessRights.FREE, 0x00, 0x00, 0x00); + desfire.CreateFile_Standard(FileID, FileCommunication.PLAIN, accesRights, FileSize); + + test_successfully = true; + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, test_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; + } + + [Test, Order(9)] + public void WriteFile() + { + IHardware hardware = new Hardware_PCSC(); + IReader reader = hardware.OpenReader(ReaderID); + + bool test_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + desfire.SelectApplication(0x000000); + + CipherKey key = new CipherKey(CipherType.TDES); + desfire.AuthenticateISO_DES(0x00, key._Key); + + desfire.Format(); + + desfire.AuthenticateISO_DES(0x00, key._Key); + + byte keysetting1 = desfire.GenerateKeySetting1(ChangeApplicationKey.MASTERKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.ONLYMASTERKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE); + byte keysetting2 = desfire.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 2); + + desfire.CreateApplication(ApplicationID, keysetting1, keysetting2); + + desfire.SelectApplication(ApplicationID); + + CipherKey key_aes = new CipherKey(CipherType.AES); + desfire.AuthenticateISO_AES(0x00, key_aes._Key); + + UInt16 accesRights = desfire.GenerateFileAccessRights((byte)FileAccessRights.FREE, 0x00, 0x00, 0x00); + desfire.CreateFile_Standard(FileID, FileCommunication.PLAIN, accesRights, FileSize); + + desfire.WriteData(FileID, 0, Encoding.ASCII.GetBytes("Test1234")); + + test_successfully = true; + + card.Disconnect(); + }; + + reader.CardDiscovered += handler; + reader.Start(); + + Assert.AreEqual(true, test_successfully); + + reader.Stop(); + reader.CardDiscovered -= handler; + } + + [Test, Order(10)] + public void ReadFile() + { + IHardware hardware = new Hardware_PCSC(); + IReader reader = hardware.OpenReader(ReaderID); + + bool test_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card); + + desfire.SelectApplication(0x000000); + + CipherKey key = new CipherKey(CipherType.TDES); + desfire.AuthenticateISO_DES(0x00, key._Key); + + desfire.Format(); + + desfire.AuthenticateISO_DES(0x00, key._Key); + + byte keysetting1 = desfire.GenerateKeySetting1(ChangeApplicationKey.MASTERKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.ONLYMASTERKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE); + byte keysetting2 = desfire.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 2); + + desfire.CreateApplication(ApplicationID, keysetting1, keysetting2); + + desfire.SelectApplication(ApplicationID); + + CipherKey key_aes = new CipherKey(CipherType.AES); + desfire.AuthenticateISO_AES(0x00, key_aes._Key); + + UInt16 accesRights = desfire.GenerateFileAccessRights((byte)FileAccessRights.FREE, 0x00, 0x00, 0x00); + desfire.CreateFile_Standard(FileID, FileCommunication.PLAIN, accesRights, FileSize); + + desfire.WriteData(FileID, 0, Encoding.ASCII.GetBytes("Test1234")); + + byte[] data = desfire.ReadData(FileID, 0, FileSize); + Console.WriteLine(Encoding.ASCII.GetString(data).Replace("\u0000", "")); + + 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/REAL/REAL_FabAccess_OTA.cs b/NFC_Test/REAL/REAL_FabAccess_OTA.cs new file mode 100644 index 0000000..3553509 --- /dev/null +++ b/NFC_Test/REAL/REAL_FabAccess_OTA.cs @@ -0,0 +1,130 @@ +using NFC.Cards.NXP_MIFARE_DESFire; +using NFC.Cards.NXP_MIFARE_DESFire.Enums; +using NFC.Helper.Crypto; +using NFC.Interfaces; +using NFC_PCSC; +using NUnit.Framework; +using System; +using System.Text; + +namespace NFC_Test.REAL +{ + [TestFixture, Explicit] + public class REAL_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; + + // Change of PICC Key is not implementet yet + // 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 = "verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrylooooooooooooooooooongusssssssssssssssssssssssernaaaaaaaaaaaaaaaaaaaaaaaame@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); + + /// + /// Create FabAccess Application and UserData File + /// + [Test, Order(1)] + public void Init_EmptyCard() + { + IHardware hardware = new Hardware_PCSC(); + IReader reader = hardware.OpenReader(_ReaderID); + + bool transmit_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + NXP_MIFARE_DESFire desfire = new NXP_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_AESKey._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(_FabAccess_FID, 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; + } + + /// + /// Authenticate with UserData File and AuthKey + /// + [Test, Order(2)] + public void Authenticate() + { + IHardware hardware = new Hardware_PCSC(); + IReader reader = hardware.OpenReader(_ReaderID); + + bool transmit_successfully = false; + + ReaderEventHandler handler = (sender, card) => + { + card.Connect(); + + NXP_MIFARE_DESFire desfire = new NXP_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); + + 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/REAL/REAL_Reader_PCSC.cs b/NFC_Test/REAL/REAL_Reader_PCSC.cs new file mode 100644 index 0000000..6cd6cef --- /dev/null +++ b/NFC_Test/REAL/REAL_Reader_PCSC.cs @@ -0,0 +1,62 @@ +using NFC.Interfaces; +using NFC_PCSC; +using NUnit.Framework; +using System; + +namespace NFC_Test.REAL +{ + [TestFixture, Explicit] + public class REAL_Reader_PCSC + { + /// + /// Print PCSC ReaderIDs to Console Out + /// + [Test] + public void GetReaders() + { + IHardware hardware = new Hardware_PCSC(); + string[] readers = hardware.GetReaders(); + + Console.WriteLine("PCSC Readers detected: {0}", readers.Length); + + if (readers.Length > 0) + { + Console.WriteLine("List of ReaderIDs:"); + foreach (string readerID in readers) + { + Console.WriteLine("{0}", readerID); + } + } + } + + /// + /// Connect to specific PCSC Reader by ReaderID + /// + /// ReaderID from GetReaders + [TestCase("ACS ACR122U PICC Interface 0")] + public void Connect(string readerID) + { + IHardware hardware = new Hardware_PCSC(); + 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; + } + } +} diff --git a/NFC_iOS/NFC_iOS.csproj b/NFC_iOS/NFC_iOS.csproj new file mode 100644 index 0000000..cb63190 --- /dev/null +++ b/NFC_iOS/NFC_iOS.csproj @@ -0,0 +1,7 @@ + + + + netcoreapp3.1 + + +