示例#1
0
        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");
                    });
                }
            }
        }
示例#3
0
 public void OnTagRemoved()
 {
     try
     {
         isoDep.Close();
         OnCardRemovedFromField(new EventArgs());
     }
     catch (Exception e)
     {
         throw e;
     }
 }
示例#4
0
        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();
        }
示例#5
0
        /// <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();
            }
        }