key chain not storing data in iOS simulator 11.2 - c#

I wrote below code in xamarin c# to store sensitive data in iPhone Keychain.
void StoreKeysInKeychain(string key, string value)
{
var user = Settings.CurrentUser;
var userstring = JsonConvert.SerializeObject(user);
if (value == "logout")
{
userstring = string.Empty;
};
var record = new SecRecord(SecKind.GenericPassword)
{
ValueData = NSData.FromString(userstring),
Generic = NSData.FromString(key),
Label="Sanket",
};
SecKeyChain.Remove(record);
SecKeyChain.Add(record);
}
SecRecord GetRecordsFromKeychain(string key)
{
SecStatusCode res;
var rec = new SecRecord(SecKind.GenericPassword)
{
Generic = NSData.FromString(key)
};
return SecKeyChain.QueryAsRecord(rec, out res);
}
Tested with the same code on another MAC simulator and it is working there but not on my MAC.
Both the MAC has same iOS 10.13.3 and simulator version 11.2.
Even I tried to change the simulators but it doesn't store the data.
I tried to browse Keychain contents stored in sqlite format.
Refer below link how to browse content stored in Keychain of simulator.
Link to : Browse Keychain Data stored in Simulator
I Tried to reset content of simulator but no luck.
Any help will be appreciated.
Thanks :(

In iOS 10 keychain on the simulator broke. Check out this Xamarin forums post: https://forums.xamarin.com/discussion/77760/ios-10-keychain and the correlated apple post: https://forums.developer.apple.com/thread/51071.
Here is the issue: Issue: SecKeyChain.Add() returns -34018 on iOS 10 simulator unless Enable Keychain Access Groups has been enabled in Entitlements.plist.
You need to update your Entitlements.plist for the simulator build configuration.

Related

Cross-App Keychain Access, where to configure?

I am currently developing multiple cross-plattform apps which (under iOS) use some shared keychain entries. My current project started on android and after we had a working version I continued working on the iOS version. I imported our keychain access code from earlier projects to access our shared login-data. Only this time the queries always return SecStatusCode.ItemNotFound.
I compared the provisioning profile and the entitlements and all looks the same. After some time it drove me nuts and I created a new empty app with only the keychain-code, the same bundle identifier, provisioning profiles and entitlements file as the currently-not-working-app and it works just fine and returns my data.
To my question, where else are things to be configured, that could possibly interfere with my access to keychain entries besides entitlements.plist and provisioning profile? Since the project is somewhat bigger, I don't want to copy ALL code to fresh project. I tried both Visual Studio 2017 for Windows and VS for Mac 2019. It is an internal/enterprise app, it that is of any concern...
Keychain call:
KeyChain kc = new KeyChain("USER_DATA", "de.rlp.myCompany.Shared");
var data = kc.Find("LOGIN_DATA");
Keychain-Class:
public class KeyChain
{
public string ServiceName { get; set; }
public string GroupName { get; set; }
public KeyChain(string serviceName, string groupName = null)
{
ServiceName = serviceName;
GroupName = groupName;
}
public byte[] Find(string key)
{
SecStatusCode res;
var rec = PrepareDictionary(key);
var match = SecKeyChain.QueryAsRecord(rec, out res);
if (res == SecStatusCode.Success) // ItemNotFound return-code here
{
return match.ValueData.ToArray();
}
else
{
System.Diagnostics.Debug.Write(res.ToString());
}
return null;
}
private SecRecord PrepareDictionary(string key)
{
var sr = new SecRecord(SecKind.GenericPassword)
{
Service = this.ServiceName,
Generic = NSData.FromString (key),
Account = key,
Accessible = SecAccessible.AlwaysThisDeviceOnly
};
if (string.IsNullOrEmpty(GroupName))
{
sr.AccessGroup = GroupName;
}
return sr;
}
}
Entitlements-Entry
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)de.rlp.myCompany.Shared</string>
</array>
Have you added both your applications to the same App Group/ Keychain Group from entitlements and enabled it.
VS might be buggy. Just check entitlements for both the apps on apple developer site.
That might be the problem.
Documentation

RSACertificateExtensions.GetRSAPrivateKey return null in UWP but not in WPF

I'm working on a UWP application where I need to sign data with certificates stored on a usb key.
Here is an extract of my code :
X509Certificate2 myCertificate;
using (var privateKey = cert.GetRSAPrivateKey())
{
if (privateKey == null)
{
return null;
}
[...]
var signedData = privateKey.SignData(dataToBeSigned, algoToUsedToHashData, RSASignaturePadding.Pkcs1);
}
We tested our code with usb keys from a vendor and this works fine. But one of our customer is working with keys from tuntrust (http://www.tuntrust.tn/). With those keys, the test privateKey == null is true in a UWP project (with the corresponding capacity checked in the appxmanifest) and so we can't sign data, but works fine in a WPF project.
I've tried the certutil -user -repairstore my "" command line as suggested here : https://stackoverflow.com/a/36734804/2367226 and it's not working better...
Any idea how to fix this ?

Windows IoT Raspberry Pi 3 C# GetDiskFreeSpace

I have a USB thumb-drive connected to my raspberry pi 3. I'd need to find out how to check for the available disk space to be printed on a textblock. I couldn't find any example for UWP application.
What I found was GetDiskFreeSpaceEx function and Is there a method available for UWP apps to get available disk space
Is there any example I could refer to?
Thanks.
Updated:
I have tried [Get available disk free space for a given path on Windows [duplicate]] .. Couldn't get it to work too..
You can use StorageFolder.Properties.RetrievePropertiesAsync() API to get the free space size of USB storage.I tested with the following pieces of code:
var removableDevices = KnownFolders.RemovableDevices;
var externalDevices = await removableDevices.GetFoldersAsync();
var usbDriver = externalDevices.FirstOrDefault();
var allProperties = usbDriver.Properties;
IEnumerable<string> propertiesToRetrieve = new List<string> { "System.FreeSpace" };
var storageIdProperties = await allProperties.RetrievePropertiesAsync(propertiesToRetrieve);
var freeSpaceSize = storageIdProperties["System.FreeSpace"].ToString();

UWP/C# - Issue with AQS and USB Devices

I have an issue with a UWP app that I am trying to write. I am connecting to a custom embedded USB Bulk device that I have programmed (it is actually an out of the box example from Cypress Semiconductor). I am using the WinUSB.sys driver using the embedded MS OS string in the device to allow the device to be used with out having to write a custom INF file to call the WinUSB.sys driver.
In my code, I am using the UsbDevice.GetDeviceSelector method to return an AQS that can then be passed into DeviceInformation.FindAllAsync to begin communicating with the device in my app. I have confirmed that the device shows up in the device manager without any issues, and I have checked in the registry to ensure that it has an Interface GUID. I have a screenshot from USBViewer to show the configuration of the device. This method for finding and connecting with USB devices is from this MSDN example found here.
When I use the UsbDevice.GetDeviceSelector method, it returns a GUID that is not associated with this device. The GUID that it returns is actually associated with Lumia Phones (DEE824EF-729B-4A0E-9C14-B7117D33A817). Because of this, it does not find my device connected to the system.
To troubleshoot, I have both called the DeviceInformation.FindAllAsync with out any arguments to see if my device is listed, and it does find the device (amongst over 1000 other devices that have been connected ever to my machine). I then wrote a custom AQS string without the help of the GetDeviceSelector method, starting with just the GUID. Doing this returned 27 devices, but when I tried to add the VID and PID to this AQS string, nothing returned.
I have also made sure that the device that I want to use is listed in the app manifest by its appropriate VID and PID as this is required for a device with a Custom Class of 0xFF. I have used the Custom USB UWP device example and it can find the device, though it uses a completely different method with a device picker, which I will go to if needed, but this is not my desire as it makes that part of the app not as clean of a solution.
I have posted this question over in the MSDN forums here with more information, but I have not gotten a lot of engagement there. Any help would be appreciated. I know that I must be missing something simple.
Adam
private async void button_Click(object sender, RoutedEventArgs e)
{
//UInt32 vid = 0x04B4;
//UInt32 pid = 0x00F0;
UInt32 vid = uint.Parse(textBox1.Text, System.Globalization.NumberStyles.HexNumber);
UInt32 pid = UInt32.Parse(textBox2.Text, System.Globalization.NumberStyles.HexNumber);
Guid winusbInterfaceGuid = new Guid("a5dcbf10-6530-11d2-901f-00c04fb951ed");
//string aqs = UsbDevice.GetDeviceSelector(vid, pid);
string aqs = UsbDevice.GetDeviceSelector(winusbInterfaceGuid);
var myDevices = await DeviceInformation.FindAllAsync(aqs, null);
//var myDevices = await DeviceInformation.FindAllAsync();
var myDevicesCount = myDevices.Count;
if (myDevicesCount >= 1)
{
textBlock2.Text = "Device Found";
} else
{
textBlock2.Text = "Searching";
await Task.Delay(1000);
textBlock2.Text = "looking for device";
}
}
just dropped you a mail asking about progress (I think, had to guess your mail address), but now it seems I found a solution myself. Please see my answer on UWP app cannot find/connect to USB device
In short, you have to create an inf for installing the winusb driver. I have no clue why, but that did the trick for me (and someone else, see Cannot create UsbDevice from DeviceInformation.Id)
The Guid DEE824EF-729B-4A0E-9C14-B7117D33A817 is actually the standard WinUSB Guid. I don't think it has anything to do with Lumia Phones. I don't know why it is not documented anywhere. I think that the Guid a5dcbf10-6530-11d2-901f-00c04fb951ed you specified is actually a red herring. I mistakenly used that as well, but it just led me down the garden path. It shows up USB interfaces, but I can't connect to them.
You might want to try this class https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Usb.Net.UWP/UWPUsbDevice.cs .
Here is how it gets the device:
public async Task<IEnumerable<DeviceDefinition>> GetConnectedDeviceDefinitions(uint? vendorId, uint? productId)
{
var aqsFilter = "System.Devices.InterfaceClassGuid:=\"{DEE824EF-729B-4A0E-9C14-B7117D33A817}\" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True AND " + $" System.DeviceInterface.WinUsb.UsbVendorId:={vendorId.Value} AND System.DeviceInterface.WinUsb.UsbProductId:={productId.Value}";
var deviceInformationCollection = await wde.DeviceInformation.FindAllAsync(aqsFilter).AsTask();
//TODO: return the vid/pid if we can get it from the properties. Also read/write buffer size
var deviceIds = deviceInformationCollection.Select(d => new DeviceDefinition { DeviceId = d.Id, DeviceType = DeviceType.Usb }).ToList();
return deviceIds;
}
This sample connects to a device and I think you'll be able to connect to the device in the same way:
private static async Task InitializeTrezor()
{
//Register the factory for creating Usb devices. This only needs to be done once.
UWPUsbDeviceFactory.Register();
//Register the factory for creating Usb devices. This only needs to be done once.
UWPHidDeviceFactory.Register();
//Note: other custom device types could be added here
//Define the types of devices to search for. This particular device can be connected to via USB, or Hid
var deviceDefinitions = new List<DeviceDefinition>
{
new DeviceDefinition{ DeviceType= DeviceType.Hid, VendorId= 0x534C, ProductId=0x0001, Label="Trezor One Firmware 1.6.x" },
new DeviceDefinition{ DeviceType= DeviceType.Usb, VendorId= 0x1209, ProductId=0x53C1, ReadBufferSize=64, WriteBufferSize=64, Label="Trezor One Firmware 1.7.x" },
new DeviceDefinition{ DeviceType= DeviceType.Usb, VendorId= 0x1209, ProductId=0x53C0, ReadBufferSize=64, WriteBufferSize=64, Label="Model T" }
};
//Get the first available device and connect to it
var devices = await DeviceManager.Current.GetDevices(deviceDefinitions);
var trezorDevice = devices.FirstOrDefault();
await trezorDevice.InitializeAsync();
//Create a buffer with 3 bytes (initialize)
var buffer = new byte[64];
buffer[0] = 0x3f;
buffer[1] = 0x23;
buffer[2] = 0x23;
//Write the data to the device
await trezorDevice.WriteAsync(buffer);
//Read the response
var readBuffer = await trezorDevice.ReadAsync();
}
If you connect to the device in this way, you'll get Windows classic, and Android support for free with Device.Net (https://github.com/MelbourneDeveloper/Device.Net)
With Device.net's DeviceManager.Current.GetDevices(deviceDefinitions) using .NET 5 I can't find any device connected to my win10, which can be easily selected by ManagementObjectSearcher:
public List<ManagementBaseObject> GetLogicalDevices()
{
List<ManagementBaseObject> devices = new List<ManagementBaseObject>();
ManagementObjectCollection collection;
ManagementObjectSearcher seacher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM CIM_LogicalDevice");
collection = seacher.Get();
foreach (var device in collection)
{
devices.Add(device);
}
return devices;
}

Xamarin C# for Android : Searching for an App and path

GOAL : I need to find if an app is installed on a device AND find it's path..
I see using PackageManager, you can do this in general but I would like to refine it.
I know if you use com.google.chrome you can find chrome explorer installed,
but this fails when you look simply for Chrome.
On some devices Chrome (and other apps, like Opera, Mini,etc) is not installed as com.google.chrome.
So how would one find an app without the com.google and just use Chrome as the search criteria ?
Simple, just combine PackageManager and ApplicationInfo, and then check if app name contain your search string. Here is some example code:
var searchQuery = "chrome";
var flag = PackageInfoFlags.Activities;
var apps = PackageManager.GetInstalledApplications(flag);
foreach(var app in apps)
{
try
{
var appInfo = PackageManager.GetApplicationInfo(app.PackageName, 0);
var appLabel = PackageManager.GetApplicationLabel(appInfo);
if (appLabel.ToLower().Contains(searchQuery.ToLower()))
{
var builder = new AlertDialog.Builder(this);
builder.SetTitle("Found it!");
builder.SetMessage(appLabel + " installed at: " + app.SourceDir);
builder.Show();
}
}
catch (PackageManager.NameNotFoundException e) { continue; }
}

Categories