/// <summary>
        /// Click handler for the 'ResetPin' button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void ResetPin_Click(object sender, RoutedEventArgs e)
        {
            if (!rootPage.ValidateTPMSmartCard())
            {
                rootPage.NotifyUser("Use Scenario One to create a TPM virtual smart card.", NotifyType.ErrorMessage);
                return;
            }

            Button b = sender as Button;

            b.IsEnabled = false;

            try
            {
                SmartCard card = await rootPage.GetSmartCard();

                SmartCardProvisioning provisioning = await SmartCardProvisioning.FromSmartCardAsync(card);

                rootPage.NotifyUser("Resetting smart card PIN...", NotifyType.StatusMessage);

                // When requesting a PIN reset, a SmartCardPinResetHandler must be
                // provided as an argument.  This handler must use the challenge
                // it receives and the card's admin key to calculate and set the
                // response.
                bool result = await provisioning.RequestPinResetAsync(
                    (pinResetSender, request) =>
                {
                    SmartCardPinResetDeferral deferral = request.GetDeferral();

                    try
                    {
                        IBuffer response = ChallengeResponseAlgorithm.CalculateResponse(request.Challenge, rootPage.AdminKey);
                        request.SetResponse(response);
                    }
                    finally
                    {
                        deferral.Complete();
                    }
                });

                if (result)
                {
                    rootPage.NotifyUser("Smart card PIN reset operation completed.", NotifyType.StatusMessage);
                }
                else
                {
                    rootPage.NotifyUser("Smart card PIN reset operation was canceled by the user.", NotifyType.StatusMessage);
                }
            }
            catch (Exception ex)
            {
                rootPage.NotifyUser("Resetting smart card PIN failed with exception: " + ex.ToString(), NotifyType.ErrorMessage);
            }
            finally
            {
                b.IsEnabled = true;
            }
        }
        /// <summary>
        /// Click handler for the 'ChangeAdminKey' button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void ChangeAdminKey_Click(object sender, RoutedEventArgs e)
        {
            if (!rootPage.ValidateTPMSmartCard())
            {
                rootPage.NotifyUser(
                    "Use Scenario One to create a TPM virtual smart card.",
                    NotifyType.ErrorMessage);
                return;
            }

            Button b = sender as Button;

            b.IsEnabled = false;

            try
            {
                IBuffer newadminkey = CryptographicBuffer.GenerateRandom(
                    MainPage.ADMIN_KEY_LENGTH_IN_BYTES);

                SmartCard card = await rootPage.GetSmartCard();

                SmartCardProvisioning provisioning =
                    await SmartCardProvisioning.FromSmartCardAsync(card);

                rootPage.NotifyUser("Changing smart card admin key...",
                                    NotifyType.StatusMessage);

                using (SmartCardChallengeContext context =
                           await provisioning.GetChallengeContextAsync())
                {
                    IBuffer response =
                        ChallengeResponseAlgorithm.CalculateResponse(
                            context.Challenge, rootPage.AdminKey);

                    await context.ChangeAdministrativeKeyAsync(response,
                                                               newadminkey);

                    rootPage.AdminKey = newadminkey;
                }

                rootPage.NotifyUser(
                    "Smart card change admin key operation completed.",
                    NotifyType.StatusMessage);
            }
            catch (Exception ex)
            {
                rootPage.NotifyUser(
                    "Changing smart card admin key operation failed " +
                    "with exception: " +
                    ex.ToString(),
                    NotifyType.ErrorMessage);
            }
            finally
            {
                b.IsEnabled = true;
            }
        }
        /// <summary>
        /// Click handler for the 'VerifyResponse' button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void VerifyResponse_Click(object sender, RoutedEventArgs e)
        {
            if (!rootPage.ValidateTPMSmartCard())
            {
                rootPage.NotifyUser(
                    "Use Scenario One to create a TPM virtual smart card.",
                    NotifyType.ErrorMessage);
                return;
            }

            Button b = sender as Button;

            b.IsEnabled = false;

            try
            {
                bool      verifyResult = false;
                SmartCard card         = await rootPage.GetSmartCard();

                SmartCardProvisioning provisioning =
                    await SmartCardProvisioning.FromSmartCardAsync(card);

                rootPage.NotifyUser("Verifying smart card response...",
                                    NotifyType.StatusMessage);

                using (SmartCardChallengeContext context =
                           await provisioning.GetChallengeContextAsync())
                {
                    IBuffer response = ChallengeResponseAlgorithm.CalculateResponse(
                        context.Challenge,
                        rootPage.AdminKey);

                    verifyResult = await context.VerifyResponseAsync(response);
                }

                rootPage.NotifyUser(
                    "Smart card response verification completed. Result: " +
                    verifyResult.ToString(),
                    NotifyType.StatusMessage);
            }
            catch (Exception ex)
            {
                rootPage.NotifyUser(
                    "Verifying smart card response operation failed " +
                    "with exception: " +
                    ex.ToString(),
                    NotifyType.ErrorMessage);
            }
            finally
            {
                b.IsEnabled = true;
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Click handler for the 'ChangePin' button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void ChangePin_Click(object sender, RoutedEventArgs e)
        {
            if (!rootPage.ValidateTPMSmartCard())
            {
                rootPage.NotifyUser(
                    "Use Scenario One to create a TPM virtual smart card.",
                    NotifyType.ErrorMessage);
                return;
            }

            Button b = sender as Button;

            b.IsEnabled = false;

            try
            {
                SmartCard card = await rootPage.GetSmartCard();

                SmartCardProvisioning provisioning =
                    await SmartCardProvisioning.FromSmartCardAsync(card);

                rootPage.NotifyUser("Changing smart card PIN...",
                                    NotifyType.StatusMessage);

                bool result = await provisioning.RequestPinChangeAsync();

                if (result)
                {
                    rootPage.NotifyUser(
                        "Smart card change PIN operation completed.",
                        NotifyType.StatusMessage);
                }
                else
                {
                    rootPage.NotifyUser(
                        "Smart card change PIN operation was canceled by " +
                        "the user.",
                        NotifyType.StatusMessage);
                }
            }
            catch (Exception ex)
            {
                rootPage.NotifyUser(
                    "Changing smart card PIN failed with exception: " +
                    ex.ToString(),
                    NotifyType.ErrorMessage);
            }
            finally
            {
                b.IsEnabled = true;
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Click handler for the 'ListSmartCard' button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void ListSmartCard_Click(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;

            b.IsEnabled = false;
            try
            {
                rootPage.NotifyUser("Enumerating smart cards...", NotifyType.StatusMessage);

                // This list will be bound to our ItemListView once it has been
                // filled with SmartCardListItems.  The SmartCardListItem class
                // is defined above, and describes a reader/card pair with a
                // reader name and a card name.
                List <SmartCardListItem> cardItems = new List <SmartCardListItem>();

                // First we get the device selector for smart card readers using
                // the static GetDeviceSelector method of the SmartCardReader
                // class.  The selector is a string which describes a class of
                // devices to query for, and is used as the argument to
                // DeviceInformation.FindAllAsync.  GetDeviceSelector is
                // overloaded so that you can provide a SmartCardReaderKind
                // to specify if you are only interested in a particular type
                // of card/reader (e.g. TPM virtual smart card.)  In this case
                // we will list all cards and readers.
                string selector = SmartCardReader.GetDeviceSelector();
                DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(selector);

                // DeviceInformation.FindAllAsync gives us a
                // DeviceInformationCollection, which is essentially a list
                // of DeviceInformation objects.  We must iterate through that
                // list and instantiate SmartCardReader objects from the
                // DeviceInformation objects.
                foreach (DeviceInformation device in devices)
                {
                    SmartCardReader reader = await SmartCardReader.FromIdAsync(device.Id);

                    // For each reader, we want to find all the cards associated
                    // with it.  Then we will create a SmartCardListItem for
                    // each (reader, card) pair.
                    IReadOnlyList <SmartCard> cards = await reader.FindAllCardsAsync();

                    foreach (SmartCard card in cards)
                    {
                        SmartCardProvisioning provisioning = await SmartCardProvisioning.FromSmartCardAsync(card);

                        SmartCardListItem item = new SmartCardListItem()
                        {
                            ReaderName = card.Reader.Name,
                            CardName   = await provisioning.GetNameAsync()
                        };

                        cardItems.Add(item);
                    }
                }

                // Bind the source of ItemListView to our SmartCardListItem list.
                ItemListView.ItemsSource = cardItems;

                rootPage.NotifyUser("Enumerating smart cards completed.", NotifyType.StatusMessage);
            }
            catch (Exception ex)
            {
                rootPage.NotifyUser("Enumerating smart cards failed with exception: " + ex.ToString(), NotifyType.ErrorMessage);
            }
            finally
            {
                b.IsEnabled = true;
            }
        }
Exemplo n.º 6
0
        public static async Task RegisterDevice_Click(string deviceFriendlyName)
        {
            String  deviceId  = "";
            IBuffer deviceKey = CryptographicBuffer.GenerateRandom(32);
            IBuffer authKey   = CryptographicBuffer.GenerateRandom(32);

            byte[] deviceKeyArray            = new byte[32];
            byte[] authKeyArray              = new byte[32];
            byte[] deviceIdArray             = new byte[16];
            byte[] deviceDlockState          = new byte[1];
            byte[] response                  = { 0 };
            int    numberOfDevices           = 0;
            int    numberOfRegisteredDevices = 0;
            string sw1sw2 = null;
            //byte[] combinedDataArray = new byte[64];
            string NanosATR          = "3b00";
            String deviceModelNumber = "0001";
            //List<SmartCardListItem> cardItems = new List<SmartCardListItem>();
            MessageDialog myDlg;

            bool isSupported;

            isSupported = await KeyCredentialManager.IsSupportedAsync();

            if (!isSupported)
            {
                var    loader = new Windows.ApplicationModel.Resources.ResourceLoader();
                string PleaseSetUpPinContent = loader.GetString("PleaseSetupPin_content_error");
                string PleaseSetUpPinTitle   = loader.GetString("PleaseSetupPin_title_error");

                myDlg = new MessageDialog(PleaseSetUpPinContent, PleaseSetUpPinTitle);
                await myDlg.ShowAsync();

                return;
            }

            IReadOnlyList <User> users = await User.FindAllAsync(UserType.LocalUser, UserAuthenticationStatus.LocallyAuthenticated);

            string userId = users.ElementAt(0).NonRoamableId;

            string selector = SmartCardReader.GetDeviceSelector();

            selector += " AND System.Devices.DeviceInstanceId:~~\"Ledger\"";
            //string test = selector.Replace(" ", ((char)34).ToString());
            DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(selector);

            foreach (DeviceInformation device in devices)
            {
                SmartCardReader reader = await SmartCardReader.FromIdAsync(device.Id);

                IReadOnlyList <SmartCard> cards = await reader.FindAllCardsAsync();

                foreach (SmartCard card in cards)
                {
                    SmartCardProvisioning provisioning = await SmartCardProvisioning.FromSmartCardAsync(card);

                    IBuffer ATR = await card.GetAnswerToResetAsync();

                    string ATR_str = CryptographicBuffer.EncodeToHexString(ATR);

                    if (ATR_str.Equals(NanosATR))
                    {
                        numberOfDevices++;
                        bool foundCompanionDevice = false;
                        // List the registered devices to prevent registering twice the same device
                        IReadOnlyList <SecondaryAuthenticationFactorInfo> registeredDeviceList = await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync(
                            SecondaryAuthenticationFactorDeviceFindScope.AllUsers);

                        SmartCardConnection connection = await card.ConnectAsync();

                        response = await Apdu.TransmitApduAsync(connection, Apdu.getDeviceGuidCmdApdu);

                        sw1sw2 = Apdu.ApduResponseParser(response, out response);
                        connection.Dispose();
                        deviceIdArray = response;
                        deviceId      = BitConverter.ToString(response).Replace("-", "");
                        // Loop on registered devices to check if device to register has already been registered
                        for (int i = 0; i < registeredDeviceList.Count(); i++)
                        {
                            if (registeredDeviceList.ElementAt(i).DeviceId == deviceId)
                            {
                                //deviceFriendlyName = registeredDeviceList.ElementAt(i).DeviceFriendlyName;
                                numberOfRegisteredDevices++;
                                foundCompanionDevice = true;
                                break;
                            }
                        }
                        if (foundCompanionDevice)// This device has already been registered
                        {
                            // New message dialog to inform user, and break from card loop
                            //myDlg = null;
                            //myDlg = new MessageDialog("The device \"" + deviceFriendlyName + "\" has already been registered");
                            //await myDlg.ShowAsync();
                            continue;
                        }

                        connection = await card.ConnectAsync();

                        response = await Apdu.TransmitApduAsync(connection, Apdu.getDlockStateCmdApdu);

                        sw1sw2           = Apdu.ApduResponseParser(response, out response);
                        deviceDlockState = response;

                        response = await Apdu.TransmitApduAsync(connection, Apdu.startRegistrationCmdApdu);

                        sw1sw2 = Apdu.ApduResponseParser(response, out response);

                        connection.Dispose();

                        if (sw1sw2 != "9000")
                        {
                            var    loader = new Windows.ApplicationModel.Resources.ResourceLoader();
                            string RegistrationDeniedContent = loader.GetString("RegsitrationDenied_content_error");
                            string RegistrationDeniedTitle   = loader.GetString("RegsitrationDenied_title_error");

                            myDlg = null;
                            myDlg = new MessageDialog(RegistrationDeniedContent, RegistrationDeniedTitle);
                            await myDlg.ShowAsync();

                            return;
                        }
                        // Get device key from response
                        for (int index = 0; index < 32; index++)
                        {
                            deviceKeyArray[index] = response[index];
                        }
                        deviceKey = CryptographicBuffer.CreateFromByteArray(deviceKeyArray);
                        // Get auth key from response
                        for (int index = 0; index < 32; index++)
                        {
                            authKeyArray[index] = response[index + 32];
                        }
                        authKey = CryptographicBuffer.CreateFromByteArray(authKeyArray);

                        byte[] deviceConfigDataArray = new byte[18]; //16 bytes for GUID and 1 byte for dLockstate

                        for (int i = 0; i < 16; i++)
                        {
                            deviceConfigDataArray[i] = deviceIdArray[i];
                        }
                        deviceConfigDataArray[16] = deviceDlockState[0];
                        deviceConfigDataArray[17] = 0; // 1 if used for last logon, 0 instead

                        string   deviceConfigString = "";
                        DateTime addDate            = DateTime.Now;
                        //DateTime addDate = new DateTime(2017, 5, 31, 13, 23, 45);
                        if (deviceDlockState[0] == 0)
                        {
                            deviceConfigString = deviceId + "-0-0-" + deviceFriendlyName + "-" + addDate.ToString() + "-" + userId;
                        }
                        else
                        {
                            deviceConfigString = deviceId + "-1-0-" + deviceFriendlyName + "-" + addDate.ToString() + "-" + userId;
                        }

                        // Get a Ibuffer from combinedDataArray
                        IBuffer deviceConfigData = CryptographicBuffer.ConvertStringToBinary(deviceConfigString, 0);
                        //IBuffer deviceConfigData = CryptographicBuffer.CreateFromByteArray(deviceConfigDataArray);

                        SecondaryAuthenticationFactorDeviceCapabilities capabilities = SecondaryAuthenticationFactorDeviceCapabilities.SecureStorage |
                                                                                       SecondaryAuthenticationFactorDeviceCapabilities.HMacSha256 | SecondaryAuthenticationFactorDeviceCapabilities.StoreKeys |
                                                                                       SecondaryAuthenticationFactorDeviceCapabilities.SupportSecureUserPresenceCheck;

                        SecondaryAuthenticationFactorRegistrationResult registrationResult = await SecondaryAuthenticationFactorRegistration.RequestStartRegisteringDeviceAsync(
                            deviceId,
                            capabilities,
                            deviceFriendlyName,
                            deviceModelNumber,
                            deviceKey,
                            authKey);

                        if (registrationResult.Status != SecondaryAuthenticationFactorRegistrationStatus.Started)
                        {
                            myDlg = null;

                            if (registrationResult.Status == SecondaryAuthenticationFactorRegistrationStatus.DisabledByPolicy)
                            {
                                //For DisaledByPolicy Exception:Ensure secondary auth is enabled.
                                //Use GPEdit.msc to update group policy to allow secondary auth
                                //Local Computer Policy\Computer Configuration\Administrative Templates\Windows Components\Microsoft Secondary Authentication Factor\Allow Companion device for secondary authentication
                                myDlg = new MessageDialog("Disabled by Policy.  Please update the policy and try again.");
                            }

                            if (registrationResult.Status == SecondaryAuthenticationFactorRegistrationStatus.PinSetupRequired)
                            {
                                //For PinSetupRequired Exception:Ensure PIN is setup on the device
                                //Either use gpedit.msc or set reg key
                                //This setting can be enabled by creating the AllowDomainPINLogon REG_DWORD value under the HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System Registry key and setting it to 1.
                                var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
                                var str    = loader.GetString("PleaseSetupPin_error");
                                myDlg = new MessageDialog(str);
                            }

                            if (myDlg != null)
                            {
                                await myDlg.ShowAsync();

                                return;
                            }
                        }

                        System.Diagnostics.Debug.WriteLine("[RegisterDevice_Click] Device Registration Started!");
                        await registrationResult.Registration.FinishRegisteringDeviceAsync(deviceConfigData);

                        //DeviceListBox.Items.Add(deviceFriendlyName);
                        System.Diagnostics.Debug.WriteLine("[RegisterDevice_Click] Device Registration is Complete!");

                        IReadOnlyList <SecondaryAuthenticationFactorInfo> deviceList = await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync(
                            SecondaryAuthenticationFactorDeviceFindScope.AllUsers);

                        SecondaryAuthenticationFactorDevicePresenceMonitoringRegistrationStatus status =
                            await SecondaryAuthenticationFactorRegistration.RegisterDevicePresenceMonitoringAsync(
                                deviceId,
                                device.Id,
                                SecondaryAuthenticationFactorDevicePresenceMonitoringMode.AppManaged /*,
                                                                                                      * deviceFriendlyName,
                                                                                                      * deviceModelNumber,
                                                                                                      * deviceConfigData*/);

                        switch (status)
                        {
                        //case SecondaryAuthenticationFactorDevicePresenceMonitoringRegistrationStatus.Succeeded:
                        //    await new MessageDialog("Registered for presence monitoring!").ShowAsync();
                        //    break;

                        case SecondaryAuthenticationFactorDevicePresenceMonitoringRegistrationStatus.DisabledByPolicy:
                            await new MessageDialog("Registered for presence disabled by policy!").ShowAsync();
                            break;
                        }

                        listContent listItem = new listContent();
                        listItem.deviceFriendlyName = deviceFriendlyName;
                        listItem.deviceGUID         = deviceId;
                        //listItem.isVisible = false;
                        listItem.date       = addDate;
                        listItem.dateString = FormatDate(addDate);
                        //DeviceListBox.Items.Add(listItem);
                        //StartWatcher();
                        //this.Frame.Navigate(typeof(MainPage), "false");
                    }
                }
            }
            if (numberOfDevices == numberOfRegisteredDevices)
            {
                var    loader = new Windows.ApplicationModel.Resources.ResourceLoader();
                string str    = loader.GetString("DeviceAlreadyRegistered_content_error");


                throw new Exception(str);
                //myDlg = new MessageDialog("Ledger Nano-s for Windows Hello not found" + Environment.NewLine + Environment.NewLine + "Please plug a ledger Nano-s in a usb port");
                //await myDlg.ShowAsync();
                //return;
            }
            return;
        }