private async Task <SmartCard> FindSmartCard(SmartCardReader cardReader, CancellationToken cts) { while (true) { if (cts.IsCancellationRequested) { throw new OperationCanceledException(); } IReadOnlyList <SmartCard> cards = await cardReader.FindAllCardsAsync(); if (cards != null && cards.Count > 0) { var card = cards[0]; return(card); } } }
private async void Reader_CardAdded(SmartCardReader sender, CardAddedEventArgs args) { var cards = await sender.FindAllCardsAsync(); if (cards.Count < 1) { return; } var card = cards[0]; const int READ_AMOUNT = 80; SmartCardConnection connection; try { connection = await card.ConnectAsync(); } catch (Exception) // This is literally the most specific exception sent for this error { // Couldn't open reader because tag was lifted too early return; } using (connection) { const byte START_BLOCK = 4; const byte MAX_READ_SIZE = 16; byte[] data = new byte[READ_AMOUNT]; for (int i = 0; i < Math.Ceiling((float)READ_AMOUNT / MAX_READ_SIZE); i++) { byte[] command = { 0xFF, 0xB0, 0x00, (byte)(START_BLOCK + i * 4), MAX_READ_SIZE }; var response = await connection.TransmitAsync(command.AsBuffer()); if (response.Length != MAX_READ_SIZE + 2) // 2 bytes for command execution status { Debug.WriteLine("Tag lifted too early"); return; } uint length = response.Length; response.CopyTo(0, data, i * MAX_READ_SIZE, MAX_READ_SIZE); } // Parse TLV blocks for (int i = 0; i < data.Length; i++) { if (data[i] == 0x00) { // NULL TLV continue; } else if (data[i] == 0x01) { // Lock control TLV i++; i += data[i]; // Skip over block according to its length } else if (data[i] == 0x03) { // NDEF TLV i++; byte length = data[i]; byte[] ndefData = new byte[length]; Array.Copy(data, i + 1, ndefData, 0, length); string uri = getURIFromNdef(ndefData); OnBadgeTapped(new BadgeEventArgs(uri)); i += length + 1; // Also skip over trailing 0xFE } } } }
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; }