private async Task AuthenticateWithSmartCardAsync(SmartCard card) { var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; String m_selectedDeviceId = localSettings.Values["SelectedDevice"] as String; string m_selectedDeviceFriendlyName = string.Empty; string m_selectedDeviceAddDate = string.Empty; string deviceConfigString = string.Empty; char[] deviceConfigCharArray; byte[] deviceIdArray = new byte[16]; byte[] deviceDlockState = new byte[1]; bool foundCompanionDevice = false; byte[] response = { 0 }; string sw1sw2 = null; SecondaryAuthenticationFactorAuthenticationStageInfo authStageInfo = await SecondaryAuthenticationFactorAuthentication.GetAuthenticationStageInfoAsync(); if ((authStageInfo.Stage != SecondaryAuthenticationFactorAuthenticationStage.CollectingCredential) && (authStageInfo.Stage != SecondaryAuthenticationFactorAuthenticationStage.WaitingForUserConfirmation)) { throw new Exception("Unexpected! Stage: " + authStageInfo.Stage); } //ShowToastNotification("Post Collecting Credential"); System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Post Collecting Credential"); IReadOnlyList <SecondaryAuthenticationFactorInfo> deviceList = await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync( SecondaryAuthenticationFactorDeviceFindScope.AllUsers); if (deviceList.Count == 0) { //ShowToastNotification("Unexpected exception, device list = 0"); throw new Exception("Unexpected exception, device list = 0"); } SmartCardConnection connection = await card.ConnectAsync(); System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Connection"); response = await Apdu.TransmitApduAsync(connection, Apdu.getDeviceGuidCmdApdu); sw1sw2 = Apdu.ApduResponseParser(response, out response); deviceIdArray = response; string deviceId = BitConverter.ToString(response).Replace("-", ""); response = await Apdu.TransmitApduAsync(connection, Apdu.getDlockStateCmdApdu); sw1sw2 = Apdu.ApduResponseParser(response, out response); deviceDlockState = response; //string deviceFriendlyName = null; byte[] deviceConfigDataArray = new byte[18]; //16 bytes for GUID and 1 byte for dLockstate IBuffer deviceConfigData; byte[] deviceConfigurationDataArray; //List<byte[]> deviceConfigList = new List<byte[]>(); foreach (SecondaryAuthenticationFactorInfo device in deviceList) { CryptographicBuffer.CopyToByteArray(device.DeviceConfigurationData, out deviceConfigurationDataArray); //deviceConfigList.Add(deviceConfigurationDataArray); //deviceFriendlyName = device.DeviceFriendlyName; if (device.DeviceId == deviceId) { m_selectedDeviceId = deviceId; m_selectedDeviceFriendlyName = device.DeviceFriendlyName; deviceConfigString = CryptographicBuffer.ConvertBinaryToString(0, device.DeviceConfigurationData); //deviceConfigCharArray = new char[deviceConfigString.Count()]; //deviceConfigCharArray = deviceConfigString.ToCharArray(); int count = device.DeviceFriendlyName.Count(); m_selectedDeviceAddDate = deviceConfigString.Substring(35 + 1 + count + 1 + 1); foundCompanionDevice = true; //continue; } } //Debugger.Break(); if (!foundCompanionDevice) { throw new CompanionDeviceNotFoundException(); } System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Start Nonce APDU sending"); response = await Apdu.TransmitApduAsync(connection, Apdu.getNonceCmdApdu); sw1sw2 = Apdu.ApduResponseParser(response, out response); if (sw1sw2 != "9000") { throw new UnableTogetNonceFromDeviceException(); } System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Nonce APDU recieved without error"); string nonce = BitConverter.ToString(response).Replace("-", ""); IBuffer svcNonce = CryptographicBuffer.DecodeFromHexString(nonce); System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Start Authentication"); SecondaryAuthenticationFactorAuthenticationResult authResult = await SecondaryAuthenticationFactorAuthentication.StartAuthenticationAsync( m_selectedDeviceId, svcNonce); if (authResult.Status != SecondaryAuthenticationFactorAuthenticationStatus.Started) { //ShowToastNotification("Unexpected! Could not start authentication!"); throw new Exception("Unexpected! Could not start authentication! Status: " + authResult.Status); } byte[] devNonce = { 0 }; byte[] svcHmac = { 0 }; byte[] sessNonce = { 0 }; CryptographicBuffer.CopyToByteArray(authResult.Authentication.ServiceAuthenticationHmac, out svcHmac); CryptographicBuffer.CopyToByteArray(authResult.Authentication.SessionNonce, out sessNonce); CryptographicBuffer.CopyToByteArray(authResult.Authentication.DeviceNonce, out devNonce); byte[] cmd = new byte[Apdu.challengeCmdApdu.Length + svcHmac.Length + sessNonce.Length + devNonce.Length]; System.Buffer.BlockCopy(Apdu.challengeCmdApdu, 0, cmd, 0, Apdu.challengeCmdApdu.Length); System.Buffer.BlockCopy(svcHmac, 0, cmd, Apdu.challengeCmdApdu.Length, svcHmac.Length); System.Buffer.BlockCopy(sessNonce, 0, cmd, Apdu.challengeCmdApdu.Length + svcHmac.Length, sessNonce.Length); System.Buffer.BlockCopy(devNonce, 0, cmd, Apdu.challengeCmdApdu.Length + svcHmac.Length + sessNonce.Length, devNonce.Length); System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Send Challenge"); string str = "\"" + m_selectedDeviceFriendlyName + "\""; await SecondaryAuthenticationFactorAuthentication.ShowNotificationMessageAsync( str, SecondaryAuthenticationFactorAuthenticationMessage.DeviceNeedsAttention); response = await Apdu.TransmitApduAsync(connection, cmd); sw1sw2 = Apdu.ApduResponseParser(response, out response); if (sw1sw2 == "6985") { throw new UnauthorizedUserException(); } else if (sw1sw2 == "6984") { //ShowToastNotification("Log-in denied by user"); throw new LogInDeniedByUserException(); } System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Response recieved"); byte[] HMACdk = new byte[32]; byte[] HMACsk = new byte[32]; System.Buffer.BlockCopy(response, 0, HMACdk, 0, 32); System.Buffer.BlockCopy(response, 32, HMACsk, 0, 32); IBuffer deviceHmac = CryptographicBuffer.CreateFromByteArray(HMACdk); IBuffer sessionHmac = CryptographicBuffer.CreateFromByteArray(HMACsk); SecondaryAuthenticationFactorFinishAuthenticationStatus authStatus = await authResult.Authentication.FinishAuthenticationAsync(deviceHmac, sessionHmac); if (authStatus != SecondaryAuthenticationFactorFinishAuthenticationStatus.Completed) { //ShowToastNotification("Unable to complete authentication!"); System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Unable to complete authentication"); throw new Exception("Unable to complete authentication!"); } deviceConfigString = ""; if (deviceDlockState[0] == 0) { deviceConfigString = deviceId + "-0-1-" + m_selectedDeviceFriendlyName + "-" + m_selectedDeviceAddDate; } else { deviceConfigString = deviceId + "-1-1-" + m_selectedDeviceFriendlyName + "-" + m_selectedDeviceAddDate; } deviceConfigCharArray = new char[deviceConfigString.Count()]; deviceConfigString.CopyTo(0, deviceConfigCharArray, 0, deviceConfigString.Count()); // because deviceConfigString is readonly deviceConfigCharArray[35] = '1'; // to indicate that device was not used for last login string deviceConfigStringNew = new string(deviceConfigCharArray); //Debugger.Break(); deviceConfigData = CryptographicBuffer.ConvertStringToBinary(deviceConfigStringNew, 0); await SecondaryAuthenticationFactorRegistration.UpdateDeviceConfigurationDataAsync(deviceId, deviceConfigData); //update deviceConfigData foreach (SecondaryAuthenticationFactorInfo device in deviceList) { if (device.DeviceId != deviceId) { deviceConfigString = CryptographicBuffer.ConvertBinaryToString(0, device.DeviceConfigurationData); deviceConfigCharArray = new char[deviceConfigString.Count()]; deviceConfigString.CopyTo(0, deviceConfigCharArray, 0, deviceConfigString.Count()); // decause deviceConfigString is readonly deviceConfigCharArray[35] = '0'; // to indicate that device was not used for last login deviceConfigStringNew = new string(deviceConfigCharArray); deviceConfigData = CryptographicBuffer.ConvertStringToBinary(deviceConfigStringNew, 0); //Debugger.Break(); await SecondaryAuthenticationFactorRegistration.UpdateDeviceConfigurationDataAsync(device.DeviceId, deviceConfigData); //update deviceConfigData } } System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Auth completed"); connection.Dispose(); }
private async Task writeConnectedRegisteredDevices() { string NanosATR = "3b00"; string selector = SmartCardReader.GetDeviceSelector(); selector += " AND System.Devices.DeviceInstanceId:~~\"Ledger\""; byte[] response = { 0 }; string sw1sw2 = null; byte[] deviceDlockState = new byte[1]; byte[] deviceIdArray = new byte[16]; string txt = ""; DeviceInformationCollection readers = await DeviceInformation.FindAllAsync(selector); IReadOnlyList <SecondaryAuthenticationFactorInfo> RegisteredDeviceList_addEvent = await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync( SecondaryAuthenticationFactorDeviceFindScope.User); List <SecondaryAuthenticationFactorInfo> ConnectedRegisteredDeviceList = await getConnectedRegisteredDeviceList(RegisteredDeviceList_addEvent); foreach (SecondaryAuthenticationFactorInfo device in ConnectedRegisteredDeviceList) { foreach (DeviceInformation smartcardreader in readers) { SmartCardReader reader = await SmartCardReader.FromIdAsync(smartcardreader.Id); SmartCardReaderStatus readerstatus = await reader.GetStatusAsync(); IReadOnlyList <SmartCard> cards = await reader.FindAllCardsAsync(); foreach (SmartCard card in cards) { try { IBuffer ATR = await card.GetAnswerToResetAsync(); string ATR_str = CryptographicBuffer.EncodeToHexString(ATR); if (ATR_str.Equals(NanosATR)) { SmartCardConnection connection = await card.ConnectAsync(); response = await Apdu.TransmitApduAsync(connection, Apdu.getDeviceGuidCmdApdu); sw1sw2 = Apdu.ApduResponseParser(response, out response); deviceIdArray = response; string deviceId = BitConverter.ToString(response).Replace("-", ""); if (deviceId == device.DeviceId) //update config data with dLockState { if (device.PresenceMonitoringMode != SecondaryAuthenticationFactorDevicePresenceMonitoringMode.AppManaged) { // Skip the device which doesn't need to be monitored in the background task continue; } await device.UpdateDevicePresenceAsync(SecondaryAuthenticationFactorDevicePresence.Present); response = await Apdu.TransmitApduAsync(connection, Apdu.getDlockStateCmdApdu); sw1sw2 = Apdu.ApduResponseParser(response, out response); deviceDlockState = response; string deviceConfigString = CryptographicBuffer.ConvertBinaryToString(0, device.DeviceConfigurationData); char[] deviceConfigCharArray = new char[deviceConfigString.Count()]; deviceConfigCharArray = deviceConfigString.ToCharArray(); string deviceConfigStringNew = ""; int count = device.DeviceFriendlyName.Count(); if (deviceDlockState[0] == 0) { if (deviceConfigCharArray[35] == '0') // Indicates if device was used for last login { deviceConfigStringNew = device.DeviceId + "-0-0-" + device.DeviceFriendlyName + "-" + deviceConfigString.Substring(35 + 1 + count + 1 + 1); } else { deviceConfigStringNew = device.DeviceId + "-0-1-" + device.DeviceFriendlyName + "-" + deviceConfigString.Substring(35 + 1 + count + 1 + 1); } } else { if (deviceConfigCharArray[35] == '0') { deviceConfigStringNew = device.DeviceId + "-1-0-" + device.DeviceFriendlyName + "-" + deviceConfigString.Substring(35 + 1 + count + 1 + 1); } else { deviceConfigStringNew = device.DeviceId + "-1-1-" + device.DeviceFriendlyName + "-" + deviceConfigString.Substring(35 + 1 + count + 1 + 1); } } // Get a Ibuffer from combinedDataArray IBuffer deviceConfigData = CryptographicBuffer.ConvertStringToBinary(deviceConfigString, 0); await SecondaryAuthenticationFactorRegistration.UpdateDeviceConfigurationDataAsync(device.DeviceId, deviceConfigData); } connection.Dispose(); } } catch (Exception e) { } } } txt += CryptographicBuffer.ConvertBinaryToString(0, device.DeviceConfigurationData) + Environment.NewLine; } StorageFolder folder = ApplicationData.Current.LocalFolder; StorageFile ConnectedRegisteredDeviceListFile = await folder.CreateFileAsync("connectedRegisteredDeviceList.txt", CreationCollisionOption.ReplaceExisting); await FileIO.WriteTextAsync(ConnectedRegisteredDeviceListFile, txt); }