mirror of
https://gitlab.com/fabinfra/fabaccess/nfc.git
synced 2025-03-12 14:51:51 +01:00
1137 lines
34 KiB
C#
1137 lines
34 KiB
C#
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<ArgumentNullException>(
|
|
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<Exception>(
|
|
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<IllegalCommandCodeException>(
|
|
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<IntegrityErrorException>(
|
|
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<NoSuchKeyException>(
|
|
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<LengthErrorException>(
|
|
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<PermissionDeniedException>(
|
|
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<ParameterErrorException>(
|
|
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<AuthenticationDelayException>(
|
|
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<AuthenticationErrorException>(
|
|
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<BoundaryErrorException>(
|
|
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<CommandAbortedException>(
|
|
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<DuplicateErrorException>(
|
|
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<FileNotFoundException>(
|
|
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<ArgumentException>(
|
|
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<ArgumentNullException>(
|
|
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<ArgumentNullException>(
|
|
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<ArgumentNullException>(
|
|
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<ArgumentNullException>(
|
|
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<ArgumentNullException>(
|
|
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<ArgumentNullException>(
|
|
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<ArgumentOutOfRangeException>(
|
|
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<ArgumentOutOfRangeException>(
|
|
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<ArgumentOutOfRangeException>(
|
|
delegate
|
|
{
|
|
desfire.GenerateFileAccessRights(0x10, 0x00, 0x00, 0x00);
|
|
});
|
|
}
|
|
#endregion
|
|
|
|
#region DESFire Commands
|
|
[Test]
|
|
public void SelectApplication()
|
|
{
|
|
ICard card = Substitute.For<ICard>();
|
|
|
|
NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card);
|
|
|
|
APDUResponse response = new APDUResponse()
|
|
{
|
|
SW1 = 0x91,
|
|
SW2 = 0x00
|
|
};
|
|
|
|
card.Transmit(Arg.Is<APDUCommand>(x => HexConverter.ConvertToHexString(x.ToArray()) == "905a00000333221100")).Returns(response);
|
|
|
|
desfire.SelectApplication(0x112233);
|
|
}
|
|
|
|
[Test]
|
|
public void SelectApplication_InvalidAID()
|
|
{
|
|
ICard card = Substitute.For<ICard>();
|
|
|
|
NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null);
|
|
|
|
Assert.Throws<ArgumentOutOfRangeException>(
|
|
delegate
|
|
{
|
|
desfire.SelectApplication(0xFF000000);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void AuthenticateISO_DES()
|
|
{
|
|
ICard card = Substitute.For<ICard>();
|
|
|
|
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<APDUCommand>(x => HexConverter.ConvertToHexString(x.ToArray()) == "901a0000010000")).Returns(response_challenge_request);
|
|
card.Transmit(Arg.Is<APDUCommand>(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<ArgumentOutOfRangeException>(
|
|
delegate
|
|
{
|
|
desfire.AuthenticateISO_DES(0x0F, null);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void Format()
|
|
{
|
|
ICard card = Substitute.For<ICard>();
|
|
|
|
NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card);
|
|
|
|
APDUResponse response = new APDUResponse()
|
|
{
|
|
SW1 = 0x91,
|
|
SW2 = 0x00
|
|
};
|
|
|
|
card.Transmit(Arg.Is<APDUCommand>(x => HexConverter.ConvertToHexString(x.ToArray()) == "90fc000000")).Returns(response);
|
|
|
|
desfire.Format();
|
|
}
|
|
|
|
[Test]
|
|
public void CreateApplication()
|
|
{
|
|
ICard card = Substitute.For<ICard>();
|
|
|
|
NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card);
|
|
|
|
APDUResponse response = new APDUResponse()
|
|
{
|
|
SW1 = 0x91,
|
|
SW2 = 0x00
|
|
};
|
|
|
|
card.Transmit(Arg.Is<APDUCommand>(x => HexConverter.ConvertToHexString(x.ToArray()) == "90ca000005eeffaa0b8200")).Returns(response);
|
|
|
|
desfire.CreateApplication(0xAAFFEE, 0x0b, 0x82);
|
|
}
|
|
|
|
[Test]
|
|
public void CreateApplication_InvalidAID()
|
|
{
|
|
ICard card = Substitute.For<ICard>();
|
|
|
|
NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(null);
|
|
|
|
Assert.Throws<ArgumentOutOfRangeException>(
|
|
delegate
|
|
{
|
|
desfire.CreateApplication(0xFF000000, 0x00, 0x00);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void AuthenticateISO_AES()
|
|
{
|
|
ICard card = Substitute.For<ICard>();
|
|
|
|
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<APDUCommand>(x => HexConverter.ConvertToHexString(x.ToArray()) == "90aa0000010000")).Returns(response_challenge_request);
|
|
card.Transmit(Arg.Is<APDUCommand>(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<ArgumentOutOfRangeException>(
|
|
delegate
|
|
{
|
|
desfire.AuthenticateISO_AES(0x0F, null);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ChangeKey_AES()
|
|
{
|
|
ICard card = Substitute.For<ICard>();
|
|
|
|
NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card);
|
|
|
|
APDUResponse response = new APDUResponse()
|
|
{
|
|
SW1 = 0x91,
|
|
SW2 = 0x00
|
|
};
|
|
|
|
card.Transmit(Arg.Is<APDUCommand>(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<ArgumentOutOfRangeException>(
|
|
delegate
|
|
{
|
|
desfire.ChangeKey_AES(0x0F, null, 0x10);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ChangeOtherKey_AES()
|
|
{
|
|
ICard card = Substitute.For<ICard>();
|
|
|
|
NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card);
|
|
|
|
APDUResponse response = new APDUResponse()
|
|
{
|
|
SW1 = 0x91,
|
|
SW2 = 0x00
|
|
};
|
|
|
|
card.Transmit(Arg.Is<APDUCommand>(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<ArgumentOutOfRangeException>(
|
|
delegate
|
|
{
|
|
desfire.ChangeKey_AES(0x0F, null, 0x10);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void CreateFile_Standard()
|
|
{
|
|
ICard card = Substitute.For<ICard>();
|
|
|
|
NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card);
|
|
|
|
APDUResponse response = new APDUResponse()
|
|
{
|
|
SW1 = 0x91,
|
|
SW2 = 0x00
|
|
};
|
|
|
|
card.Transmit(Arg.Is<APDUCommand>(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<ICard>();
|
|
|
|
NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card);
|
|
|
|
Assert.Throws<ArgumentOutOfRangeException>(
|
|
delegate
|
|
{
|
|
desfire.CreateFile_Standard(0x21, FileCommunication.PLAIN, 0x0000, 0xF0);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void WriteData()
|
|
{
|
|
ICard card = Substitute.For<ICard>();
|
|
|
|
NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card);
|
|
|
|
APDUResponse response = new APDUResponse()
|
|
{
|
|
SW1 = 0x91,
|
|
SW2 = 0x00
|
|
};
|
|
|
|
card.Transmit(Arg.Is<APDUCommand>(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<ICard>();
|
|
|
|
NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card);
|
|
|
|
APDUResponse response = new APDUResponse()
|
|
{
|
|
SW1 = 0x91,
|
|
SW2 = 0x00
|
|
};
|
|
|
|
card.Transmit(Arg.Is<APDUCommand>(x => HexConverter.ConvertToHexString(x.ToArray()) == "903d000036010000002f0000546573743132333454657374313233345465737431323334546573743132333454657374313233345465737431323300")).Returns(response);
|
|
card.Transmit(Arg.Is<APDUCommand>(x => HexConverter.ConvertToHexString(x.ToArray()) == "903d000036012f00002f0000345465737431323334546573743132333454657374313233345465737431323334546573743132333454657374313200")).Returns(response);
|
|
card.Transmit(Arg.Is<APDUCommand>(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<ICard>();
|
|
|
|
NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card);
|
|
|
|
Assert.Throws<ArgumentOutOfRangeException>(
|
|
delegate
|
|
{
|
|
desfire.WriteData(0x21, 0x00, Encoding.ASCII.GetBytes("Test1234"));
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ReadData()
|
|
{
|
|
ICard card = Substitute.For<ICard>();
|
|
|
|
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<APDUCommand>(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<ICard>();
|
|
|
|
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<APDUCommand>(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<ICard>();
|
|
|
|
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<APDUCommand>(x => HexConverter.ConvertToHexString(x.ToArray()) == "90bd000007010000002f000000")).Returns(response_1);
|
|
card.Transmit(Arg.Is<APDUCommand>(x => HexConverter.ConvertToHexString(x.ToArray()) == "90bd000007012f00002f000000")).Returns(response_2);
|
|
card.Transmit(Arg.Is<APDUCommand>(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<ICard>();
|
|
|
|
NXP_MIFARE_DESFire desfire = new NXP_MIFARE_DESFire(card);
|
|
|
|
Assert.Throws<ArgumentOutOfRangeException>(
|
|
delegate
|
|
{
|
|
desfire.ReadData(0x21, 0x00, 0x20);
|
|
});
|
|
}
|
|
#endregion
|
|
}
|
|
}
|