public void Write(SecureStorageRequest request)
        {
            if(request == null) {
                throw new ArgumentNullException(nameof(request), "Cannot write a null storage request");
            }

            if(request.Data == null) {
                Delete(request);
                return;
            }

            var attrs = GetKeychainAttributes(request);
            attrs.ValueData = NSData.FromArray(request.Data.ToArray());
            attrs.CreationDate = NSDate.Now;
            attrs.ModificationDate = NSDate.Now;

            var err = SecKeyChain.Add(attrs);
            if(err == SecStatusCode.DuplicateItem) {
                Delete(request);
                err = SecKeyChain.Add(attrs);
            }

            if(err != SecStatusCode.Success) {
                Log.To.Sync.W(Tag, "{0} Couldn't save ID token: {1}", this, err);
                throw new IOException($"Couldn't save ID token: {err}");
            }

            Log.To.Sync.I(Tag, "{0} saved ID token to Keychain", this);
        }
        public void Write(SecureStorageRequest request)
        {
            if(request == null) {
                throw new ArgumentNullException(nameof(request), "Cannot write a null storage request");
            }

            if(request.Data == null) {
                Delete(request);
                return;
            }

            var data = request.Data.ToArray();
            var iv = default(string);
            var keyStore = KeyStore.GetInstance("AndroidKeyStore");
            keyStore.Load(null);
            var entry = (KeyStore.SecretKeyEntry)keyStore.GetEntry(Alias, null);
            var cipher = Cipher.GetInstance("AES/CBC/PKCS7Padding");
            cipher.Init(CipherMode.EncryptMode, entry.SecretKey);
            iv = Convert.ToBase64String(cipher.GetIV());
            data = cipher.DoFinal(data);

            var prefs = Application.Context.GetSharedPreferences(ServiceName, FileCreationMode.Private);
            var editor = prefs.Edit();
            var key = GetKey(request);
            editor.PutString(key, Convert.ToBase64String(data));
            editor.PutString($"{key}_iv", iv);
            editor.Commit();
        }
 public void Delete(SecureStorageRequest request)
 {
     var prefs = Application.Context.GetSharedPreferences(ServiceName, FileCreationMode.Private);
     var editor = prefs.Edit();
     var key = GetKey(request);
     editor.Remove(key);
     editor.Remove($"{key}_iv");
     editor.Commit();
 }
        public IEnumerable<byte> Read(SecureStorageRequest request)
        {
            var filename = GetFilename(request);
            if(!File.Exists(filename)) {
                return null;
            }

            using(var fs = File.OpenRead(filename))
            using(var buffer = RecyclableMemoryStreamManager.SharedInstance.GetStream("SecureStorage", (int)fs.Length)) {
                fs.CopyTo(buffer);
                return ProtectedData.Unprotect(buffer.GetBuffer().Take((int)buffer.Length).ToArray(), _Entropy, DataProtectionScope.CurrentUser);
            }
        }
        public void Delete(SecureStorageRequest request)
        {
            if (request.Account == null) {
                var folder = GetFoldername (request);
                try {
                    Directory.Delete (folder, true);
                } catch (DirectoryNotFoundException) {}
                return;
            }

            var filename = GetFilename(request);
            File.Delete(filename);
        }
        public void Write(SecureStorageRequest request)
        {
            if(request == null) {
                throw new ArgumentNullException(nameof(request), "Cannot write a null storage request");
            }

            if(request.Data == null) {
                Delete(request);
                return;
            }

            var filename = GetFilename(request);
            using(var fs = File.OpenWrite(filename)) {
                var encrypted = ProtectedData.Protect(request.Data.ToArray(), _Entropy, DataProtectionScope.CurrentUser);
                fs.Write(encrypted, 0, encrypted.Length);
            }
        }
        public IEnumerable<byte> Read(SecureStorageRequest request)
        {
            var attrs = GetKeychainAttributes(request);
            var err = default(SecStatusCode);
            var result = SecKeyChain.QueryAsRecord(attrs, out err);
           
            if(err != SecStatusCode.Success || result == null) {
                if(err == SecStatusCode.ItemNotFound) {
                    Log.To.Sync.I(Tag, "{0} No ID token found in Keychain", this);
                } else {
                    Log.To.Sync.W(Tag, "{0} Couldn't load ID token: {1}", this, err);
                }

                return null;
            }

            return result.ValueData.ToArray();
        }
        public IEnumerable<byte> Read(SecureStorageRequest request)
        {
            var key = GetKey(request);
            var prefs = Application.Context.GetSharedPreferences(ServiceName, FileCreationMode.Private);
            var saved = prefs.GetString(key, null);
            if(saved == null) {
                return null;
            }

            var data = Convert.FromBase64String(saved);
            var iv = Convert.FromBase64String(prefs.GetString($"{key}_iv", null));
            var keyStore = KeyStore.GetInstance("AndroidKeyStore");
            keyStore.Load(null);
            var entry = (KeyStore.SecretKeyEntry)keyStore.GetEntry(Alias, null);
            var cipher = Cipher.GetInstance("AES/CBC/PKCS7Padding");
            cipher.Init(CipherMode.DecryptMode, entry.SecretKey, new IvParameterSpec(iv));
            data = cipher.DoFinal(data);

            return data;
        }
 private SecRecord GetKeychainAttributes(SecureStorageRequest request)
 {
     return new SecRecord(SecKind.GenericPassword) {
         Service = request.Service,
         Account = request.Account,
         Label = request.Label
     };
 }
 public void Delete(SecureStorageRequest request)
 {
     var atts = GetKeychainAttributes(request);
     SecKeyChain.Remove(atts);
 }
 private string GetFilename(SecureStorageRequest request)
 {
     var filenameBytes = Encoding.UTF8.GetBytes($"{request.Account}");
     return Path.Combine(GetFoldername(request), $"{Misc.HexSHA1Digest(filenameBytes)}.bin");
 }
 private string GetFoldername (SecureStorageRequest request)
 {
     var folderBytes = Encoding.UTF8.GetBytes ($"{request.Service}{request.Label}");
     var retVal = Path.Combine (_BaseDirectory, $"{Misc.HexSHA1Digest (folderBytes)}");
     Directory.CreateDirectory (retVal);
     return retVal;
 }
 private string GetKey(SecureStorageRequest request)
 {
     return $"{request.Label}{request.Account}";
 }
        public void Write(SecureStorageRequest request)
        {
            if(!_HasKeyStore) {
                return;
            }

            var encrypted = Encrypt(request.Data.ToArray());
            if(encrypted == null) {
                return;
            }

            var prefs = Application.Context.GetSharedPreferences(ServiceName, FileCreationMode.Private);
            var editor = prefs.Edit();
            var key = GetKey(request);
            editor.PutString($"{key}_key", Convert.ToBase64String(encrypted[0]));
            editor.PutString($"{key}_data", Convert.ToBase64String(encrypted[1]));
            editor.Commit();
        }
        public IEnumerable<byte> Read(SecureStorageRequest request)
        {
            if(!_HasKeyStore) {
                return null;
            }

            var prefs = Application.Context.GetSharedPreferences(ServiceName, FileCreationMode.Private);
            var key = GetKey(request);
            if(!prefs.Contains($"{key}_key") || !prefs.Contains($"{key}_data")) {
                return null;
            }

            var secretKey = Convert.FromBase64String(prefs.GetString($"{key}_key", null));
            var data = Convert.FromBase64String(prefs.GetString($"{key}_data", null));
            return Decrypt(secretKey, data);
        }