public void StopApduOperations() { currentIsoDept?.Close(); currentIsoDept?.Dispose(); currentIsoDept = null; currentTag = null; currentIntent = null; }
public void OnTagDiscovered(Tag tag) { IsoDep isoDep = IsoDep.Get(tag); if (isoDep == null) { Console.WriteLine("[CODE] Unsupported Tag"); //navigator.failureNavigation("Unsupported Tag"); } else { Console.WriteLine("[CODE] IsoDep Found"); isoDep.Connect(); byte[] command = BuildSelectApdu(ACCESS_CARD_AID); //Once we find a tag, trancieve the command try { byte[] result = isoDep.Transceive(command); // If the matching AID is successfully found, 0x9000 is returned from the device as the status word (last 2 // bytes of the result) (0x9000 is the OK Status Word - this is returned if the phone is authorised and the scan was successful). Everything before the status word is // payload, in this case will be the user ID - this means result will be dynamic int resultLength = result.Length; byte[] statusWord = { result[resultLength - 2], result[resultLength - 1] }; //Grab last two bytes for the status word byte[] payload = new byte[resultLength - 2]; //Initialise empty array payload Array.Copy(result, payload, resultLength - 2); //We know the lengths, so copy from those indexes into a new array bool arrayEquals = SELECT_OK_SW.Length == statusWord.Length; for (int i = 0; i < SELECT_OK_SW.Length && i < statusWord.Length && arrayEquals; i++) { arrayEquals = (SELECT_OK_SW[i] == statusWord[i]); //Compare byte by byte, ISO-DEP communcation is in bytes - we're looking for 0x90, 0x00 if (!arrayEquals) { break; } } if (arrayEquals) //Only if the status word is OK, unauthenticated devices will not respond with the "OK" status { // The NFC device will respond with the userId as a payload string payloadString = System.Text.Encoding.UTF8.GetString(payload); Console.WriteLine($"Recieved Payload: {payloadString}"); OnPayloadReceived(payloadString); } } catch (TagLostException e) //If something happens or the tag moves away, this is thrown. Close communication and inform user that an error occurred { isoDep.Close(); Console.WriteLine("[CODE] Caught tag loss error"); Device.BeginInvokeOnMainThread(async() => { await Xamarin.Forms.Application.Current.MainPage.DisplayAlert("Error", $"Tag Lost Error", "OK"); }); } } }
public void OnTagRemoved() { try { isoDep.Close(); OnCardRemovedFromField(new EventArgs()); } catch (Exception e) { throw e; } }
protected override void OnNewIntent(Intent intent) { base.OnNewIntent(intent); Tag tag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag; SetResult(Result.Canceled, intent); if (tag != null) { IsoDep isoTag = IsoDep.Get(tag); try { isoTag.Connect(); isoTag.Timeout = 30000; byte[] resp = isoTag.Transceive(selectCommand); int length = resp.Length; if (resp[length - 2] == (byte)0x90 && resp[length - 1] == 0x00) { DoChallengeYubiKey(isoTag, slot, challenge); } else { Toast.MakeText(this, Resource.String.yubichallenge_tag_error, ToastLength.Long) .Show(); } isoTag.Close(); } catch (TagLostException e) { Toast.MakeText(this, Resource.String.yubichallenge_lost_tag, ToastLength.Long) .Show(); } catch (IOException e) { Toast.MakeText(this, GetString(Resource.String.yubichallenge_tag_error) + e.Message, ToastLength.Long).Show(); } } else { SetResult(Result.Canceled, intent); } Finish(); }
/// <summary> /// Reads the travel card data from HSL Mifare DESFire card. /// </summary> /// <param name="card">The card to try to read.</param> /// <returns>A deserialized Travel Card object if the card was valid, otherwise null.</returns> public static async Task <TravelCard> ReadTravelCardAsync(IsoDep card) { try { card.Connect(); byte[] selection = card.Transceive(HslCommands.SelectHslCommand); if (selection != null && selection.Length > 0 && selection.SequenceEqual(HslCommands.OkResponse)) { // Travel card info bytes byte[] appInfo = null; byte[] periodPass = null; byte[] storedValue = null; byte[] eTicket = null; byte[] history = null; // Temporary containers for history chunks byte[] hist1 = new byte[2]; byte[] hist2 = new byte[2]; appInfo = await card.TransceiveAsync(HslCommands.ReadAppInfoCommand); periodPass = await card.TransceiveAsync(HslCommands.ReadPeriodPassCommand); storedValue = await card.TransceiveAsync(HslCommands.ReadStoredValueCommand); eTicket = await card.TransceiveAsync(HslCommands.ReadETicketCommand); hist1 = await card.TransceiveAsync(HslCommands.ReadHistoryCommand); // If we have more history, the last two bytes of the history array will contain the MORE_DATA bytes. if (hist1.Skip(Math.Max(0, hist1.Length - 2)).ToArray() == HslCommands.MoreData) { hist2 = await card.TransceiveAsync(HslCommands.ReadNextCommand); } // Combine the two history chunks into a single array, minus their last two MORE_DATA bytes history = hist1.Take(hist1.Length - 2) .Concat(hist2.Take(hist2.Length - 2)).ToArray(); var rawCard = new RawTravelCard(appInfo, periodPass, storedValue, eTicket, history); if (rawCard.Status == CardStatus.HslCardDataFailure) { System.Diagnostics.Debug.WriteLine("Failed to construct travel card. Data appears to be invalid."); return(null); } else { return(new TravelCard(rawCard)); } } else { System.Diagnostics.Debug.WriteLine("Failed to construct travel card. This doesn't seem to be an HSL Travel card."); return(null); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("Failed to construct travel card. Reason: " + ex.ToString() + ".\nStack trace:" + ex.StackTrace); return(null); } finally { card.Close(); } }