diff --git a/Borepin/Borepin/Model/DESFireInterfaceDummy.cs b/Borepin/Borepin/Model/DESFireInterfaceDummy.cs new file mode 100644 index 0000000..ea982ae --- /dev/null +++ b/Borepin/Borepin/Model/DESFireInterfaceDummy.cs @@ -0,0 +1,63 @@ +using Borepin.Page; +using FabAccessAPI.Schema; +using ImTools; +using NFC.Helper; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Borepin.Model +{ + public class DESFireInterfaceDummy : User.ICardDESFireInterface + { + public Task Bind(IReadOnlyList token, IReadOnlyList auth_key, CancellationToken cancellationToken_ = default) + { + return Task.CompletedTask; + } + + public void Dispose() + { + + } + + public Task> GenCardToken(CancellationToken cancellationToken_ = default) + { + List token = new List(); + token.AddRange(HexConverter.ConvertFromHexString("11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11".Replace(" ", ""))); + return Task.FromResult((IReadOnlyList) token); + } + + public Task> GetMetaInfo(CancellationToken cancellationToken_ = default) + { + List data = new List(); + data.AddRange(Encoding.ASCII.GetBytes("FABACCESS\0DESFIRE\01.0\0").Append((byte)0x00)); + return Task.FromResult((IReadOnlyList)data); + } + + public Task> GetSpaceInfo(CancellationToken cancellationToken_ = default) + { + List data = new List(); + data.AddRange(Encoding.ASCII.GetBytes("urn:fabaccess:lab:fabaccess_test").Append((byte)0x00)); + return Task.FromResult((IReadOnlyList)data); + } + + public Task>> GetTokenList(CancellationToken cancellationToken_ = default) + { + List token = new List(); + token.AddRange(HexConverter.ConvertFromHexString("11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11".Replace(" ", ""))); + + IReadOnlyList> list = new List> + { + token + }; + return Task.FromResult(list); + } + + public Task Unbind(IReadOnlyList token, CancellationToken cancellationToken_ = default) + { + return Task.CompletedTask; + } + } +} diff --git a/Borepin/Borepin/Model/FabFireCard.cs b/Borepin/Borepin/Model/FabFireCard.cs index d4c2c94..0d5fb37 100644 --- a/Borepin/Borepin/Model/FabFireCard.cs +++ b/Borepin/Borepin/Model/FabFireCard.cs @@ -1,6 +1,11 @@ using Borepin.Service.ErrorMessage; +using NFC.Cards.NXP_MIFARE_DESFire; +using NFC.Cards.NXP_MIFARE_DESFire.Enums; +using NFC.Helper; +using NFC.Helper.Crypto; using NFC.Interfaces; using System; +using ZXing.Aztec.Internal; namespace Borepin.Model { @@ -20,14 +25,89 @@ namespace Borepin.Model #endregion #region Methods + /// + /// Format Card + /// + /// + /// public void FormatCard(string readerID, CardConfig cardConfig) { - throw new NotImplementedException(); + _NFCService.Connect(readerID); + + NXP_MIFARE_DESFire card = new NXP_MIFARE_DESFire(_NFCService); + card.SelectApplication(0x000000); + card.AuthenticateISO_DES(0x00, cardConfig.PICCKey); + card.Format(); + + _NFCService.Disconnect(); } - public void CreateCard(string readerID, CardConfig cardConfig) + /// + /// Create DESFire Card for V1.0 + /// + /// + /// + /// Key #1 for authentication + public byte[] CreateCard(string readerID, CardConfig cardConfig) { - throw new NotImplementedException(); + _NFCService.Connect(readerID); + + NXP_MIFARE_DESFire card = new NXP_MIFARE_DESFire(_NFCService); + + card.SelectApplication(0x000000); + + if(cardConfig.DoFormat) + { + card.AuthenticateISO_DES(0x00, new CipherKey(CipherType.TDES)); + } + else + { + card.AuthenticateISO_DES(0x00, cardConfig.PICCKey); + } + + byte keySettings1 = card.GenerateKeySetting1 + ( + 0x00, + ChangeMasterKeySettings.WITHMASTERKEY, + CreateDeleteFile.NOKEY, + FileDirectoryAccess.NOKEY, + ChangeMasterKey.CHANGEABLE + ); + + byte keySettings2 = card.GenerateKeySetting2 + ( + CryptoOperationsType.AES, + FileIdentifies.NOTUSED, + 0x02 + ); + + card.CreateApplication(0x464142, keySettings1, keySettings2); + + card.SelectApplication(0x464142); + card.AuthenticateISO_AES(0x00, new CipherKey(CipherType.AES)); + ushort file_access = card.GenerateFileAccessRights + ( + FileAccessRights.FREE, + 0x00, + 0x00, + 0x00 + ); + card.CreateFile_Standard(0x01, FileCommunication.PLAIN, file_access, cardConfig.MetaInfo.Length); + card.CreateFile_Standard(0x02, FileCommunication.PLAIN, file_access, cardConfig.SpaceInfo.Length); + card.CreateFile_Standard(0x03, FileCommunication.PLAIN, file_access, cardConfig.CardToken.Length); + + card.WriteData(0x00, 0x00, cardConfig.MetaInfo); + card.WriteData(0x00, 0x00, cardConfig.SpaceInfo); + card.WriteData(0x00, 0x00, cardConfig.CardToken); + + auth_key = cardConfig.GenerateRandomKey(); + + card.ChangeOtherKey_AES(0x01, auth_key, new CipherKey(CipherType.AES), 0x00); + card.ChangeKey_AES(0x00, cardConfig.APPKey, 0x00); + + _NFCService.Disconnect(); + + return auth_key; } #endregion } diff --git a/Borepin/Borepin/PageModel/CreateCardPageModel.cs b/Borepin/Borepin/PageModel/CreateCardPageModel.cs index 0ac1705..1dbfe5b 100644 --- a/Borepin/Borepin/PageModel/CreateCardPageModel.cs +++ b/Borepin/Borepin/PageModel/CreateCardPageModel.cs @@ -12,6 +12,8 @@ using System.Collections.Generic; using Borepin.Model; using Xamarin.Forms; using System; +using Borepin.Service.ErrorMessage; +using System.Linq; namespace Borepin.PageModel { @@ -21,15 +23,18 @@ namespace Borepin.PageModel private CardConfig _CardConfig; private User _User; private INFCService _NFCService; + private User.ICardDESFireInterface _CardDESFireInterface; + private IErrorMessageService _ErrorMessageService; private KeyTypes _ScanKeyType = KeyTypes.NONE; private KeyTypes _ScanedKeyType = KeyTypes.NONE; #endregion #region Contructors - public CreateCardPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService, INFCService nfcService) : base(navigationService, pageDialogService, apiService) + public CreateCardPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService, INFCService nfcService, IErrorMessageService errorMessageService) : base(navigationService, pageDialogService, apiService) { _NFCService = nfcService; + _ErrorMessageService = errorMessageService; _CardConfig= new CardConfig(); CreateCardCommand = new DelegateCommand(CreateCardCommandExecute); @@ -39,6 +44,9 @@ namespace Borepin.PageModel RandomAPPKeyCommand = new DelegateCommand(RandomAPPKeyCommandExecute); RefreshCommand = new DelegateCommand(async () => await RefreshCommandExecute().ConfigureAwait(true)); + + // TODO Use Server Interface + _CardDESFireInterface = new DESFireInterfaceDummy(); } #endregion @@ -230,7 +238,75 @@ namespace Borepin.PageModel { IsBusy = true; - await Task.Delay(1000).ConfigureAwait(false); + try + { + _CardConfig.PICCKey = _CardConfig.ConvertFromString(PICCKey); + } + catch + { + Device.BeginInvokeOnMainThread(async () => + { + await _PageDialogService.DisplayAlertAsync("NFC Error", "PICC Key invalid", Resources.Text.TextResource.OK).ConfigureAwait(false); + + IsBusy = false; + }); + return; + } + + try + { + _CardConfig.APPKey = _CardConfig.ConvertFromString(APPKey); + } + catch + { + Device.BeginInvokeOnMainThread(async () => + { + await _PageDialogService.DisplayAlertAsync("NFC Error", "APP Key invalid", Resources.Text.TextResource.OK).ConfigureAwait(false); + + IsBusy = false; + }); + return; + } + + _CardConfig.DoFormat = FormatCard; + + _CardConfig.CardToken = (await _CardDESFireInterface.GenCardToken().ConfigureAwait(false)).ToArray(); + _CardConfig.SpaceInfo = (await _CardDESFireInterface.GetSpaceInfo().ConfigureAwait(false)).ToArray(); + _CardConfig.MetaInfo = (await _CardDESFireInterface.GetMetaInfo().ConfigureAwait(false)).ToArray(); + + FabFireCard fabFireCard = new FabFireCard(_NFCService, _ErrorMessageService); + + try + { + if(FormatCard) + { + fabFireCard.FormatCard(ReaderID, _CardConfig); + } + } + catch + { + Device.BeginInvokeOnMainThread(async () => + { + await _PageDialogService.DisplayAlertAsync("NFC Error", "Format failed", Resources.Text.TextResource.OK).ConfigureAwait(false); + + IsBusy = false; + }); + } + + try + { + byte[] key = fabFireCard.CreateCard(ReaderID, _CardConfig); + await _CardDESFireInterface.Bind(_CardConfig.CardToken, new List(key)).ConfigureAwait(false); + } + catch + { + Device.BeginInvokeOnMainThread(async () => + { + await _PageDialogService.DisplayAlertAsync("NFC Error", "Card Creation failed", Resources.Text.TextResource.OK).ConfigureAwait(false); + + IsBusy = false; + }); + } IsBusy = false; } @@ -344,7 +420,6 @@ namespace Borepin.PageModel IsBusy = false; } #endregion - #endregion } }