Removed: NFC

This commit is contained in:
TheJoKlLa 2021-03-31 14:36:56 +02:00
parent 5e0dd63bf9
commit e0585ed422
60 changed files with 0 additions and 5226 deletions

View File

@ -1,67 +0,0 @@
//using System;
//using System.Threading;
//using CoreNFC;
//using Foundation;
//using NFC;
//using NFC.ISO7816_4;
//namespace Borepin.iOS.CNFC
//{
// public class Card : ICard
// {
// private NFCTagReaderSession _session;
// private INFCMiFareTag _tag;
// public Card(NFCTagReaderSession session, INFCMiFareTag tag)
// {
// _session = session;
// _tag = tag;
// }
// public void Connect()
// {
// var counter = new CountdownEvent(1);
// NSError err = null;
// _session.ConnectTo(_tag, (error) =>
// {
// err = error;
// counter.Signal();
// });
// counter.Wait();
// if (err != null)
// {
// throw new Exception(err.LocalizedDescription);
// }
// }
// public void Disconnect()
// {
// // TODO: decide on which should be used
// //_session.RestartPolling();
// _session.InvalidateSession("card disconnect");
// }
// public APDUResponse Transmit(APDUCommand cmd)
// {
// var counter = new CountdownEvent(1);
// byte[] buf = null;
// _tag.SendMiFareIso7816Command(new NFCIso7816Apdu(NSData.FromArray(cmd.Data)), (response, sw1, sw2, NSError) =>
// {
// // reassembly the original apdu message
// buf = new byte[response.Length + 2];
// response.ToArray().CopyTo(buf, 0);
// buf[response.Length + 0] = sw1;
// buf[response.Length + 1] = sw2;
// counter.Signal();
// });
// counter.Wait();
// return new APDUResponse(buf);
// }
// }
//}

View File

@ -1,24 +0,0 @@
//using System;
//using CoreNFC;
//using NFC;
//namespace Borepin.iOS.CNFC
//{
// public class Hardware : IHardware
// {
// public bool IsAvailable()
// {
// return NFCReaderSession.ReadingAvailable;
// }
// public String[] GetReaders()
// {
// return new String[] { "main" };
// }
// public IReader OpenReader(String readerID)
// {
// return new Reader();
// }
// }
//}

View File

@ -1,66 +0,0 @@
//using System;
//using CoreFoundation;
//using CoreNFC;
//using Foundation;
//using NFC;
//namespace Borepin.iOS.CNFC
//{
// public class Reader : NFCTagReaderSessionDelegate, IReader
// {
// public event ReaderEventHandler CardDiscovered;
// public event ReaderEventHandler CardLost;
// private NFCReaderSession _session = null;
// private DispatchQueue _queue;
// public void Start()
// {
// _queue = new DispatchQueue("NFC Reader Queue", true);
// // sessions cannot be reused
// _session = new NFCTagReaderSession(NFCPollingOption.Iso14443, this, _queue)
// {
// AlertMessage = "TODO",
// };
// if (_session == null)
// {
// Console.WriteLine("Oh no! The session is null!");
// }
// _session.BeginSession();
// }
// public void Stop()
// {
// _session?.InvalidateSession();
// _session = null;
// }
// public override void DidDetectTags(NFCTagReaderSession session, INFCTag[] tags)
// {
// Console.WriteLine("Did detect tags");
// Console.WriteLine(tags[0].Type);
// //INFCIso7816Tag tag = tags[0].GetNFCIso7816Tag();
// INFCMiFareTag tag = tags[0].GetNFCMiFareTag();
// if (tag != null)
// {
// Console.WriteLine("Card ist valid");
// CardDiscovered?.Invoke(this, new Card(session, tag));
// }
// else
// {
// Console.WriteLine("Card is not ISO7816");
// }
// }
// public override void DidInvalidate(NFCTagReaderSession session, NSError error)
// {
// // TODO: decide what to do
// Console.WriteLine("reader session invalidated");
// }
// }
//}

View File

@ -1,44 +0,0 @@
using System;
namespace NFC.Crypto
{
/// <summary>
/// CRC16 for DESFire Card
/// </summary>
public class CRC16
{
public UInt16 Polynomial { get; } = 0x8408;
public UInt16 InitValue { get; } = 0x6363;
public UInt16 Calculate(byte[] data, UInt16 crc16)
{
for (int i = 0; i < data.Length; i++)
{
crc16 ^= data[i];
for (int b = 0; b < 8; b++)
{
bool b_Bit = (crc16 & 0x01) > 0;
crc16 >>= 1;
if (b_Bit)
{
crc16 ^= Polynomial;
}
}
}
return crc16;
}
public byte[] Calculate(params byte[][] data)
{
UInt16 crc16 = InitValue;
foreach(byte[] d in data)
{
crc16 = Calculate(d, crc16);
}
return BitConverter.GetBytes(crc16);
}
}
}

View File

@ -1,44 +0,0 @@
using System;
namespace NFC.Crypto
{
/// <summary>
/// CRC32 for DESFire Card
/// </summary>
public class CRC32
{
public UInt32 Polynomial { get; } = 0xEDB88320;
public UInt32 InitValue { get; } = 0xFFFFFFFF;
public UInt32 Calculate(byte[] data, UInt32 crc32)
{
for (int i = 0; i < data.Length; i++)
{
crc32 ^= data[i];
for (int b = 0; b < 8; b++)
{
bool b_Bit = (crc32 & 0x01) > 0;
crc32 >>= 1;
if (b_Bit)
{
crc32 ^= Polynomial;
}
}
}
return crc32;
}
public byte[] Calculate(params byte[][] data)
{
UInt32 crc32 = InitValue;
foreach(byte[] d in data)
{
crc32 = Calculate(d, crc32);
}
return BitConverter.GetBytes(crc32);
}
}
}

View File

@ -1,48 +0,0 @@
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
namespace NFC.Crypto
{
public class AES : ICipher
{
public uint BlockSize { get; } = 16;
public uint KeySize { get; } = 16;
public byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
{
AesEngine engine = new AesEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
BufferedBlockCipher cipher = new BufferedBlockCipher(blockCipher);
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv);
// Encrypt
cipher.Init(true, keyParamWithIV);
byte[] outputBytes = new byte[cipher.GetOutputSize(data.Length)];
int length = cipher.ProcessBytes(data, outputBytes, 0);
cipher.DoFinal(outputBytes, length);
return outputBytes;
}
public byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
{
AesEngine engine = new AesEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
BufferedBlockCipher cipher = new BufferedBlockCipher(blockCipher);
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv);
// Decrypt
cipher.Init(false, keyParamWithIV);
byte[] outputBytes = new byte[cipher.GetOutputSize(data.Length)];
int length = cipher.ProcessBytes(data, outputBytes, 0);
cipher.DoFinal(outputBytes, length);
return outputBytes;
}
}
}

View File

@ -1,49 +0,0 @@
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
namespace NFC.Crypto
{
public class TDES : ICipher
{
public uint BlockSize { get; } = 8;
// Two times the DES Key
public uint KeySize { get; } = 16;
public byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
{
DesEngine engine = new DesEdeEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
BufferedBlockCipher cipher = new BufferedBlockCipher(blockCipher);
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv);
// Encrypt
cipher.Init(true, keyParamWithIV);
byte[] outputBytes = new byte[cipher.GetOutputSize(data.Length)];
int length = cipher.ProcessBytes(data, outputBytes, 0);
cipher.DoFinal(outputBytes, length);
return outputBytes;
}
public byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
{
DesEngine engine = new DesEdeEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
BufferedBlockCipher cipher = new BufferedBlockCipher(blockCipher);
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv);
// Decrypt
cipher.Init(false, keyParamWithIV);
byte[] outputBytes = new byte[cipher.GetOutputSize(data.Length)];
int length = cipher.ProcessBytes(data, outputBytes, 0);
cipher.DoFinal(outputBytes, length);
return outputBytes;
}
}
}

View File

@ -1,48 +0,0 @@
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
namespace NFC.Crypto
{
public class TDES_2K : ICipher
{
public uint BlockSize { get; } = 8;
public uint KeySize { get; } = 16;
public byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
{
DesEngine engine = new DesEdeEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
BufferedBlockCipher cipher = new BufferedBlockCipher(blockCipher);
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv);
// Encrypt
cipher.Init(true, keyParamWithIV);
byte[] outputBytes = new byte[cipher.GetOutputSize(data.Length)];
int length = cipher.ProcessBytes(data, outputBytes, 0);
cipher.DoFinal(outputBytes, length);
return outputBytes;
}
public byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
{
DesEngine engine = new DesEdeEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
BufferedBlockCipher cipher = new BufferedBlockCipher(blockCipher);
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv);
// Decrypt
cipher.Init(false, keyParamWithIV);
byte[] outputBytes = new byte[cipher.GetOutputSize(data.Length)];
int length = cipher.ProcessBytes(data, outputBytes, 0);
cipher.DoFinal(outputBytes, length);
return outputBytes;
}
}
}

View File

@ -1,48 +0,0 @@
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
namespace NFC.Crypto
{
public class TDES_3K : ICipher
{
public uint BlockSize { get; } = 8;
public uint KeySize { get; } = 24;
public byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
{
DesEngine engine = new DesEdeEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
BufferedBlockCipher cipher = new BufferedBlockCipher(blockCipher);
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv);
// Encrypt
cipher.Init(true, keyParamWithIV);
byte[] outputBytes = new byte[cipher.GetOutputSize(data.Length)];
int length = cipher.ProcessBytes(data, outputBytes, 0);
cipher.DoFinal(outputBytes, length);
return outputBytes;
}
public byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
{
DesEngine engine = new DesEdeEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
BufferedBlockCipher cipher = new BufferedBlockCipher(blockCipher);
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv);
// Decrypt
cipher.Init(false, keyParamWithIV);
byte[] outputBytes = new byte[cipher.GetOutputSize(data.Length)];
int length = cipher.ProcessBytes(data, outputBytes, 0);
cipher.DoFinal(outputBytes, length);
return outputBytes;
}
}
}

View File

@ -1,182 +0,0 @@
using System;
namespace NFC.Crypto
{
/// <summary>
/// Key for DESFire Card
/// </summary>
public class CipherKey
{
#region Constructors
/// <summary>
/// Creates Key from Array
/// </summary>
/// <param name="key">Key</param>
/// <param name="cipher">Cipher for Key</param>
/// <param name="keyVersion">Version of Key</param>
public CipherKey(byte[] key, CipherType cipher, byte keyVersion)
{
_Cipher = cipher;
if (cipher == CipherType.AES && keyVersion < 0x10)
{
throw new ArgumentOutOfRangeException("KeyVersion is to low for AES Key (Minimum = 0x10)");
}
_KeyVersion = keyVersion;
if (!CheckKey(key, cipher))
{
throw new ArgumentException("Key is not vaild for CipherType");
}
if (cipher == CipherType.TDES || cipher == CipherType.TDES_2K || cipher == CipherType.TDES_3K)
{
_Key = SetKeyVersion(key, keyVersion);
}
else
{
_Key = key;
}
}
/// <summary>
/// Creates Key from String
/// </summary>
/// <param name="key">Key</param>
/// <param name="cipher">Cipher for Key</param>
/// <param name="keyVersion">Version of Key</param>
public CipherKey(string key, CipherType cipher, byte keyVersion) : this(HexConverter.ConvertFromHexString(key), cipher, keyVersion)
{
}
/// <summary>
/// Generates Empty Key
/// </summary>
/// <param name="cipher">Cipher for Key</param>
/// <param name="keyVerion"></param>
public CipherKey(CipherType cipher)
{
_Cipher = cipher;
_Key = GenerateEmptyKey(cipher);
if (cipher == CipherType.AES)
{
_KeyVersion = 0x10;
}
else
{
_KeyVersion = 0x00;
}
}
#endregion
#region Properties
/// <summary>
/// Key as Array
/// </summary>
public byte[] _Key { get; private set; }
/// <summary>
/// CipherType of Key
/// </summary>
public CipherType _Cipher { get; private set; }
/// <summary>
/// KeyVersion of Key
/// For AES 0x10 is minimum
/// </summary>
public byte _KeyVersion { get; private set; }
#endregion
#region Methods
/// <summary>
/// Generate Empty Key for CipherType
/// </summary>
/// <param name="cipher">Type of Cipher</param>
public byte[] GenerateEmptyKey(CipherType cipher)
{
uint size = GetKeySize(cipher);
byte[] key = new byte[size];
for (int i = 0; i < size; i++)
{
key[i] = 0;
}
return key;
}
/// <summary>
/// Check Key Array
/// </summary>
/// <param name="key">Key</param>
/// <param name="cipher">Cipher Type of Key</param>
public bool CheckKey(byte[] key, CipherType cipher)
{
if (key.Length != GetKeySize(cipher))
{
return false;
}
else
{
return true;
}
}
/// <summary>
/// Get KeySize for CipherType
/// </summary>
/// <param name="cipher">Type of Cipher</param>
public uint GetKeySize(CipherType cipher)
{
switch (cipher)
{
case CipherType.TDES:
return 16;
case CipherType.TDES_2K:
return 16;
case CipherType.TDES_3K:
return 24;
case CipherType.AES:
return 16;
default:
throw new ArgumentOutOfRangeException("Unknown CipherType.");
}
}
/// <summary>
/// Set Key Version for DES/TDES Keys
/// KeyVersion is stored in the LSBits of the first 8 Bytes
/// Parity Bits are not used from DESFire Cars
/// </summary>
/// <param name="key"></param>
/// <param name="version"></param>
/// <returns></returns>
public byte[] SetKeyVersion(byte[] key, byte version)
{
byte[] pow2 = new byte[]
{
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
};
byte[] new_key = new byte[key.Length];
key.CopyTo(new_key, 0);
for (int i = 0; i < 8; i++)
{
if ((version & pow2[i]) > 0)
{
new_key[i] = (byte)(new_key[5] | 0x01);
}
else
{
new_key[i] = (byte)(new_key[5] & 0x7F);
}
}
return new_key;
}
#endregion
}
}

View File

@ -1,25 +0,0 @@
namespace NFC.Crypto
{
public enum CipherType
{
/// <summary>
/// DES / Triple DES
/// </summary>
TDES,
/// <summary>
/// Triple DES with 2 DES Keys
/// </summary>
TDES_2K,
/// <summary>
/// Triple DES with 3 DES Keys
/// </summary>
TDES_3K,
/// <summary>
/// AES
/// </summary>
AES
}
}

View File

@ -1,32 +0,0 @@
namespace NFC.Crypto
{
public interface ICipher
{
/// <summary>
/// Size of Cipher Block in Byte
/// </summary>
public uint BlockSize { get; }
/// <summary>
/// Size of Key in Byte
/// </summary>
public uint KeySize { get; }
/// <summary>
/// Encrypt Data
/// </summary>
/// <param name="data">Data in BlockSize</param>
/// <param name="key">Key</param>
/// <param name="IV">Initialisation Vector</param>
/// <returns></returns>
public byte[] Encrypt(byte[] data, byte[] key, byte[] IV);
/// <summary>
/// Decrypt Data
/// </summary>
/// <param name="data">Data in BlockSize</param>
/// <param name="key">Key</param>
/// <param name="IV">Initialisation Vector</param>
public byte[] Decrypt(byte[] data, byte[] key, byte[] IV);
}
}

View File

@ -1,51 +0,0 @@
using System;
namespace NFC
{
/// <summary>
/// Converts to and from Byte Array from and to String
/// </summary>
public static class HexConverter
{
/// <summary>
/// Converts byte[] to string with HEX Code
/// No 0x is created
/// </summary>
/// <param name="data">Data</param>
public static string ConvertToHexString(byte[] data)
{
return BitConverter.ToString(data).Replace("-", "").ToLower();
}
/// <summary>
/// Converts string with HEX Code to byte[]
/// No 0x is requiered
/// </summary>
/// <param name="data">Data</param>
public static byte[] ConvertFromHexString(string data)
{
if (data.Length % 2 == 1)
throw new Exception("Data Length is uneven.");
byte[] arr = new byte[data.Length >> 1];
for (int i = 0; i < data.Length >> 1; ++i)
{
arr[i] = (byte)((GetHexVal(data[i << 1]) << 4) + (GetHexVal(data[(i << 1) + 1])));
}
return arr;
}
private static int GetHexVal(char hex)
{
int val = (int)hex;
//For uppercase A-F letters:
//return val - (val < 58 ? 48 : 55);
//For lowercase a-f letters:
//return val - (val < 58 ? 48 : 87);
//Or the two combined, but a bit slower:
return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
}
}
}

View File

@ -1,77 +0,0 @@
using System;
using NFC.ISO7816_4;
namespace NFC
{
/// <summary>
/// Abstract representation of the platform specific NFC Hardware.
/// </summary>
public interface IHardware
{
/// <summary>
/// Check if the device has nfc support.
/// </summary>
/// <returns>Returns true if the device supports NFC.</returns>
bool IsAvailable();
/// <returns>Returns all available readers.</returns>
string[] GetReaders();
/// <summary>
/// Create a new reader instance from the specified id.
/// </summary>
/// <returns>Returns the spatform specific reader that corresponds to the id.</returns>
/// <exception cref="ArgumentException">Invalid reader id.</exception>
IReader OpenReader(string readerID);
}
public delegate void ReaderEventHandler(object sender, ICard card);
/// <summary>
/// Abstraction of a platform-specifc reader that can communicate with NFC cards.
/// </summary>
public interface IReader
{
/// <summary>
/// Event that will be called when a new tag was discovered.
/// </summary>
event ReaderEventHandler CardDiscovered;
/// <summary>
/// Event that will be called when a tag that is in use gets disconnected.
/// </summary>
event ReaderEventHandler CardLost;
void Start();
void Stop();
}
public interface ICard
{
/// <summary>
/// Connect to Smartcard
/// </summary>
void Connect();
/// <summary>
/// Disconnect from Smartcard
/// </summary>
void Disconnect();
/// <summary>
/// Transmit APDU Command to Smartcard
/// </summary>
/// <param name="apdu_cmd">Application Protocol Data Unit Command - ISO 7816</param>
/// <returns>Application Protocol Data Unit Response - ISO 7816</returns>
APDUResponse Transmit(APDUCommand apdu_cmd);
}
public class ReaderUnavailableException : Exception { }
public class CardUnavailableException : Exception { }
public class APDUException : Exception {
public readonly byte ResponseCode;
}
}

View File

@ -1,83 +0,0 @@
using PCSC;
using PCSC.Iso7816;
using System;
using System.Linq;
namespace NFC.ISO7816_4
{
public class APDUCommand : CommandApdu
{
public APDUCommand(IsoCase isoCase) : base(isoCase, SCardProtocol.Any)
{
}
public override bool Equals(object obj)
{
return obj is APDUCommand command &&
Case == command.Case &&
Protocol == command.Protocol &&
CLA == command.CLA &&
INS == command.INS &&
P1 == command.P1 &&
P2 == command.P2 &&
Data.SequenceEqual(command.Data) &&
Le == command.Le;
}
public override int GetHashCode()
{
HashCode hash = new HashCode();
hash.Add(Case);
hash.Add(Protocol);
hash.Add(IsValid);
hash.Add(CLA);
hash.Add(INS);
hash.Add(P1);
hash.Add(P2);
hash.Add(P1P2);
hash.Add(Data);
hash.Add(Lc);
hash.Add(P3);
hash.Add(Le);
hash.Add(ExpectedResponseLength);
hash.Add(IsValid);
return hash.ToHashCode();
}
public static bool operator ==(APDUCommand obj1, APDUCommand obj2)
{
return obj1.Equals(obj2);
}
public static bool operator !=(APDUCommand obj1, APDUCommand obj2)
{
return !(obj1.Equals(obj2));
}
public override string ToString()
{
string pattern_case1 = "(CASE: 1) CLA: 0x{0:x} | INS: 0x{1:x} | P1: 0x{2:x} | P2: 0x{3:x}";
string pattern_case2 = "(CASE: 2) CLA: 0x{0:x} | INS: 0x{1:x} | P1: 0x{2:x} | P2: 0x{3:x} | LE: 0x{4:x} |";
string pattern_case3 = "(CASE: 3) CLA: 0x{0:x} | INS: 0x{1:x} | P1: 0x{2:x} | P2: 0x{3:x} | LC: 0x{4:x} | Data: {5:x}";
string pattern_case4 = "(CASE: 4) CLA: 0x{0:x} | INS: 0x{1:x} | P1: 0x{2:x} | P2: 0x{3:x} | LC: 0x{4:x} | Data: {5:x} | LE: 0x{6:x} |";
switch (Case)
{
case IsoCase.Case1:
return string.Format(pattern_case1, CLA, INS, P1, P2);
case IsoCase.Case2Short:
case IsoCase.Case2Extended:
return string.Format(pattern_case2, CLA, INS, P1, P2, Le);
case IsoCase.Case3Short:
case IsoCase.Case3Extended:
return string.Format(pattern_case3, CLA, INS, P1, P2, Lc, BitConverter.ToString(Data).Replace("-", "").ToLower());
case IsoCase.Case4Short:
case IsoCase.Case4Extended:
return string.Format(pattern_case4, CLA, INS, P1, P2, Lc, BitConverter.ToString(Data).Replace("-", "").ToLower(), Le);
default:
throw new Exception("Unknown IsoCase");
}
}
}
}

View File

@ -1,161 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NFC.Mifare_DESFire;
namespace NFC.ISO7816_4
{
public class APDUResponse
{
#region constructor
public APDUResponse()
{
}
/// <summary>
/// Creates a new APDUResponse from the raw received data.
/// </summary>
public APDUResponse(byte[] raw)
{
Body = raw.Take(raw.Length - 1).ToArray();
SW1 = raw[raw.Length - 2];
SW2 = raw[raw.Length - 3];
}
#endregion
#region Properties
/// <summary>
/// ISO 7816-4-4 - Body - Body
/// </summary>
public byte[] Body { get; set; }
/// <summary>
/// ISO 7816-4 - SW1 - Status Word 1
/// </summary>
public byte SW1 { get; set; }
/// <summary>
/// ISO 7816-4 - SW2 - Status Word 2
/// </summary>
public byte SW2 { get; set; }
public APDUStatusWords StatusWord
{
get
{
// Some status words only require a specific first byte
// and in some cases SW2 contains additional information.
// This will filter out those errors. When there is more information separate methods for getting those are available.
switch(SW1) {
case 0x61:
// Kommando erfolgreich ausgeführt. xx Datenbytes können mit dem GET RESPONSE-Kommando abgeholt werden. Statuswort zur Steuerung des T=0-Protokolls
return APDUStatusWords.DATA_READY;
case 0x62:
// Warnung; Zustand des nichtflüchtigen Speichers nicht verändert
return APDUStatusWords.STORAGE_NOT_CHANGED;
case 0x63:
if((SW2 & 0xF0) == 0xC0) {
// Zähler hat den Wert x erreicht (die genaue Bedeutung ist vom Kommando abhängig)
return APDUStatusWords.COUNTER_REACHED;
}
// Warnung; Zustand des nichtflüchtigen Speichers verändert
return APDUStatusWords.STORAGE_CHANGED;
case 0x64:
// Ausführungsfehler; Zustand des nichtflüchtigen Speichers nicht verändert
return APDUStatusWords.EXECUTION_ERROR_WITHOUT_CHANGE;
case 0x65:
// Ausführungsfehler; Zustand des nichtflüchtigen Speichers verändert
return APDUStatusWords.EXECUTION_ERROR_WITH_CHANGE;
case 0x6C:
// Falsche Länge Le; xx gibt die korrekte Länge an Statuswort zur Steuerung des T=0-Protokolls
return APDUStatusWords.INVALID_LE;
}
return (APDUStatusWords) (((UInt16) SW1) << 8 | ((UInt16) SW2));
}
}
/// <summary>
/// If the reponse status is DATA_READY this method can be used to get the amount of data that can be read from the card.
/// </summary>
public byte DataLength
{
get
{
return SW2;
}
}
/// <summary>
/// If the reponse status is COUNTER_REACHED this method can be used to get the value that the counter reached.
/// </summary>
public byte Counter
{
get
{
return (byte)(SW2 & 0x0F);
}
}
/// <summary>
/// If the reponse status is INVALID_LE this method can be used to get the correct LE.
/// </summary>
public byte CorrectLE
{
get
{
return SW2;
}
}
#endregion
#region Methodes
public byte[] ToArray()
{
byte[] array = null;
if (Body != null)
{
array = new byte[Body.Length + 2];
Body.CopyTo(array, 0);
array[Body.Length] = SW1;
array[Body.Length + 1] = SW2;
}
else
{
array = new byte[2];
array[0] = SW1;
array[1] = SW2;
}
return array;
}
public override bool Equals(object obj)
{
return obj is APDUResponse response &&
EqualityComparer<byte[]>.Default.Equals(Body, response.Body) &&
SW1 == response.SW1 &&
SW2 == response.SW2;
}
public override int GetHashCode()
{
return HashCode.Combine(Body, SW1, SW2);
}
public override string ToString()
{
if(Body == null)
{
return string.Format("SW1: 0x{0:x} | SW2: 0x{1:x}", SW1, SW2);
}
else
{
return string.Format("SW1: 0x{0:x} | SW2: 0x{1:x} | Body: {2:x}", SW1, SW2, BitConverter.ToString(Body).Replace("-", "").ToLower());
}
}
#endregion
}
}

View File

@ -1,212 +0,0 @@
using System;
namespace NFC.Mifare_DESFire
{
public enum APDUStatusWords : UInt16
{
/// <summary>
/// Kommando erfolgreich ausgeführt. xx Datenbytes können mit dem GET RESPONSE-Kommando abgeholt werden. Statuswort zur Steuerung des T=0-Protokolls
/// </summary>
DATA_READY = 0x6100,
/// <summary>
/// Die zurückgegebenen Daten können fehlerhaft sein.
/// </summary>
FAULTY_DATA = 0x6281,
/// <summary>
/// Da das Dateiende vorher erreicht wurde, konnten nur weniger als Le Bytes gelesen werden.
/// </summary>
UNEXPECTED_END_OF_FILE = 0x6282,
/// <summary>
/// Die ausgewählte Datei ist gesperrt (englisch invalidated, wörtlich „ungültig“).
/// </summary>
INVALIDATED_FILE = 0x6283,
/// <summary>
/// Die File Control Information (FCI) ist inkonform zu ISO 7816-4.
/// </summary>
FCI_NOT_CONFORM = 0x6284,
/// <summary>
/// Warnung; Zustand des nichtflüchtigen Speichers nicht verändert
/// </summary>
STORAGE_NOT_CHANGED = 0x6200,
/// <summary>
/// Zähler hat den Wert x erreicht (die genaue Bedeutung ist vom Kommando abhängig)
/// </summary>
COUNTER_REACHED = 0x63C0,
/// <summary>
/// Warnung; Zustand des nichtflüchtigen Speichers verändert
/// </summary>
STORAGE_CHANGED = 0x6300,
/// <summary>
/// Ausführungsfehler; Zustand des nichtflüchtigen Speichers nicht verändert
/// </summary>
EXECUTION_ERROR_WITHOUT_CHANGE = 0x6400,
/// <summary>
/// Speicherfehler
/// </summary>
MEMORY_ERROR = 0x6581,
/// <summary>
/// Ausführungsfehler; Zustand des nichtflüchtigen Speichers verändert
/// </summary>
EXECUTION_ERROR_WITH_CHANGE = 0x6500,
/// <summary>
/// Befehlslänge (Lc) oder erwartete Antwortlänge (Le) falsch
/// </summary>
INVALID_LC_LE = 0x6700,
/// <summary>
/// Funktionen im Class-Byte werden nicht unterstützt
/// </summary>
CLASS_FEATURE_NOT_SUPPORTED = 0x6800,
/// <summary>
/// Logische Kanäle werden nicht unterstützt
/// </summary>
LOGIC_CHANNEL_NOT_SUPPORTED = 0x6881,
/// <summary>
/// Secure Messaging wird nicht unterstützt
/// </summary>
SECURE_MESSAGING_NOT_SUPPORTED = 0x6882,
/// <summary>
/// Kommando nicht erlaubt
/// </summary>
COMMAND_NOT_ALLOWED = 0x6900,
/// <summary>
/// Kommando inkompatibel zur Dateistruktur
/// </summary>
COMMAND_INCOMPATIBLE = 0x6981,
/// <summary>
/// Sicherheitszustand nicht erfüllt
/// </summary>
SAFETY_STATUS_NOT_FULFILLED = 0x6982,
/// <summary>
/// Authentisierungsmethode ist gesperrt
/// </summary>
AUTHENTICATION_METHOD_LOCKED = 0x6983,
/// <summary>
/// Referenzierte Daten sind gesperrt
/// </summary>
REFERENCED_FILE_LOCKED = 0x6984,
/// <summary>
/// Nutzungsbedingungen sind nicht erfüllt
/// </summary>
TERMS_OF_SERVICE_NOT_FULFILLED = 0x6985,
/// <summary>
/// Kommando nicht erlaubt (kein EF selektiert)
/// </summary>
COMMAND_NOT_ALLOWED_NO_EF_SELECTED = 0x6986,
/// <summary>
/// Erwartete Secure-Messaging-Objekte nicht gefunden
/// </summary>
EXPECTED_SECURE_MESSAGING_OBJECTS_NOT_FOUND = 0x6987,
/// <summary>
/// Secure-Messaging-Datenobjekte sind inkorrekt
/// </summary>
INVALID_SECURE_MESSAGING_OBJECTS = 0x6988,
/// <summary>
/// Falsche Parameter P1/P2
/// </summary>
WRONG_PARAMETERS = 0x6A00,
/// <summary>
/// Falsche Daten
/// </summary>
WRONG_DATA = 0x6A80,
/// <summary>
/// Funktion wird nicht unterstützt
/// </summary>
FEATURE_NOT_SUPPORTED = 0x6A81,
/// <summary>
/// Datei wurde nicht gefunden
/// </summary>
FILE_NOT_FOUND = 0x6A82,
/// <summary>
/// Datensatz (engl. record) der Datei nicht gefunden
/// </summary>
RECORD_NOT_FOUND = 0x6A83,
/// <summary>
/// Nicht genügend Speicherplatz in der Datei
/// </summary>
INSUFFICIENT_SPACE = 0x6A84,
/// <summary>
/// Lc nicht konsistent mit der TLV-Struktur
/// </summary>
LC_TLV_INCONSISTENT = 0x6A85,
/// <summary>
/// Inkorrekte Parameter P1/P2
/// </summary>
INCORRECT_PARAMETERs = 0x6A86,
/// <summary>
/// Lc inkonsistent mit P1/P2
/// </summary>
LC_PARAMETERS_INCONSISTENT = 0x6A87,
/// <summary>
/// Referenzierte Daten nicht gefunden
/// </summary>
REFERENCED_FILE_NOT_FOUND = 0x6A88,
/// <summary>
/// Parameter P1/P2 falsch
/// </summary>
WRONG_PARAMETERS_2 = 0x6B00,
/// <summary>
/// Falsche Länge Le; xx gibt die korrekte Länge an Statuswort zur Steuerung des T=0-Protokolls
/// </summary>
INVALID_LE = 0x6C00,
/// <summary>
/// Das Kommando (INS) wird nicht unterstützt
/// </summary>
INSTRUCTION_NOT_SUPPORTED = 0x6D00,
/// <summary>
/// Die Kommandoklasse (CLA) wird nicht unterstützt
/// </summary>
CLASS_NOT_SUPPORTED = 0x6E00,
/// <summary>
/// Kommando wurde mit unbekanntem Fehler abgebrochen
/// </summary>
UNKNOWN_ERROR = 0x6F00,
/// <summary>
/// Kommando erfolgreich ausgeführt
/// </summary>
SUCCESS = 0x9000,
/// <summary>
/// OK
/// </summary>
OK = 0x9100,
}
}

View File

@ -1,13 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="log4net" Version="2.0.12" />
<PackageReference Include="PCSC" Version="5.0.0" />
<PackageReference Include="PCSC.Iso7816" Version="5.0.0" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.9" />
</ItemGroup>
</Project>

View File

@ -1,44 +0,0 @@
namespace NFC.Mifare_DESFire
{
enum APDUInstructions : byte
{
AUTHENTICATE_ISO = 0x1A,
AUTHENTICATE_AES = 0xAA,
CHANGE_KEY_SETTINGS = 0x54,
SET_CONFIGURATION = 0x5C,
CHANGE_KEY = 0xC4,
GET_KEY_VERSION = 0x64,
CREATE_APPLICATION = 0xCA,
DELETE_APPLICATION = 0xDA,
GET_APPLICATION_IDS = 0x6A,
FREE_MEMORY = 0x6E,
GET_DF_NAMES = 0x6D,
GET_KEY_SETTINGS = 0x45,
SELECT_APPLICATION = 0x5A,
FORMAT_PICC = 0xFC,
GET_VERSION = 0x60,
GET_CARD_UID = 0x51,
GET_FILE_IDS = 0x6F,
GET_FILE_SETTINGS = 0xF5,
CHANGE_FILE_SETTINGS = 0x5F,
CREATE_STDDATAFILE = 0xCD,
CREATE_BACKUPDATAFILE = 0xCB,
CREATE_VALUE_FILE = 0xCC,
CREATE_LINEAR_RECORD_FILE = 0xC1,
CREATE_CYCLIC_RECORD_FILE = 0xC0,
DELETE_FILE = 0xDF,
GET_ISO_FILE_IDS = 0x61,
READ_DATA = 0xBD,
WRITE_DATA = 0x3D,
GET_VALUE = 0x6C,
CREDIT = 0x0C,
DEBIT = 0xDC,
LIMITED_CREDIT = 0x1C,
WRITE_RECORD = 0x3B,
READ_RECORDS = 0xBB,
CLEAR_RECORD_FILE = 0xEB,
COMMIT_TRANSACTION = 0xC7,
ABORT_TRANSACTION = 0xA7,
CONTINUE = 0xAF,
}
}

View File

@ -1,30 +0,0 @@
using System;
namespace NFC.Mifare_DESFire
{
public enum APDUStatusCodes : UInt16
{
OPERATION_OK = 0x9000, // = Successful operation
NO_CHANGES = 0x900C, // = No changes done to backup files, CommitTransaction / AbortTransaction not necessary
OUT_OF_EEPROM_ERROR = 0x900E, // = Insufficient NV-Memory to complete command
ILLEGAL_COMMAND_CODE = 0x901C, // = Command code not supported
INTEGRITY_ERROR = 0x901E, // = CRC or MAC does not match data Padding bytes not valid
NO_SUCH_KEY = 0x9040, // = Invalid key number specified
LENGTH_ERROR = 0x907E, // = Length of command string invalid
PERMISSION_DENIED = 0x909D, // = Current configuration / status does not allow the requested command
PARAMETER_ERROR = 0x909E, // = Value of the parameter(s) invalid
APPLICATION_NOT_FOUND = 0x90A0, // = Requested AID not present on PICC
APPL_INTEGRITY_ERROR = 0x90A1, // = Unrecoverable error within application, application will be disabled
AUTHENTICATION_ERROR = 0x90AE, // = Current authentication status does not allow the requested command
ADDITIONAL_FRAME = 0x90AF, // = Additional data frame is expected to be sent
BOUNDARY_ERROR = 0x90BE, // = Attempt to read/write data from/to beyond the file\'s/record\'s limits. Attempt to exceed the limits of a value file.
PICC_INTEGRITY_ERROR = 0x90C1, // = Unrecoverable error within PICC, PICC will be disabled
COMMAND_ABORTED = 0x90CA, // = Previous Command was not fully completed Not all Frames were requested or provided by the PCD
PICC_DISABLED_ERROR = 0x90CD, // = PICC was disabled by an unrecoverable error
COUNT_ERROR = 0x90CE, // = Number of Applications limited to 28, no additional CreateApplication possible
DUPLICATE_ERROR = 0x90DE, // = Creation of file/application failed because file/application with same number already exists
EEPROM_ERROR = 0x90EE, // = Could not complete NV-write operation due to loss of power, internal backup/rollback mechanism activated
FILE_NOT_FOUND = 0x90F0, // = Specified file number does not exist
FILE_INTEGRITY_ERROR = 0x90F1, // = Unrecoverable error within file, file will be disabled
}
}

View File

@ -1,21 +0,0 @@
namespace NFC.Mifare_DESFire.Enums
{
/// <summary>
/// hold the Access Rights for changing application keys (Change Key command)
/// </summary>
public enum ChangeApplicationKey : byte
{
/// <summary>
/// Application master key authentication is necessary to change any key (default)
/// </summary>
MASTERKEY = 0x00,
/// <summary>
/// Authentication with the key to be changed (same Key#) is necessary to change a key
/// </summary>
SAMEKEY = 0x0E,
/// <summary>
/// All keys (except application master key, see Bit 0) within this application are frozen
/// </summary>
ALLKEYS = 0x0F
}
}

View File

@ -1,18 +0,0 @@
namespace NFC.Mifare_DESFire.Enums
{
/// <summary>
/// codes whether the application master key is changeable
/// </summary>
public enum ChangeMasterKey : byte
{
/// <summary>
/// Application master key is not changeable anymore (frozen)
/// </summary>
FROZEN = 0x00,
/// <summary>
/// Application master key is changeable (authentication with the current application master key necessary, default)
/// </summary>
CHANGEABLE = 0x01,
}
}

View File

@ -1,19 +0,0 @@
namespace NFC.Mifare_DESFire.Enums
{
/// <summary>
/// codes whether a change of the application master key settings is allowed
/// </summary>
public enum ChangeMasterKeySettings : byte
{
/// <summary>
/// configuration not changeable anymore (frozen)
/// </summary>
FROZEN = 0x00,
/// <summary>
/// this configuration is changeable if authenticated with the application master key (default)
/// </summary>
WITHMASTERKEY = 0x08
}
}

View File

@ -1,18 +0,0 @@
namespace NFC.Mifare_DESFire.Enums
{
/// <summary>
/// codes whether application master key authentication is needed before “Create File” / “Delete File”
/// </summary>
public enum CreateDeleteFile : byte
{
/// <summary>
/// “Create File”/ “Delete File”is permitted only with application master key authentication
/// </summary>
ONLYMASTERKEY = 0x00,
/// <summary>
/// “Create File”/ “Delete File”is permitted also without application master key authentication (default)
/// </summary>
NOKEY = 0x04,
}
}

View File

@ -1,12 +0,0 @@
namespace NFC.Mifare_DESFire.Enums
{
/// <summary>
/// Crypto method of the application
/// </summary>
public enum CryptoOperationsType : byte
{
TDES = 0x00,
TKTDES = 0x40,
AES = 0x80,
}
}

View File

@ -1,8 +0,0 @@
namespace NFC.Mifare_DESFire.Enums
{
public enum FileAccessRights : byte
{
FREE = 0x0E,
NEVER = 0x0F
}
}

View File

@ -1,20 +0,0 @@
namespace NFC.Mifare_DESFire.Enums
{
public enum FileCommunication : byte
{
/// <summary>
/// "Plain communication"
/// </summary>
PLAIN = 0x00,
/// <summary>
/// Plain communication secured by DES/3DES MACing
/// </summary>
MAC = 0x01,
/// <summary>
/// Fully DES/3DES enciphered communication
/// </summary>
ENCRYPT = 0x03
}
}

View File

@ -1,18 +0,0 @@
namespace NFC.Mifare_DESFire.Enums
{
/// <summary>
/// codes whether application master key authentication is needed for file directory access
/// </summary>
public enum FileDirectoryAccess : byte
{
/// <summary>
/// Successful application master key authentication is required for executing the “Get FID List”, “Get File Settings”and “Get Key Settings”commands
/// </summary>
ONLYMASTERKEY = 0x00,
/// <summary>
/// “Get FID List”, “Get File Settings” and “Get Key Settings” commands succeed independentlyof a preceding application master key authentication (default)
/// </summary>
NOKEY = 0x02,
}
}

View File

@ -1,11 +0,0 @@
namespace NFC.Mifare_DESFire.Enums
{
/// <summary>
/// Indicates use of 2 byte ISO/IEC 7816-4 File Identifies for files within the Application
/// </summary>
public enum FileIdentifies : byte
{
NOTUSED = 0x00,
USED = 0x20
}
}

View File

@ -1,30 +0,0 @@
namespace NFC.Mifare_DESFire.Enums
{
enum FileTypes : byte
{
/// <summary>
/// Standard Data File
/// </summary>
STANDARD = 0x00,
/// <summary>
/// Backup Data Files
/// </summary>
BACKUP = 0x01,
/// <summary>
/// Value Files with Backup
/// </summary>
VALUE = 0x02,
/// <summary>
/// Linear Record Files with Backup
/// </summary>
LINEARRECORD = 0x03,
/// <summary>
/// Cyclic Record Files with Backup
/// </summary>
CYCLICRECORD = 0x04
}
}

View File

@ -1,26 +0,0 @@
using System;
namespace NFC.NXP_MIFARE_DESFire.Exceptions
{
/// <summary>
/// Currently not allowed to authenticate. Keeptrying until full delay is spent.
/// 0x91AD
/// </summary>
public class AuthenticationDelayException : Exception
{
public AuthenticationDelayException()
{
}
public AuthenticationDelayException(string message) : base(message)
{
}
public AuthenticationDelayException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,26 +0,0 @@
using System;
namespace NFC.NXP_MIFARE_DESFire.Exceptions
{
/// <summary>
/// Current authentication status does not allow there- quested command.
/// 0x91AE
/// </summary>
public class AuthenticationErrorException : Exception
{
public AuthenticationErrorException()
{
}
public AuthenticationErrorException(string message) : base(message)
{
}
public AuthenticationErrorException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,26 +0,0 @@
using System;
namespace NFC.NXP_MIFARE_DESFire.Exceptions
{
/// <summary>
/// Current authentication status does not allow there- quested command.
/// 0x91AE
/// </summary>
public class AuthenticationMissingException : Exception
{
public AuthenticationMissingException()
{
}
public AuthenticationMissingException(string message) : base(message)
{
}
public AuthenticationMissingException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,26 +0,0 @@
using System;
namespace NFC.NXP_MIFARE_DESFire.Exceptions
{
/// <summary>
/// Attempt toread/write data from/to beyond thefiles/records limits. Attempt to exceed the limitsof a value file.
/// 0x91BE
/// </summary>
public class BoundaryErrorException : Exception
{
public BoundaryErrorException()
{
}
public BoundaryErrorException(string message) : base(message)
{
}
public BoundaryErrorException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,26 +0,0 @@
using System;
namespace NFC.NXP_MIFARE_DESFire.Exceptions
{
/// <summary>
/// Previous Command was not fully completed.Not all Frames were requested or provided bythe PCD.
/// 0x91CA
/// </summary>
public class CommandAbortedException : Exception
{
public CommandAbortedException()
{
}
public CommandAbortedException(string message) : base(message)
{
}
public CommandAbortedException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,26 +0,0 @@
using System;
namespace NFC.NXP_MIFARE_DESFire.Exceptions
{
/// <summary>
/// Creation of file/application failed because file/application with same number already exists
/// 0x91DE
/// </summary>
public class DuplicateErrorException : Exception
{
public DuplicateErrorException()
{
}
public DuplicateErrorException(string message) : base(message)
{
}
public DuplicateErrorException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,26 +0,0 @@
using System;
namespace NFC.NXP_MIFARE_DESFire.Exceptions
{
/// <summary>
/// Specified file number does not exist.
/// 0x91F0
/// </summary>
public class FileNotFoundException : Exception
{
public FileNotFoundException()
{
}
public FileNotFoundException(string message) : base(message)
{
}
public FileNotFoundException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,26 +0,0 @@
using System;
namespace NFC.NXP_MIFARE_DESFire.Exceptions
{
/// <summary>
/// Command code not supported.
/// 0x911C
/// </summary>
public class IllegalCommandCodeException : Exception
{
public IllegalCommandCodeException()
{
}
public IllegalCommandCodeException(string message) : base(message)
{
}
public IllegalCommandCodeException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,26 +0,0 @@
using System;
namespace NFC.NXP_MIFARE_DESFire.Exceptions
{
/// <summary>
/// CRC or MAC does not match data. Paddingbytes not valid.
/// 0x911E
/// </summary>
public class IntegrityErrorException : Exception
{
public IntegrityErrorException()
{
}
public IntegrityErrorException(string message) : base(message)
{
}
public IntegrityErrorException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,26 +0,0 @@
using System;
namespace NFC.NXP_MIFARE_DESFire.Exceptions
{
/// <summary>
/// Length of command string invalid.
/// 0x917E
/// </summary>
public class LengthErrorException : Exception
{
public LengthErrorException()
{
}
public LengthErrorException(string message) : base(message)
{
}
public LengthErrorException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,26 +0,0 @@
using System;
namespace NFC.NXP_MIFARE_DESFire.Exceptions
{
/// <summary>
/// Invalid key number specified.
/// 0x9140
/// </summary>
public class NoSuchKeyException : Exception
{
public NoSuchKeyException()
{
}
public NoSuchKeyException(string message) : base(message)
{
}
public NoSuchKeyException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,26 +0,0 @@
using System;
namespace NFC.NXP_MIFARE_DESFire.Exceptions
{
/// <summary>
/// Value of the parameter(s) invalid.
/// 0x919E
/// </summary>
public class ParameterErrorException : Exception
{
public ParameterErrorException()
{
}
public ParameterErrorException(string message) : base(message)
{
}
public ParameterErrorException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,26 +0,0 @@
using System;
namespace NFC.NXP_MIFARE_DESFire.Exceptions
{
/// <summary>
/// Current configuration / status does not allow the requested command.
/// 0x919D
/// </summary>
public class PermissionDeniedException : Exception
{
public PermissionDeniedException()
{
}
public PermissionDeniedException(string message) : base(message)
{
}
public PermissionDeniedException(string message, Exception inner) : base(message, inner)
{
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,53 +0,0 @@
using PCSC;
using PCSC.Iso7816;
using NFC.ISO7816_4;
namespace NFC.Readers.PCSC
{
public class Card : ICard
{
private IsoReader _ISOReader;
private string _ReaderID;
public Card(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)
{
CommandApdu apdu = (CommandApdu)apdu_cmd;
return apdu;
}
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;
}
}
}

View File

@ -1,33 +0,0 @@
using PCSC;
namespace NFC.Readers.PCSC
{
public class PCSC_Hardware : 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 PCSC_Reader(readerID);
}
}
}

View File

@ -1,49 +0,0 @@
using PCSC;
using PCSC.Iso7816;
using System;
namespace NFC.Readers.PCSC
{
public class PCSC_Reader : IReader, IDisposable
{
private string _ReaderID;
private IContextFactory _ContextFactory;
private ISCardContext _SCardContext;
private IsoReader _ISOReader;
private ICard _Card;
public PCSC_Reader(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(_ISOReader, _ReaderID);
CardDiscovered?.Invoke(this, _Card);
}
public void Stop()
{
CardLost?.Invoke(this, _Card);
_ISOReader.Dispose();
_SCardContext.Dispose();
}
}
}

View File

@ -1,24 +0,0 @@
using NFC;
using NFC.Crypto;
using NUnit.Framework;
namespace NFC_Unit_Test.Crypto
{
[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);
}
}
}

View File

@ -1,23 +0,0 @@
using NFC;
using NFC.Crypto;
using NUnit.Framework;
namespace NFC_Unit_Test.Crypto
{
[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);
}
}
}

View File

@ -1,22 +0,0 @@
using NFC;
using NFC.Crypto;
using NUnit.Framework;
namespace NFC_Unit_Test.Crypto
{
[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);
}
}
}

View File

@ -1,10 +0,0 @@
using NUnit.Framework;
namespace NFC_Unit_Test.Crypto
{
[TestFixture]
public class CipherKey_Test
{
}
}

View File

@ -1,55 +0,0 @@
using NFC;
using NFC.Crypto;
using NUnit.Framework;
namespace NFC_Unit_Test.Crypto
{
[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);
}
}
}

View File

@ -1,34 +0,0 @@
using NFC;
using NUnit.Framework;
namespace NFC_Unit_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));
}
}
}

View File

@ -1,119 +0,0 @@
using System;
using NFC.ISO7816_4;
using NUnit.Framework;
using PCSC.Iso7816;
namespace NFC_Unit_Test.ISO7816_4
{
[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());
}
}
}

View File

@ -1,18 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.0" />
<PackageReference Include="NSubstitute" Version="4.2.2" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NFC\NFC.csproj" />
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +0,0 @@
using log4net.Config;
using NUnit.Framework;
namespace NFC_Unit_Test
{
/// <summary>
/// Add log4net Output to Console Out
/// </summary>
[SetUpFixture]
public class NamespaceSetUp
{
[OneTimeSetUp]
public void OneTimeSetUp()
{
BasicConfigurator.Configure();
}
}
}
namespace NFC_Real_Test
{
/// <summary>
/// Add log4net Output to Console Out
/// </summary>
[SetUpFixture]
public class NamespaceSetUp
{
[OneTimeSetUp]
public void OneTimeSetUp()
{
BasicConfigurator.Configure();
}
}
}

View File

@ -1,477 +0,0 @@
using NFC;
using NFC.Crypto;
using NFC.Mifare_DESFire;
using NFC.Mifare_DESFire.Enums;
using NFC.Readers.PCSC;
using NUnit.Framework;
using System;
using System.Text;
namespace NFC_Real_Test
{
/// <summary>
/// Test all DESFire Commands with an Empty Card
/// The Test are ordered to check the Commands one by one
/// </summary>
[TestFixture, Explicit]
public class REAL_DESFireCommands
{
/// <summary>
/// Set ReaderID for PCSC Interface
/// You can get the ID from REAL_Reader_PCSC
/// </summary>
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 PCSC_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, Order(2)]
public void Authenticate_DES()
{
IHardware hardware = new PCSC_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, Order(3)]
public void Format()
{
IHardware hardware = new PCSC_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);
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 PCSC_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);
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 PCSC_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);
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 PCSC_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);
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 PCSC_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);
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 PCSC_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);
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 PCSC_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);
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 PCSC_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);
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;
}
}
}

View File

@ -1,130 +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;
using NFC.Crypto;
namespace NFC_Real_Test
{
[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);
/// <summary>
/// Create FabAccess Application and UserData File
/// </summary>
[Test, Order(1)]
public void Init_EmptyCard()
{
IHardware hardware = new PCSC_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_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;
}
/// <summary>
/// Authenticate with UserData File and AuthKey
/// </summary>
[Test, Order(2)]
public void Authenticate()
{
IHardware hardware = new PCSC_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);
transmit_successfully = true;
card.Disconnect();
};
reader.CardDiscovered += handler;
reader.Start();
Assert.AreEqual(true, transmit_successfully);
reader.Stop();
reader.CardDiscovered -= handler;
}
}
}

View File

@ -1,62 +0,0 @@
using NFC;
using NFC.Readers.PCSC;
using NUnit.Framework;
using System;
namespace NFC_Real_Test
{
[TestFixture, Explicit]
public class REAL_Reader_PCSC
{
/// <summary>
/// Print PCSC ReaderIDs to Console Out
/// </summary>
[Test]
public void GetReaders()
{
IHardware hardware = new PCSC_Hardware();
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);
}
}
}
/// <summary>
/// Connect to specific PCSC Reader by ReaderID
/// </summary>
/// <param name="readerID">ReaderID from GetReaders</param>
[TestCase("ACS ACR122U PICC Interface 0")]
public void Connect(string readerID)
{
IHardware hardware = new PCSC_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;
}
}
}