protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
            var deviceInfo = await SmartCardReaderUtils.GetDefaultSmartCardReaderInfo();

            if (deviceInfo == null)
            {
                LogMessage("NFC card reader mode not supported on this device", NotifyType.ErrorMessage);
                return;
            }

            if (!deviceInfo.IsEnabled)
            {
                var msgbox = new Windows.UI.Popups.MessageDialog("Your NFC proximity setting is turned off, you will be taken to the NFC proximity control panel to turn it on");
                msgbox.Commands.Add(new Windows.UI.Popups.UICommand("OK"));
                await msgbox.ShowAsync();

                // This URI will navigate the user to the NFC proximity control panel
                NfcUtils.LaunchNfcProximitySettingsPage();
                return;
            }

            if (m_cardReader == null)
            {
                m_cardReader = await SmartCardReader.FromIdAsync(deviceInfo.Id);

                m_cardReader.CardAdded   += cardReader_CardAdded;
                m_cardReader.CardRemoved += cardReader_CardRemoved;
            }
        }
Example #2
0
        private byte[] BuildReadRecordResponseV(string track2, string cardholderName, string track1Discretionary)
        {
            if (track2.Length % 2 != 0)
            {
                track2 += "F";
            }

            return(new TlvEntry(0x70, new TlvEntry[] {
                new TlvEntry(0x57, NfcUtils.HexStringToBytes(track2)),
                new TlvEntry(0x5F20, cardholderName),
                new TlvEntry(0x9F1F, track1Discretionary),
            }).GetData(0x9000));
        }
        private async void btnRegisterBgTask_Click(object sender, RoutedEventArgs e)
        {
            // Clear the messages
            rootPage.NotifyUser(String.Empty, NotifyType.StatusMessage, true);

            // First check if the device supports NFC/HCE at all
            if (!(await NfcUtils.CheckHceSupport()))
            {
                // HCE not supported
                return;
            }

            // Register the background task which gets launched to handle and respond to incoming APDUs
            await NfcUtils.GetOrRegisterHceBackgroundTask("NFC HCE Sample - Activated", "NfcHceBackgroundTask.BgTask", SmartCardTriggerType.EmulatorHostApplicationActivated);

            // Register the background task which gets launched when our registration state changes (for example the user changes which card is the payment default in the control panel, or another app causes us to be disabled due to an AID conflict)
            await NfcUtils.GetOrRegisterHceBackgroundTask("NFC HCE Sample - Registration Changed", "NfcHceBackgroundTask.BgTask", SmartCardTriggerType.EmulatorAppletIdGroupRegistrationChanged);
        }
        private async void btnForegroundOverrideCard_Click(object sender, RoutedEventArgs e)
        {
            // Clear the messages
            rootPage.NotifyUser(String.Empty, NotifyType.StatusMessage, true);

            var reg = (SmartCardAppletIdGroupRegistration)lstCards.SelectedItem;

            if (reg == null)
            {
                LogMessage("No card selected, must select from listbox", NotifyType.ErrorMessage);
                return;
            }

            await NfcUtils.SetCardActivationPolicy(reg, SmartCardAppletIdGroupActivationPolicy.ForegroundOverride);

            // Refresh the listbox
            lstCards.ItemsSource = await SmartCardEmulator.GetAppletIdGroupRegistrationsAsync();
        }
        private async void btnAddCard_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            // Clear the messages
            MainPage.Current.NotifyUser(String.Empty, NotifyType.StatusMessage, true);

            // Register the AID/applet IDs that this application will handle for our particular card(s)
            var reg = await NfcUtils.RegisterAidGroup(txtDisplayName.Text, new[] { AID_PPSE.AsBuffer(), AID_SAMPLE_CARD.AsBuffer() }, SmartCardEmulationCategory.Payment, SmartCardEmulationType.Host, (chkAutomaticEnablement.IsChecked ?? false));

            var track2          = txtPAN.Text + "D" + txtExpiryYear.Text + txtExpiryMonth.Text + txtServiceCode.Text + txtTrack2Discretionary.Text;
            var record          = BuildReadRecordResponse(track2, txtCardholderName.Text, txtTrack1Discretionary.Text);
            var encryptedRecord = await ProtectDataAsync(record, "LOCAL=user");

            var file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync("ReadRecordResponse-" + reg.Id.ToString("B") + ".dat", Windows.Storage.CreationCollisionOption.ReplaceExisting);

            await Windows.Storage.FileIO.WriteBufferAsync(file, encryptedRecord);

            LogMessage("Card data saved", NotifyType.StatusMessage);
            this.Frame.GoBack();
        }
Example #6
0
        private byte[] BuildReadRecordResponseMC(string pan, string exp, string serviceCode, string cardholderName, string track1Discretionary, string track2Discretionary)
        {
            var track1 = "B" + pan + "^" + cardholderName + "^" + exp + serviceCode + track1Discretionary;
            var track2 = pan + "D" + exp + serviceCode + track2Discretionary;

            if (track2.Length % 2 != 0)
            {
                track2 += "F";
            }

            return(new TlvEntry(0x70, new TlvEntry[] {
                // Magstripe version
                new TlvEntry(0x9F6C, new byte[] { 0x00, 0x01 }),

                // Track 1 data
                new TlvEntry(0x56, System.Text.Encoding.UTF8.GetBytes(track1)),

                // Track 1 bit map for CVC3
                new TlvEntry(0x9F62, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E }),

                // Track 1 bit map for UN and ATC
                new TlvEntry(0x9F63, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }),

                // Track 1 number of ATC digits
                new TlvEntry(0x9F64, new byte[] { 0x00 }),

                // Track 2 data
                new TlvEntry(0x9F6B, NfcUtils.HexStringToBytes(track2)),

                // Track 2 bit map for CVC3
                new TlvEntry(0x9F65, new byte[] { 0x00, 0x0E }),

                // Track 2 bit map for UN and ATC
                new TlvEntry(0x9F66, new byte[] { 0x00, 0x00 }),

                // Track 2 number of ATC digits
                new TlvEntry(0x9F67, new byte[] { 0x00 }),

                // Magstripe CVM list
                new TlvEntry(0x9F68, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x03, 0x42, 0x03, 0x1F, 0x03 }),
            }).GetData(0x9000));
        }
        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
            // Clear the messages
            MainPage.Current.NotifyUser(String.Empty, NotifyType.StatusMessage, true);


            // First try to find a reader that advertises as being NFC
            var deviceInfo = await SmartCardReaderUtils.GetFirstSmartCardReaderInfo(SmartCardReaderKind.Nfc);

            if (deviceInfo == null)
            {
                // If we didn't find an NFC reader, let's see if there's a "generic" reader meaning we're not sure what type it is
                deviceInfo = await SmartCardReaderUtils.GetFirstSmartCardReaderInfo(SmartCardReaderKind.Any);
            }

            if (deviceInfo == null)
            {
                LogMessage("NFC card reader mode not supported on this device", NotifyType.ErrorMessage);
                return;
            }

            if (!deviceInfo.IsEnabled)
            {
                var msgbox = new Windows.UI.Popups.MessageDialog("Your NFC proximity setting is turned off, you will be taken to the NFC proximity control panel to turn it on");
                msgbox.Commands.Add(new Windows.UI.Popups.UICommand("OK"));
                await msgbox.ShowAsync();

                // This URI will navigate the user to the NFC proximity control panel
                NfcUtils.LaunchNfcProximitySettingsPage();
                return;
            }

            if (m_cardReader == null)
            {
                m_cardReader = await SmartCardReader.FromIdAsync(deviceInfo.Id);

                m_cardReader.CardAdded   += cardReader_CardAdded;
                m_cardReader.CardRemoved += cardReader_CardRemoved;
            }
        }
        private byte[] BuildReadRecordResponse(string track2, string cardholderName, string track1Discretionary)
        {
            if (track2.Length % 2 != 0)
            {
                track2 += "F";
            }
            // Calculate the card length in bytes (will always be an even number because of padded 'F')
            int trackTwoLength = track2.Length / 2;

            // read record tag + size = 2, track 2 tag and size = 2, cardholder name tag and size = 3,
            // track 1 discretionary tag and size = 3, status word = 2
            List <byte> readRecordResponse = new List <byte>(trackTwoLength + cardholderName.Length + track1Discretionary.Length + 12);

            // Add the response header
            readRecordResponse.Add((byte)0x70);                                                                              // Record template
            readRecordResponse.Add((byte)(2 + trackTwoLength + 3 + cardholderName.Length + 3 + track1Discretionary.Length)); // Data length plus size of tag and size
            readRecordResponse.Add((byte)0x57);                                                                              // Track 2 equivalent data
            readRecordResponse.Add((byte)trackTwoLength);                                                                    // Data length
            readRecordResponse.AddRange(NfcUtils.HexStringToBytes(track2));

            // Add the cardholder's name as ascii
            readRecordResponse.Add((byte)0x5F);                  // Tag cardholder name
            readRecordResponse.Add((byte)0x20);                  // Tag cardholder name
            readRecordResponse.Add((byte)cardholderName.Length); // Data length
            readRecordResponse.AddRange(System.Text.Encoding.UTF8.GetBytes(cardholderName));

            // Add track one discretionary data as ascii
            readRecordResponse.Add((byte)0x9F);
            readRecordResponse.Add((byte)0x1F);
            readRecordResponse.Add((byte)track1Discretionary.Length);
            readRecordResponse.AddRange(System.Text.Encoding.UTF8.GetBytes(track1Discretionary));

            // Add the result code
            readRecordResponse.Add((byte)0x90); // Status byte one (SW1)
            readRecordResponse.Add((byte)0x00); // Status byte two (SW2)

            return(readRecordResponse.ToArray());
        }
        private async void btnRegisterSamplePaymentCard_Click(object sender, RoutedEventArgs e)
        {
            // Clear the messages
            rootPage.NotifyUser(String.Empty, NotifyType.StatusMessage, true);

            // First check if the device supports NFC/HCE at all
            if (!(await NfcUtils.CheckHceSupport()))
            {
                // HCE not supported
                return;
            }

            // Next check if NFC card emualtion is turned on in the settings control panel
            if ((await SmartCardEmulator.GetDefaultAsync()).EnablementPolicy == SmartCardEmulatorEnablementPolicy.Never)
            {
                ShowDialog("Your NFC tap+pay setting is turned off, you will be taken to the NFC control panel to turn it on");

                // This URI will navigate the user to the NFC tap+pay control panel
                NfcUtils.LaunchNfcPaymentsSettingsPage();
                return;
            }

            this.Frame.Navigate(typeof(SetCardDataScenario));
        }
Example #10
0
        private async void btnAddCard_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            // Clear the messages
            MainPage.Current.NotifyUser(String.Empty, NotifyType.StatusMessage, true);

            // Register the AID/applet IDs that this application will handle for our particular card(s)
            SmartCardAppletIdGroupRegistration reg;

            if (optUICC.IsChecked ?? false)
            {
                reg = await NfcUtils.RegisterAidGroup(
                    txtDisplayName.Text,
                    new[] { AID_PPSE.AsBuffer(), AID_V.AsBuffer(), AID_MC.AsBuffer() },
                    SmartCardEmulationCategory.Payment,
                    SmartCardEmulationType.Uicc,
                    (chkAutomaticEnablement.IsChecked ?? false));
            }
            else if (optNonPayment.IsChecked ?? false)
            {
                reg = await NfcUtils.RegisterAidGroup(
                    txtDisplayName.Text,
                    new[] { AID_NONPAYMENT.AsBuffer() },
                    SmartCardEmulationCategory.Other,
                    SmartCardEmulationType.Host,
                    (chkAutomaticEnablement.IsChecked ?? false));

                var rule1 = new SmartCardAutomaticResponseApdu(NfcUtils.HexStringToBytes("0012AABB").AsBuffer(), NfcUtils.HexStringToBytes("AABBCCDDEE9000").AsBuffer());
                rule1.AppletId = AID_NONPAYMENT.AsBuffer();
                await reg.SetAutomaticResponseApdusAsync(new List <SmartCardAutomaticResponseApdu>() { rule1 });
            }
            else
            {
                var aid       = (optV.IsChecked ?? false) ? AID_V : AID_MC;
                var aidBuffer = aid.AsBuffer();
                reg = await NfcUtils.RegisterAidGroup(
                    txtDisplayName.Text,
                    new[] { AID_PPSE.AsBuffer(), aidBuffer },
                    SmartCardEmulationCategory.Payment,
                    SmartCardEmulationType.Host,
                    (chkAutomaticEnablement.IsChecked ?? false));

                var rules = new List <SmartCardAutomaticResponseApdu>();

                // Construct SELECT PPSE response and set as auto responder
                rules.Add(new SmartCardAutomaticResponseApdu(
                              new SelectCommand(AID_PPSE, 0x00).GetBuffer(),
                              new TlvEntry(0x6F, new TlvEntry[] {
                    new TlvEntry(0x84, "2PAY.SYS.DDF01"),
                    new TlvEntry(0xA5, new TlvEntry[] {
                        new TlvEntry(0xBF0C,
                                     new TlvEntry(0x61, new TlvEntry[] {
                            new TlvEntry(0x4F, aidBuffer),
                            new TlvEntry(0x87, new byte[] { 0x01 })
                        }))
                    })
                }).GetData(0x9000).AsBuffer()));

                // Construct SELECT AID response and set as auto responder
                rules.Add(new SmartCardAutomaticResponseApdu(
                              new SelectCommand(aid, 0x00).GetBuffer(),
                              new TlvEntry(0x6F, new TlvEntry[] {
                    new TlvEntry(0x84, aidBuffer),
                    new TlvEntry(0xA5, new TlvEntry[] {
                        new TlvEntry(0x50, "CREDIT CARD")
                    })
                }).GetData(0x9000).AsBuffer()));

                if (optMC.IsChecked ?? false)
                {
                    var ruleGpo = new SmartCardAutomaticResponseApdu(
                        NfcUtils.HexStringToBytes("80A80000").AsBuffer(),
                        new TlvEntry(0x77, new TlvEntry[] {
                        new TlvEntry(0x82, new byte[] { 0x00, 0x00 }),
                        new TlvEntry(0x94, new byte[] { 0x08, 0x01, 0x01, 0x00 }),
                        new TlvEntry(0xD7, new byte[] { 0x00, 0x00, 0x80 })
                    }).GetData(0x9000).AsBuffer());
                    ruleGpo.AppletId          = aidBuffer;
                    ruleGpo.ShouldMatchLength = false;
                    rules.Add(ruleGpo);
                }
                else if (optV.IsChecked ?? false)
                {
                    var ruleGpo = new SmartCardAutomaticResponseApdu(
                        NfcUtils.HexStringToBytes("80A80000").AsBuffer(),
                        new TlvEntry(0x80, new byte[] { 0x00, 0x80, 0x08, 0x01, 0x01, 0x00 }).GetData(0x9000).AsBuffer());
                    ruleGpo.AppletId          = aidBuffer;
                    ruleGpo.ShouldMatchLength = false;
                    rules.Add(ruleGpo);
                }

                byte[] record;
                if (optV.IsChecked ?? false)
                {
                    var track2 = txtPAN.Text + "D" + txtExpiryYear.Text + txtExpiryMonth.Text + txtServiceCode.Text + txtTrack2Discretionary.Text;
                    record = BuildReadRecordResponseV(track2, txtCardholderName.Text, txtTrack1Discretionary.Text);
                }
                else
                {
                    record = BuildReadRecordResponseMC(txtPAN.Text, txtExpiryYear.Text + txtExpiryMonth.Text, txtServiceCode.Text, txtCardholderName.Text, txtTrack1Discretionary.Text, txtTrack2Discretionary.Text);
                }

                var encryptedRecord = await ProtectDataAsync(record, "LOCAL=user");

                var file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync("ReadRecordResponse-" + reg.Id.ToString("B") + ".dat", Windows.Storage.CreationCollisionOption.ReplaceExisting);

                await Windows.Storage.FileIO.WriteBufferAsync(file, encryptedRecord);

                await reg.SetAutomaticResponseApdusAsync(rules);
            }

            LogMessage("Card data saved", NotifyType.StatusMessage);
            this.Frame.GoBack();
        }