public async Task <bool> RemoveKeyPair(CancellationToken ct, string name)
        {
            if (this.Log().IsEnabled(LogLevel.Debug))
            {
                this.Log().Debug($"Removing the key pair (name: '{name}').");
            }

            name.Validation().NotNullOrEmpty(nameof(name));

            await AssertTouchIdIsEnabled(ct);

            using (await _asyncLock.LockAsync(ct))
            {
                var status = SecKeyChain.Remove(new SecRecord(SecKind.Key)
                {
                    ApplicationTag = $"{name}_priv"
                });

                if (this.Log().IsEnabled(LogLevel.Information))
                {
                    this.Log().Info($"Successfully removed the key pair (name: '{name}').");
                }

                return(status == SecStatusCode.Success);
            }
        }
示例#2
0
        /// <summary>
        /// Removes the record.
        /// </summary>
        /// <returns>The record.</returns>
        /// <param name="key">Key.</param>
        private SecStatusCode RemoveRecord(string key)
        {
            SecStatusCode ssc;
            SecRecord     found = GetRecord(key, out ssc);

            // if it exists, delete it
            if (ssc == SecStatusCode.Success)
            {
                // this has to be different that the one queried
                var sr = new SecRecord(StoreSecKind);
                sr.Account   = key;
                sr.ValueData = found.ValueData;
                if (DefaultAccessible != SecAccessible.Invalid)
                {
                    sr.Accessible = DefaultAccessible;
                }

                if (UseCloud)
                {
                    sr.Synchronizable = true;
                }
                return(SecKeyChain.Remove(sr));
            }

            return(SecStatusCode.NoSuchKeyChain);
        }
示例#3
0
        /// <summary>
        /// Delete the specified credential based on user ID and SSO group key.
        /// </summary>
        /// <param name="userID">User identifier.</param>
        /// <param name="ssoGroupKey">SSO Group Key.</param>
        override public void Delete(string userID, string ssoGroupKey)
        {
            var nativeCredEnumeration = FindCredentialsForOrg(ssoGroupKey);

            foreach (var nc in nativeCredEnumeration)
            {
                //if (nc.UserID.Equals(userID))
                //{
                //query.Account = nc.UserID;
                //break;
                //}

                SecRecord query = new SecRecord(SecKind.GenericPassword);
                query.Service = ssoGroupKey;
                query.Account = nc.UserID;

                var statusCode = SecKeyChain.Remove(query);

                if (statusCode != SecStatusCode.Success &&
                    statusCode != SecStatusCode.ItemNotFound)
                {
                    throw new KinveyException(EnumErrorCategory.ERROR_USER, EnumErrorCode.ERROR_MIC_CREDENTIAL_DELETE, statusCode.ToString());
                }
            }
        }
示例#4
0
        public void ServiceCallBack(ServiceCallbackHelper data)
        {
            if (data.Status == "error")
            {
                UIAlertView error = new UIAlertView("Ошибка", "Вы неправильно ввели логин или пароль.Попробуйте снова.", null, "Закрыть", null);
                error.Show();
                btnLogin.Enabled = true;
            }
            else
            {
                var record = new SecRecord(SecKind.GenericPassword)
                {
                    Description = KeyChain.Description,
                    Comment     = KeyChain.Comment,
                    Service     = KeyChain.Service,
                    Label       = KeyChain.Label,
                    Account     = txtLogin.Text,
                    ValueData   = NSData.FromString(txtPassword.Text),
                    Generic     = NSData.FromString(KeyChain.Generic),
                    Accessible  = SecAccessible.Always
                };
                SecStatusCode code = SecKeyChain.Add(record);
                if (code == SecStatusCode.DuplicateItem)
                {
                    code = SecKeyChain.Remove(existingRec);
                }
                if (code == SecStatusCode.Success)
                {
                    code = SecKeyChain.Add(record);
                }


                PerformSegue("autherication", this);
            }
        }
示例#5
0
        void Accessible(SecAccessible access)
        {
            var rec = new SecRecord(SecKind.GenericPassword)
            {
                Account = "Username"
            };

            SecKeyChain.Remove(rec);              // it might already exists (or not)

            rec = new SecRecord(SecKind.GenericPassword)
            {
                Account    = "Username",
                ValueData  = NSData.FromString("Password"),
                Accessible = access
            };

            Assert.That(SecKeyChain.Add(rec), Is.EqualTo(SecStatusCode.Success), "Add");

            SecStatusCode code;
            var           match = SecKeyChain.QueryAsRecord(rec, out code);

            Assert.That(code, Is.EqualTo(SecStatusCode.Success), "QueryAsRecord");

            Assert.That(match.Accessible, Is.EqualTo(access), "Accessible");
        }
示例#6
0
        public void Add_Certificate()
        {
#if MONOMAC && !NET
            Stream certStream = typeof(KeyChainTest).Assembly.GetManifestResourceStream("xammac_tests.Security.openssl_crt.der");
#else
            Stream certStream = typeof(KeyChainTest).Assembly.GetManifestResourceStream("monotouchtest.Security.openssl_crt.der");
#endif
            NSData data = NSData.FromStream(certStream);

            var query = new SecRecord(SecKind.Certificate)
            {
                Label = $"Internet Widgits Pty Ltd",
            };
            var rec = query.Clone();
            rec.SetValueRef(new SecCertificate(data));

            try {
                // delete any existing certificates first.
                SecKeyChain.Remove(query);
                // add the new certificate
                var rc = SecKeyChain.Add(rec);
                Assert.That(rc, Is.EqualTo(SecStatusCode.Success), "Add_Certificate");
            } finally {
                // clean up after ourselves
                SecKeyChain.Remove(query);
            }
        }
示例#7
0
        public void GenerateKeyPairTest()
        {
            NSError error;
            SecKey  private_key;
            SecKey  public_key;
            var     att = new SecPublicPrivateKeyAttrs();

            att.Label            = $"{CFBundle.GetMain ().Identifier}-{GetType ().FullName}-{Process.GetCurrentProcess ().Id}";
            att.IsPermanent      = false;
            att.ApplicationTag   = new NSData();
            att.EffectiveKeySize = 1024;
            att.CanEncrypt       = false;
            att.CanDecrypt       = false;
            att.CanDerive        = false;
            att.CanSign          = false;
            att.CanVerify        = false;
            att.CanUnwrap        = false;

            try {
                Assert.That(SecKey.GenerateKeyPair(SecKeyType.RSA, 1024, att, out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");


                Assert.Throws <ArgumentException> (() => { SecKey.GenerateKeyPair(SecKeyType.Invalid, -1, null, out _, out _); }, "GenerateKeyPair - Invalid");
                Assert.That(SecKey.GenerateKeyPair(SecKeyType.RSA, -1, null, out _, out _), Is.EqualTo(SecStatusCode.Param), "GenerateKeyPair - Param issue, invalid RSA key size");
                Assert.That(SecKey.GenerateKeyPair(SecKeyType.RSA, 1024, null, out _, out _), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair - Null optional params, success");

#if IOS
                var att2 = new SecPublicPrivateKeyAttrs();
                att2.IsPermanent      = false;
                att2.EffectiveKeySize = 1024;
                att2.CanEncrypt       = true;
                att2.CanDecrypt       = true;
                att2.CanDerive        = true;
                att2.CanSign          = true;
                att2.CanVerify        = true;
                att2.CanUnwrap        = true;
                Assert.That(SecKey.GenerateKeyPair(SecKeyType.RSA, 1024, att, att2, out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair - iOS Only API");
#endif
                if (TestRuntime.CheckXcodeVersion(8, 0))
                {
                    using (var attrs = public_key.GetAttributes()) {
                        Assert.That(attrs.Count, Is.GreaterThan((nuint)0), "public/GetAttributes");
                    }
                    using (var attrs = private_key.GetAttributes()) {
                        Assert.That(attrs.Count, Is.GreaterThan((nuint)0), "private/GetAttributes");
                    }
                }
            } finally {
                var query = new SecRecord(SecKind.Key)
                {
                    Label = att.Label,
                };
                SecStatusCode code;
                do
                {
                    // For some reason each call to SecKeyChain will only remove a single key, so do a loop.
                    code = SecKeyChain.Remove(query);
                } while (code == SecStatusCode.Success);
            }
        }
        private void SaveRecord()
        {
            var record = new SecRecord(SecKind.GenericPassword)
            {
                Label       = "交易密碼",
                Description = "用於xxx服務",
                Account     = "*****@*****.**",
                Service     = "Transcation",
                Comment     = "Demo",
                ValueData   = NSData.FromString("P@ssw0rd"),
                Generic     = NSData.FromString("SecurityChainDemo")
            };

            var status = SecKeyChain.Add(record);

            if (SecStatusCode.Success == status)
            {
                Debug.WriteLine("Keychain Saved!");
            }
            else if (SecStatusCode.DuplicateItem == status || SecStatusCode.DuplicateKeyChain == status)
            {
                Debug.WriteLine("Duplicate !");
                SecKeyChain.Remove(record);
            }
            else
            {
                Debug.WriteLine($"{ status }");
            }
        }
示例#9
0
        void Protocol(SecProtocol protocol)
        {
            var rec = new SecRecord(SecKind.InternetPassword)
            {
                Account = "Protocol"
            };

            SecKeyChain.Remove(rec);              // it might already exists (or not)

            rec = new SecRecord(SecKind.InternetPassword)
            {
                Account   = "Protocol",
                ValueData = NSData.FromString("Password"),
                Protocol  = protocol,
                Server    = "www.xamarin.com"
            };

            Assert.That(SecKeyChain.Add(rec), Is.EqualTo(SecStatusCode.Success), "Add");

            SecStatusCode code;
            var           match = SecKeyChain.QueryAsRecord(rec, out code);

            Assert.That(code, Is.EqualTo(SecStatusCode.Success), "QueryAsRecord");

            Assert.That(match.Protocol, Is.EqualTo(protocol), "Protocol");
        }
示例#10
0
        public bool TryRemove(KeyType key)
        {
            var result = SecKeyChain.Remove(GetQuery(config.Prefix + key));

            Logger.Shared.Debug($"KeychainService.TryRemove: {result} => {key}");
            return(result.Equals(SecStatusCode.Success));
        }
        public void AfterAccess(TokenCacheNotificationArgs args)
        {
            if (args.TokenCache.HasStateChanged)
            {
                try
                {
                    var s = new SecRecord(SecKind.GenericPassword)
                    {
                        Generic     = NSData.FromString(LocalSettingsContainerName),
                        Accessible  = SecAccessible.Always,
                        Service     = "ADAL.PCL.iOS Service",
                        Account     = "ADAL.PCL.iOS cache",
                        Label       = "ADAL.PCL.iOS Label",
                        Comment     = "ADAL.PCL.iOS Cache",
                        Description = "Storage for cache"
                    };

                    var err = SecKeyChain.Remove(s);
                    if (args.TokenCache.Count > 0)
                    {
                        s.ValueData = NSData.FromArray(args.TokenCache.Serialize());
                        err         = SecKeyChain.Add(s);
                    }

                    args.TokenCache.HasStateChanged = false;
                }
                catch (Exception ex)
                {
                    PlatformPlugin.Logger.Warning(null, "Failed to save cache: " + ex);
                }
            }
        }
示例#12
0
        public override void RemoveStoredKeyValuePairs(string[] keynames)
        {
            string        sAccessGroup        = KeyChainAccessGroup;
            List <string> successfullKeyPairs = new List <string>();
            List <string> failedKeyPairs      = new List <string>();

            UIApplication.SharedApplication.InvokeOnMainThread(delegate {
                foreach (string keyname in keynames)
                {
                    SecRecord srDeleteEntry = new SecRecord(SecKind.GenericPassword)
                    {
                        Account = keyname
                    };

                    if (sAccessGroup != null)
                    {
                        srDeleteEntry.AccessGroup = sAccessGroup;
                    }

                    SecStatusCode code = SecKeyChain.Remove(srDeleteEntry);
                    if (code == SecStatusCode.Success)
                    {
                        successfullKeyPairs.Add(keyname);
                    }
                    else
                    {
                        failedKeyPairs.Add(keyname);
                    }
                }
                SystemLogger.Log(SystemLogger.Module.PLATFORM, "RemoveStoredKeyValuePair - Success: " + successfullKeyPairs.Count + ", Failed: " + failedKeyPairs.Count);

                IPhoneUtils.GetInstance().FireUnityJavascriptEvent("Appverse.OnKeyValuePairsRemoveCompleted", new object[] { successfullKeyPairs, failedKeyPairs });
            });
        }
示例#13
0
        public void SetSecured(string key, string value, string clientId, string service, string sharedGroupId)
        {
            var s = new SecRecord(SecKind.GenericPassword)
            {
                Service = $"{clientId}-{key}-{service}",
            };

            SecStatusCode res;
            var           match = SecKeyChain.QueryAsRecord(s, out res);

            if (res == SecStatusCode.Success)
            {
                var remStatus = SecKeyChain.Remove(s);
            }

            s.ValueData = NSData.FromString(value);

            if (!string.IsNullOrWhiteSpace(sharedGroupId))
            {
                s.AccessGroup = sharedGroupId;
            }

            var err = SecKeyChain.Add(s);

            Console.WriteLine(err);
        }
示例#14
0
        /// <summary>
        /// Adds an entry into key chain. If a duplicate is found, it is removed & re-added.
        /// </summary>
        /// <param name="secureValues">Object containing secure values</param>
        /// <returns>Whether the key chain entry was added successfully.</returns>
        public static bool StoreSecureDataInKeychain(KeyStoreModel secureValues)
        {
            var success = false;
            var s       = new SecRecord(SecKind.GenericPassword)
            {
                ValueData   = NSData.FromString(JsonConvert.SerializeObject(secureValues)),
                Generic     = NSData.FromString(KEY),
                AccessGroup = "H29ZBDYNSU.com.andculture.boilerplate"                 // TODO: Change to your app's bundle id
            };
            var err = SecKeyChain.Add(s);

            if (err == SecStatusCode.DuplicateItem)
            {
                err = SecKeyChain.Remove(s);
                if (err == SecStatusCode.Success)
                {
                    return(StoreSecureDataInKeychain(secureValues));
                }
            }
            else if (err == SecStatusCode.Success)
            {
                success = true;
            }
            return(success);
        }
        public void SaveUserInfo(string userId, string userName, string password)
        {
            var rec = new SecRecord(SecKind.GenericPassword)
            {
                Generic = NSData.FromString("password")
            };

            SecStatusCode res;
            var           match = SecKeyChain.QueryAsRecord(rec, out res);

            if (res == SecStatusCode.Success)
            {
                res = SecKeyChain.Remove(rec);
            }

            var s = new SecRecord(SecKind.GenericPassword)
            {
                Service   = "BodyReportUserInfo",
                Account   = userId + (char)3 + userName,
                ValueData = NSData.FromString(password),
                Generic   = NSData.FromString("password")
            };

            res = SecKeyChain.Add(s);
        }
    public void Save(string pin, string serviceId)
    {
        var statusCode        = SecStatusCode.Success;
        var serializedAccount = pin;
        var data = NSData.FromString(serializedAccount, NSStringEncoding.UTF8);
        //
        // Remove any existing record
        //
        var existing = FindAccount(serviceId);

        if (existing != null)
        {
            var query = new SecRecord(SecKind.GenericPassword);
            query.Service = serviceId;
            statusCode    = SecKeyChain.Remove(query);
            if (statusCode != SecStatusCode.Success)
            {
                throw new Exception("Could not save account to KeyChain: " + statusCode);
            }
        }
        //
        // Add this record
        //
        var record = new SecRecord(SecKind.GenericPassword);

        record.Service    = serviceId;
        record.Generic    = data;
        record.Accessible = SecAccessible.WhenUnlocked;
        statusCode        = SecKeyChain.Add(record);
        if (statusCode != SecStatusCode.Success)
        {
            throw new Exception("Could not save account to KeyChain: " + statusCode);
        }
    }
示例#17
0
        void AuthenticationType(SecAuthenticationType type)
        {
            var rec = new SecRecord(SecKind.InternetPassword)
            {
                Account = "AuthenticationType"
            };

            SecKeyChain.Remove(rec);              // it might already exists (or not)

            rec = new SecRecord(SecKind.InternetPassword)
            {
                Account            = "AuthenticationType",
                ValueData          = NSData.FromString("Password"),
                AuthenticationType = type,
                Server             = "www.xamarin.com"
            };

            Assert.That(SecKeyChain.Add(rec), Is.EqualTo(SecStatusCode.Success), "Add");

            SecStatusCode code;
            var           match = SecKeyChain.QueryAsRecord(rec, out code);

            Assert.That(code, Is.EqualTo(SecStatusCode.Success), "QueryAsRecord");

            Assert.That(match.AuthenticationType, Is.EqualTo(type), "AuthenticationType");
        }
示例#18
0
        void AuthenticationType(SecAuthenticationType type)
        {
            var rec = new SecRecord(SecKind.InternetPassword)
            {
                Account = "AuthenticationType"
            };

            SecKeyChain.Remove(rec);              // it might already exists (or not)

            rec = new SecRecord(SecKind.InternetPassword)
            {
                Account            = $"{CFBundle.GetMain ().Identifier}-{GetType ().FullName}-{Process.GetCurrentProcess ().Id}",
                ValueData          = NSData.FromString("Password"),
                AuthenticationType = type,
                Server             = "www.xamarin.com"
            };

            Assert.That(SecKeyChain.Add(rec), Is.EqualTo(SecStatusCode.Success), "Add");

            var query = new SecRecord(SecKind.InternetPassword)
            {
                Account            = rec.Account,
                AuthenticationType = rec.AuthenticationType,
                Server             = rec.Server,
            };

            SecStatusCode code;
            var           match = SecKeyChain.QueryAsRecord(query, out code);

            Assert.That(code, Is.EqualTo(SecStatusCode.Success), "QueryAsRecord");

            Assert.That(match.AuthenticationType, Is.EqualTo(type), "AuthenticationType");
        }
        /// <summary>
        /// Deletes a username/password record.
        /// </summary>
        /// <param name="username">the username to query. Not case sensitive. May not be NULL.</param>
        /// <param name="serviceId">the service description to query. Not case sensitive.  May not be NULL.</param>
        /// <param name="synchronizable">
        /// Defines if the record you want to delete is syncable via iCloud keychain or not. Note that using the same username and service ID
        /// but different synchronization settings will result in two keychain entries.
        /// </param>
        /// <returns>Status code</returns>
        public static SecStatusCode DeletePasswordForUsername(string username, string serviceId, bool synchronizable)
        {
            if (username == null)
            {
                throw new ArgumentNullException("userName");
            }

            if (serviceId == null)
            {
                throw new ArgumentNullException("serviceId");
            }

            // Querying is case sesitive - we don't want that.
            username  = username.ToLower();
            serviceId = serviceId.ToLower();

            // Query and remove.
            SecRecord queryRec = new SecRecord(SecKind.GenericPassword)
            {
                Service        = serviceId,
                Label          = serviceId,
                Account        = username,
                Synchronizable = synchronizable
            };
            SecStatusCode code = SecKeyChain.Remove(queryRec);

            return(code);
        }
示例#20
0
        public void AddQueryRemove_Identity()
        {
            using (SecRecord rec = new SecRecord(SecKind.Identity))
                using (var id = IdentityTest.GetIdentity()) {
                    rec.SetValueRef(id);
                    SecStatusCode code = SecKeyChain.Add(rec);
                    Assert.True(code == SecStatusCode.DuplicateItem || code == SecStatusCode.Success);
                }

            if (!TestRuntime.CheckXcodeVersion(5, 0))
            {
                Assert.Inconclusive("QueryAsConcreteType does not work before iOS7");
            }

            using (SecRecord rec = new SecRecord(SecKind.Identity)) {
                SecStatusCode code;
                var           match = SecKeyChain.QueryAsConcreteType(rec, out code);
                if ((match == null) && (code == SecStatusCode.ItemNotFound))
                {
                    Assert.Inconclusive("Test randomly fails (race condition between addtion/commit/query?");
                }

                Assert.That(code, Is.EqualTo(SecStatusCode.Success), "QueryAsRecord-2");
                Assert.NotNull(match, "match-2");

                code = SecKeyChain.Remove(rec);
                Assert.That(code, Is.EqualTo(SecStatusCode.Success), "Remove");

                match = SecKeyChain.QueryAsConcreteType(rec, out code);
                Assert.That(code, Is.EqualTo(SecStatusCode.ItemNotFound), "QueryAsRecord-3");
                Assert.Null(match, "match-3");
            }
        }
示例#21
0
        void Protocol(SecProtocol protocol)
        {
            var rec = new SecRecord(SecKind.InternetPassword)
            {
                Account = $"Protocol-{protocol}-{CFBundle.GetMain ().Identifier}-{GetType ().FullName}-{Process.GetCurrentProcess ().Id}",
            };

            try {
                SecKeyChain.Remove(rec);                  // it might already exists (or not)

                rec = new SecRecord(SecKind.InternetPassword)
                {
                    Account   = "Protocol",
                    ValueData = NSData.FromString("Password"),
                    Protocol  = protocol,
                    Server    = "www.xamarin.com"
                };

                Assert.That(SecKeyChain.Add(rec), Is.EqualTo(SecStatusCode.Success), "Add");

                SecStatusCode code;
                var           match = SecKeyChain.QueryAsRecord(rec, out code);
                Assert.That(code, Is.EqualTo(SecStatusCode.Success), "QueryAsRecord");

                Assert.That(match.Protocol, Is.EqualTo(protocol), "Protocol");
            } finally {
                // Clean up after us
                SecKeyChain.Remove(rec);
            }
        }
        protected override Task <SecureValueResult> NativeRemoveSecureValue(SecureValueRequestConfiguration secureValueRequestConfig, CancellationToken cancellationToken)
        {
#if __MAC__
            return(Task.FromResult(new SecureValueResult
            {
                Status = FingerprintAuthenticationResultStatus.NotAvailable,
                ErrorMessage = "Not implemented for the current platform."
            }));
#else
            var key       = secureValueRequestConfig.Key.ToLower();
            var serviceId = secureValueRequestConfig.ServiceId.ToLower();

            var secureRecord = new SecRecord(SecKind.GenericPassword)
            {
                Service = serviceId,
                Label   = serviceId,
                Account = key,
            };

            var statusCode = SecKeyChain.Remove(secureRecord);

            if (statusCode == SecStatusCode.Success)
            {
                return(Task.FromResult(new SecureValueResult
                {
                    Status = FingerprintAuthenticationResultStatus.Succeeded,
                }));
            }

            return(Task.FromResult(new SecureValueResult
            {
                Status = FingerprintAuthenticationResultStatus.UnknownError,
            }));
#endif
        }
示例#23
0
        public bool Remove(string key)
        {
            key = KeyPrefix + key;

            SecRecord record = new SecRecord(SecKind.GenericPassword)
            {
                Account = key,
                Service = Service
            };

            using (record)
                using (SecRecord match = SecKeyChain.QueryAsRecord(record, out SecStatusCode result))
                {
                    if (result == SecStatusCode.Success)
                    {
                        result = SecKeyChain.Remove(record);
                        if (result != SecStatusCode.Success && result != SecStatusCode.ItemNotFound)
                        {
                            throw new Exception($"Error removing record: {result}");
                        }

                        return(true);
                    }
                }

            return(false);
        }
示例#24
0
        /// <summary>
        /// Deletes any account credentials that are stored.
        /// </summary>
        public void DeleteAccountCredentials()
        {
            SecRecord recordToDelete = new SecRecord(SecKind.GenericPassword);

            recordToDelete.Service = this.applicationId;

            SecKeyChain.Remove(recordToDelete);
        }
示例#25
0
        public bool Delete(string key)
        {
            var query = strategy.KeyToQuery(key);
            var code  = SecKeyChain.Remove(query);

            SecureStoreStrategyExtensions.AssertOk(code);
            return(code != SecStatusCode.ItemNotFound);
        }
示例#26
0
 public void Clear()
 {
     using (var query = new SecRecord(SecKind.GenericPassword)
     {
         Service = this.Service
     })
         SecKeyChain.Remove(query);
 }
示例#27
0
        public void Remove(string key)
        {
            var rec = new SecRecord(SecKind.GenericPassword)
            {
                Generic = NSData.FromString(key)
            };

            SecKeyChain.Remove(rec);
        }
示例#28
0
 public void Remove(string key)
 {
     var existingRecord = new SecRecord(SecKind.GenericPassword)
     {
         Account = key,
         Service = NSBundle.MainBundle.BundleIdentifier
     };
     var code = SecKeyChain.Remove(existingRecord);
 }
示例#29
0
        public static void RemoveTokenKeyChain( )
        {
            SecRecord secRecord = GetTokenKeyChain(out SecRecord tokenQuery);

            if (secRecord != null)
            {
                SecKeyChain.Remove(secRecord);
            }
        }
 /// <summary>
 /// Deletes data.
 /// </summary>
 /// <param name="key">Key for the data to be deleted.</param>
 public void Delete(string key)
 {
     using (var record = GetExistingRecord(key))
     {
         if (record != null)
         {
             CheckError(SecKeyChain.Remove(record));
         }
     }
 }