mirror of
https://github.com/bitwarden/android.git
synced 2024-11-01 15:45:42 +03:00
112 lines
2.9 KiB
C#
112 lines
2.9 KiB
C#
|
using System.IO;
|
||
|
using System.IO.IsolatedStorage;
|
||
|
using Java.Lang;
|
||
|
using Java.Security;
|
||
|
using Javax.Crypto;
|
||
|
using Android.OS;
|
||
|
using Bit.App.Abstractions;
|
||
|
|
||
|
namespace Bit.Android.Services
|
||
|
{
|
||
|
public class KeyStoreStorageService : ISecureStorageService
|
||
|
{
|
||
|
private const string StorageFile = "Bit.Android.KeyStoreStorageService";
|
||
|
|
||
|
private static readonly object SaveLock = new object();
|
||
|
|
||
|
private readonly KeyStore _keyStore;
|
||
|
private readonly KeyStore.PasswordProtection _protection;
|
||
|
|
||
|
public KeyStoreStorageService()
|
||
|
: this(Build.Serial.ToCharArray()) { }
|
||
|
|
||
|
public KeyStoreStorageService(char[] password)
|
||
|
{
|
||
|
_keyStore = KeyStore.GetInstance(KeyStore.DefaultType);
|
||
|
_protection = new KeyStore.PasswordProtection(password);
|
||
|
|
||
|
if(File.FileExists(StorageFile))
|
||
|
{
|
||
|
using(var stream = new IsolatedStorageFileStream(StorageFile, FileMode.Open, FileAccess.Read, File))
|
||
|
{
|
||
|
_keyStore.Load(stream, password);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_keyStore.Load(null, password);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static IsolatedStorageFile File
|
||
|
{
|
||
|
get { return IsolatedStorageFile.GetUserStoreForApplication(); }
|
||
|
}
|
||
|
|
||
|
public void Store(string key, byte[] dataBytes)
|
||
|
{
|
||
|
_keyStore.SetEntry(key, new KeyStore.SecretKeyEntry(new SecureData(dataBytes)), _protection);
|
||
|
Save();
|
||
|
}
|
||
|
|
||
|
public byte[] Retrieve(string key)
|
||
|
{
|
||
|
var entry = _keyStore.GetEntry(key, _protection) as KeyStore.SecretKeyEntry;
|
||
|
if(entry == null)
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
return entry.SecretKey.GetEncoded();
|
||
|
}
|
||
|
|
||
|
public void Delete(string key)
|
||
|
{
|
||
|
_keyStore.DeleteEntry(key);
|
||
|
Save();
|
||
|
}
|
||
|
|
||
|
public bool Contains(string key)
|
||
|
{
|
||
|
return _keyStore.ContainsAlias(key);
|
||
|
}
|
||
|
|
||
|
private void Save()
|
||
|
{
|
||
|
lock(SaveLock)
|
||
|
{
|
||
|
using(var stream = new IsolatedStorageFileStream(StorageFile, FileMode.OpenOrCreate, FileAccess.Write, File))
|
||
|
{
|
||
|
_keyStore.Store(stream, _protection.GetPassword());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private class SecureData : Object, ISecretKey
|
||
|
{
|
||
|
private const string Raw = "RAW";
|
||
|
|
||
|
private readonly byte[] _data;
|
||
|
|
||
|
public SecureData(byte[] dataBytes)
|
||
|
{
|
||
|
_data = dataBytes;
|
||
|
}
|
||
|
|
||
|
public string Algorithm
|
||
|
{
|
||
|
get { return Raw; }
|
||
|
}
|
||
|
|
||
|
public string Format
|
||
|
{
|
||
|
get { return Raw; }
|
||
|
}
|
||
|
|
||
|
public byte[] GetEncoded()
|
||
|
{
|
||
|
return _data;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|