reactiveui / Akavache

An asynchronous, persistent key-value store created for writing desktop and mobile applications, based on SQLite3. Akavache is great for both storing important data as well as cached local data that expires.
https://evolve.xamarin.com/session/56e2044afd00c0253cae33a3
MIT License
2.44k stars 288 forks source link

Deadlock when using SecureCache on Windows 10 UWP #298

Open dominik-weber opened 8 years ago

dominik-weber commented 8 years ago

When using the SQLiteEncryptedBlobCache aka SecureCache in our Windows 10 UWP app I'm facing an issue where the app keeps locking up. This is the stack trace:

image

I don't know why, but if I replace the code

public IObservable<byte[]> DecryptBlock(byte[] block)
{
    // Do not include a protectionDescriptor 
    // http://msdn.microsoft.com/en-us/library/windows/apps/windows.security.cryptography.dataprotection.dataprotectionprovider.unprotectasync.aspx 
    var dpapi = new DataProtectionProvider();
    return dpapi.UnprotectAsync(block.AsBuffer()).ToObservable().Select(b => b.ToArray());
}

with

public IObservable<byte[]> DecryptBlock(byte[] block)
{
    // Do not include a protectionDescriptor 
    // http://msdn.microsoft.com/en-us/library/windows/apps/windows.security.cryptography.dataprotection.dataprotectionprovider.unprotectasync.aspx 
    var dpapi = new DataProtectionProvider();
    return dpapi.UnprotectAsync(block.AsBuffer()).AsTask().ToObservable().Select(b => b.ToArray());
}

(first convert the AsyncOperation to a Task with AsTask() and then use ToObservable on the Task) the deadlock seems to disappear...

The app is cross platform and I'm using the same code on Android and iOS, it works perfectly there. Also when using the unencrypted cache the app runs fine on windows.

Any ideas? ;)

flagbug commented 8 years ago

Looks just like https://github.com/akavache/Akavache/issues/205

Bouncaaa commented 8 years ago

Hello,

I am experiencing a similar problem except I can reproduce it systematically. I am building a uwp for the surface pro and I am using MVVMLight. I have a very simple login screen (2 fields and a button). The button calls an MVVMlight AsyncRelayCommand in which I first do an asynchronous call the the login web service and then I save the credentials into Blob.secure which hangs every time (through the extention method Blob.secure.SaveLogin(...)).

If I make a dummy call in the App.xaml.cs to Blob.secure.SaveLogin(...) then it all works fine.

Here is the login code:

ILoginRequest request = new LoginRequest(_apiKeychain.ClientId, userName, password);
ILoginResponse response = await _api.Login(request);
await _secureCache.SaveCredentials(userName, password);
await _secureCache.InsertObject(AccessTokenKey, response.Token);
return response.Token;

Note in the above code SaveCredentials is just a wrapper around Blob.secure.SaveLogin.

I just can't figure out why making dummy calls at startup changes anything.

Any help would be much appreciated.

Cheers

Bouncaaa commented 8 years ago

the solution proposed in #216 worked for me. Make a dummy call to the secure blob cache in the App.xaml.cs like await BlobCache.Secure.InsertObject("dummy", "dummy"); and this properly initializes Akavache.