示例#1
0
        private NativeCredential FindCredential(string username, string ssoGroupKey)
        {
            NativeCredential nc = null;

            var query = new SecRecord(SecKind.GenericPassword);

            query.Service = ssoGroupKey;
            query.Account = username;

            SecStatusCode result;
            var           record = SecKeyChain.QueryAsRecord(query, out result);

            if (record != null)
            {
                nc = GetCredentialFromRecord(record);
            }

            return(nc);
        }
示例#2
0
        public string Unprotect(string key)
        {
            var existingRecord = new SecRecord(SecKind.GenericPassword)
            {
                Account = key,
                Label   = key,
                Service = NSBundle.MainBundle.BundleIdentifier
            };

            // Locate the entry in the keychain, using the label, service and account information.
            // The result code will tell us the outcome of the operation.
            SecStatusCode resultCode;

            SecKeyChain.QueryAsRecord(existingRecord, out resultCode);

            return(resultCode == SecStatusCode.Success
                ? NSString.FromData(existingRecord.ValueData, NSStringEncoding.UTF8)
                : null);
        }
示例#3
0
        public string Retrieve(string key)
        {
            var recordToQueryWith = new SecRecord(SecKind.GenericPassword)
            {
                Generic = NSData.FromString(key)
            };

            SecStatusCode queryStatus;
            var           queriedRecord = SecKeyChain.QueryAsRecord(recordToQueryWith, out queryStatus);

            if (queryStatus == SecStatusCode.Success)
            {
                return(queriedRecord.ValueData.ToString());
            }
            else
            {
                return(null);
            }
        }
示例#4
0
        static internal void SetSecured(string key, string value, string clientId, string service)
        {
            var s = new SecRecord(SecKind.GenericPassword)
            {
                Service   = $"{clientId} - {service}",
                Generic   = NSData.FromString(key),
                ValueData = NSData.FromString(value),
            };

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

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

            var err = SecKeyChain.Add(s);
        }
示例#5
0
        private static bool RemoveRecord(SecRecord record)
        {
            try
            {
                var result = SecKeyChain.Remove(record);
                if (result != SecStatusCode.Success)
                {
                    Logger.Technical.From <Record>().Error($"Error removing record: {result}.").Log();
                }

                return(result == SecStatusCode.Success);
            }
            catch (Exception ex)
            {
                Logger.Technical.From <Record>().Exception(ex).Log();
            }

            return(false);
        }
        void ILegacyCachePersistence.WriteCache(byte[] serializedCache)
        {
            try
            {
                var s = new SecRecord(SecKind.GenericPassword)
                {
                    Generic     = NSData.FromString(LocalSettingsContainerName),
                    Accessible  = SecAccessible.Always,
                    Service     = NAME + " Service",
                    Account     = NAME + " cache",
                    Label       = NAME + " Label",
                    Comment     = NAME + " Cache",
                    Description = "Storage for cache"
                };

                if (keychainGroup != null)
                {
                    s.AccessGroup = keychainGroup;
                }

                var err = SecKeyChain.Remove(s);
                if (err != SecStatusCode.Success)
                {
                    string msg = "Failed to remove adal cache record: ";
                    MsalLogger.Default.WarningPii(msg + err, msg);
                }

                if (serializedCache != null && serializedCache.Length > 0)
                {
                    s.ValueData = NSData.FromArray(serializedCache);
                    err         = SecKeyChain.Add(s);
                    if (err != SecStatusCode.Success)
                    {
                        string msg = "Failed to save adal cache record: ";
                        MsalLogger.Default.WarningPii(msg + err, msg);
                    }
                }
            }
            catch (Exception ex)
            {
                MsalLogger.Default.WarningPiiWithPrefix(ex, "Failed to save adal cache: ");
            }
        }
示例#7
0
        /// <summary>
        /// Tries the get password.
        /// </summary>
        /// <returns><c>true</c>, if get password was tryed, <c>false</c> otherwise.</returns>
        /// <param name="username">Username.</param>
        /// <param name="service">Service.</param>
        /// <param name="password">Password.</param>
        public bool TryGetPassword(string username, string service, out string password)
        {
            password = string.Empty;

            if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(service))
            {
                return(false);
            }

            username = username.ToLower();
//          service = service.ToLower();

            SecStatusCode code;
            // Query the record.
            var queryRec = new SecRecord(SecKind.GenericPassword)
            {
                Service        = service,
                Label          = service,
                Account        = username,
                Synchronizable = Synchronizable
            };

            try
            {
                queryRec = SecKeyChain.QueryAsRecord(queryRec, out code);

                LastCode = code;

                if (LastCode == SecStatusCode.Success && queryRec != null && queryRec.ValueData != null)
                {
                    password = NSString.FromData(queryRec.ValueData, NSStringEncoding.UTF8).ToString();
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }

            System.Diagnostics.Debug.WriteLine(LastCode);
            // Something went wrong.
            return(LastCode == SecStatusCode.Success);
        }
        public static void AfterAccess(TokenCacheNotificationArgs args)
        {
            if (args.TokenCache.HasStateChanged)
            {
                try
                {
                    var s = new SecRecord(SecKind.GenericPassword)
                    {
                        Generic     = NSData.FromString(LocalSettingsContainerName),
                        Accessible  = SecAccessible.Always,
                        Service     = NAME + " Service",
                        Account     = NAME + " cache",
                        Label       = NAME + " Label",
                        Comment     = NAME + " Cache",
                        Description = "Storage for cache"
                    };

                    var err = SecKeyChain.Remove(s);
                    if (err != SecStatusCode.Success)
                    {
                        CallState.Default.Logger.Warning(null, "Failed to remove cache record: " + err);
                    }

                    if (args.TokenCache.Count > 0)
                    {
                        s.ValueData = NSData.FromArray(args.TokenCache.Serialize());
                        err         = SecKeyChain.Add(s);
                        if (err != SecStatusCode.Success)
                        {
                            CallState.Default.Logger.Warning(null, "Failed to save cache record: " + err);
                        }
                    }

                    args.TokenCache.HasStateChanged = false;
                }
                catch (Exception ex)
                {
                    CallState.Default.Logger.Warning(null, "Failed to save cache: ");
                    CallState.Default.Logger.ErrorPii(null, ex);
                }
            }
        }
示例#9
0
        public bool SetPassword(string password, string serviceName, string account, bool enableTouchId = false)
        {
            var record = new SecRecord(SecKind.GenericPassword)
            {
                Service = serviceName,
                Account = account
            };

            var updateCode = SecKeyChain.Remove(record);

            SecRecord newRecord = null;

            if (updateCode == SecStatusCode.Success || updateCode == SecStatusCode.ItemNotFound)
            {
                if (IsIos8 && enableTouchId)
                {
                    var secObject = new SecAccessControl(SecAccessible.WhenPasscodeSetThisDeviceOnly, SecAccessControlCreateFlags.UserPresence);

                    newRecord = new SecRecord(SecKind.GenericPassword)
                    {
                        Service   = serviceName,
                        Account   = account,
                        ValueData = password != null?NSData.FromString(password, NSStringEncoding.UTF8) : null,
                                        UseNoAuthenticationUI = true,
                                        AccessControl         = secObject
                    };
                }
                else
                {
                    newRecord = new SecRecord(SecKind.GenericPassword)
                    {
                        Service   = serviceName,
                        Account   = account,
                        ValueData = password != null?NSData.FromString(password, NSStringEncoding.UTF8) : null
                    };
                }

                updateCode = SecKeyChain.Add(newRecord);
            }

            return(updateCode == SecStatusCode.Success);
        }
        internal static byte[] GetRawBrokerKey()
        {
            byte[]    brokerKey = null;
            SecRecord record    = new SecRecord(SecKind.GenericPassword)
            {
                Generic     = NSData.FromString(LocalSettingsContainerName),
                Service     = "Broker Key Service",
                Account     = "Broker Key Account",
                Label       = "Broker Key Label",
                Comment     = "Broker Key Comment",
                Description = "Storage for broker key"
            };

            NSData key = SecKeyChain.QueryAsData(record);

            if (key == null)
            {
                AesManaged algo = new AesManaged();
                algo.GenerateKey();
                byte[] rawBytes = algo.Key;
                NSData byteData = NSData.FromArray(rawBytes);
                record = new SecRecord(SecKind.GenericPassword)
                {
                    Generic     = NSData.FromString(LocalSettingsContainerName),
                    Service     = "Broker Key Service",
                    Account     = "Broker Key Account",
                    Label       = "Broker Key Label",
                    Comment     = "Broker Key Comment",
                    Description = "Storage for broker key",
                    ValueData   = byteData
                };

                SecStatusCode code = SecKeyChain.Add(record);
                brokerKey = byteData.ToArray();
            }
            else
            {
                brokerKey = key.ToArray();
            }

            return(brokerKey);
        }
示例#11
0
        private string RetrieveKey(string keyName, string prompt)
        {
            if (this.Log().IsEnabled(LogLevel.Debug))
            {
                this.Log().Debug($"Retrieving the key pair (key name: '{keyName}', prompt: '{prompt}').");
            }

            var record = new SecRecord(SecKind.GenericPassword)
            {
                Service            = keyName.ToLowerInvariant(),
                UseOperationPrompt = prompt
            };

            var key = SecKeyChain.QueryAsRecord(record, out var result);

            switch (result)
            {
            case SecStatusCode.Success:

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

                return(key.Generic.ToString());

            case SecStatusCode.AuthFailed:

                if (this.Log().IsEnabled(LogLevel.Information))
                {
                    this.Log().Info($"Could not retrieve the key due to a failed authentication (key name: '{keyName}', prompt: '{prompt}').");
                }

                return(null);

            case SecStatusCode.ItemNotFound:
                throw new ArgumentException("Key not found.");

            default:
                throw new SecurityException(result);
            }
        }
示例#12
0
        private void saveXamarinAuthAccountInternal(Xamarin.Auth.Account account, SecAccessible access)
        {
            var accountStore = AccountStore.Create();
            var serviceId    = NSBundle.MainBundle.InfoDictionary["CFBundleName"].ToString();

            var statusCode        = SecStatusCode.Success;
            var serializedAccount = account.Serialize();
            var data = NSData.FromString(serializedAccount, NSStringEncoding.UTF8);

            // Remove any existing record
            var existing = accountStore.FindAccountsForService(serviceId);

            if (existing.Any())
            {
                var query = new SecRecord(SecKind.GenericPassword)
                {
                    Service = serviceId,
                    Account = account.Username
                };

                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)
            {
                Service    = serviceId,
                Account    = account.Username,
                Generic    = data,
                Accessible = access
            };

            statusCode = SecKeyChain.Add(record);
            if (statusCode != SecStatusCode.Success)
            {
                throw new Exception("Could not save account to KeyChain: " + statusCode);
            }
        }
示例#13
0
        public void TestUpdate()
        {
            var queryRecord = new SecRecord(SecKind.GenericPassword)
            {
                Account    = TestAccountName,
                Accessible = SecAccessible.WhenUnlocked
            };

            SecStatusCode queryStatusCode;
            SecRecord     queryResult;

            queryResult = SecKeyChain.QueryAsRecord(queryRecord, out queryStatusCode);
            if (queryStatusCode == SecStatusCode.ItemNotFound)
            {
                var newRecord = new SecRecord(SecKind.GenericPassword)
                {
                    Account    = TestAccountName,
                    Accessible = SecAccessible.WhenUnlocked,
                    Generic    = TestSecret
                };
                var newRecordStatusCode = SecKeyChain.Add(newRecord);
                Assert.True(newRecordStatusCode == SecStatusCode.Success);
            }

            queryResult = SecKeyChain.QueryAsRecord(queryRecord, out queryStatusCode);
            Assert.True(queryStatusCode == SecStatusCode.Success);
            Assert.True(TestSecret.Equals(queryResult.Generic));

            // try updating
            SecRecord newSecret = new SecRecord()
            {
                Generic = TestNewSecret
            };
            var updateStatusCode = SecKeyChain.Update(queryRecord, newSecret);

            Assert.True(updateStatusCode == SecStatusCode.Success,
                        string.Format("Got {0} instead", updateStatusCode));

            queryResult = SecKeyChain.QueryAsRecord(queryRecord, out queryStatusCode);
            Assert.True(queryStatusCode == SecStatusCode.Success);
            Assert.True(TestNewSecret.Equals(queryResult.Generic));
        }
        public ICollection <string> GetRecordsFromKeychain(string key)
        {
            List <string> returnResults = new List <string>();
            var           queryRecord   = new SecRecord(SecKind.GenericPassword)
            {
                AccessGroup = key
            };

            var records = SecKeyChain.QueryAsRecord(queryRecord, Int32.MaxValue, out SecStatusCode resultCode);

            if (resultCode == SecStatusCode.Success)
            {
                foreach (var r in records)
                {
                    var s = r.ValueData.ToString(Foundation.NSStringEncoding.UTF8);
                    returnResults.Add(s);
                }
            }
            return(returnResults);
        }
示例#15
0
        static Guid GetID()
        {
            Guid          returnGuid = Guid.Empty;
            SecStatusCode code;
            SecRecord     queryRec = new SecRecord(SecKind.GenericPassword)
            {
                Service = "KEYCHAIN_SERVICE",
                Label   = "KEYCHAIN_SERVICE",
                Account = "KEYCHAIN_ACCOUNT"
            };

            queryRec = SecKeyChain.QueryAsRecord(queryRec, out code);

            if (code == SecStatusCode.Success && queryRec != null && queryRec.Generic != null)
            {
                returnGuid = new Guid(NSString.FromData(queryRec.Generic, NSStringEncoding.UTF8));
            }

            return(returnGuid);
        }
示例#16
0
        public void SetToken(string token)
        {
            byte[] password_bytes = Encoding.UTF8.GetBytes(token);

            SecStatusCode result = SecKeyChain.AddGenericPassword(
                SERVICE, ACCOUNT, password_bytes);

            if (result == SecStatusCode.DuplicateItem)
            {
                // TODO: Replace the token
                // SecKeyChain.Remove ();
                // StoreToken (token);
                return;
            }

            if (result != SecStatusCode.Success)
            {
                throw new Exception("Could not store token in Keychain");
            }
        }
        internal SecStatusCode TryGetBrokerApplicationToken(string clientId, out string appToken)
        {
            var queryRecord = new SecRecord(SecKind.GenericPassword)
            {
                AccessGroup = _keychainGroup,
                Account     = clientId,
                Service     = iOSBrokerConstants.iOSBroker,
            };

            SecRecord record = SecKeyChain.QueryAsRecord(queryRecord, out SecStatusCode resultCode);

            appToken = null;

            if (resultCode == SecStatusCode.Success)
            {
                appToken = record.ValueData.ToString(NSStringEncoding.UTF8);
            }

            return(resultCode);
        }
        public static SecIdentity GetIdentity(X509Certificate certificate)
        {
            /*
             * If we got an 'X509Certificate2', then we require it to have a private key
             * and import it.
             */
            var certificate2 = certificate as X509Certificate2;

            if (certificate2 != null)
            {
                return(SecIdentity.Import(certificate2));
            }

            /*
             * Otherwise, we require the private key to be in the keychain.
             */
            using (var secCert = new SecCertificate(certificate)) {
                return(SecKeyChain.FindIdentity(secCert, true));
            }
        }
示例#19
0
        /// <summary>
        /// Saves the credentials to OS key store.
        /// </summary>
        /// <returns><c>true</c>, if credentials to OS key store was saved, <c>false</c> otherwise.</returns>
        /// <param name="userId">User identifier.</param>
        private bool SaveCredentialsToOSKeyStore(string userId)
        {
            var secRecord = new SecRecord(SecKind.GenericPassword)
            {
                Label       = "Keychain item for TouchId App",
                Description = "Keychain item for TouchId App",
                Account     = "Account",
                Service     = AppConstants.FullAppName,
                Comment     = "TouchId App",
                ValueData   = NSData.FromString(userId),
                Generic     = NSData.FromString("foobar")
            };

            secRecord.AccessControl = new SecAccessControl(SecAccessible.WhenPasscodeSetThisDeviceOnly, SecAccessControlCreateFlags.UserPresence);

            var result = SecKeyChain.Add(secRecord);

            Debug.WriteLine("OS Keystore: " + result.ToString());
            return(result == SecStatusCode.Success || result == SecStatusCode.DuplicateItem);
        }
示例#20
0
        public override void Delete(string key)
        {
            try
            {
                key = key.ToLower();
                if (string.IsNullOrEmpty(key))
                {
                    return;
                }

                SecRecord queryRec = new SecRecord(SecKind.GenericPassword)
                {
                    Service = serviceId, Label = serviceId, Account = key, Synchronizable = false
                };
                SecStatusCode code = SecKeyChain.Remove(queryRec);
            }
            catch (Exception)
            {
            }
        }
示例#21
0
        public void Set(string key, object value)
        {
            this.Remove(key);

            var content = this.serializer.Serialize(value);
            var record  = new SecRecord(SecKind.GenericPassword)
            {
                Account    = key,
                Service    = this.Service,
                Label      = key,
                Accessible = DefaultAccessible,
                ValueData  = NSData.FromString(content, NSStringEncoding.UTF8),
            };
            var result = SecKeyChain.Add(record);

            if (result != SecStatusCode.Success)
            {
                throw new ArgumentException("Failed to add secure value - " + result);
            }
        }
        void CopyMatchingAsync()
        {
            var securityRecord = new SecRecord(SecKind.GenericPassword)
            {
                Service            = Text.SERVICE_NAME,
                UseOperationPrompt = Text.AUTHENTICATE_TO_ACCESS_SERVICE_PASSWORD
            };

            DispatchQueue.MainQueue.DispatchAsync(() => {
                SecStatusCode status;
                NSData resultData = SecKeyChain.QueryAsData(securityRecord, false, out status);

                var result = resultData != null ? new NSString(resultData, NSStringEncoding.UTF8) : Text.USER_CANCELED_ACTION;

                var sb = new StringBuilder();
                sb.AppendFormat(Text.SEC_ITEM_COPY_MATCHING_STATUS, status.GetDescription());
                sb.AppendFormat(Text.RESULT, result);
                PrintResult(textView, sb.ToString());
            });
        }
示例#23
0
        public void UpdateKeyChainPassword(string account, string password)
        {
            SecRecord query = new SecRecord(SecKind.InternetPassword)
            {
                Server           = "com.crosshelper.cycbis",
                Service          = "com.crosshelper.cycbis",
                Account          = account,
                ApplicationLabel = "Cycbis",
            };
            SecRecord newAttributes = new SecRecord(SecKind.InternetPassword)
            {
                Server           = "com.crosshelper.cycbis",
                Service          = "com.crosshelper.cycbis",
                Account          = account,
                ApplicationLabel = "Cycbis",
                ValueData        = password
            };

            SecKeyChain.Update(query, newAttributes);
        }
示例#24
0
        private static string GetRecordsFromKeychain(string key, string service)
        {
            string        ret = null;
            SecStatusCode res;
            var           rec = new SecRecord(SecKind.GenericPassword)
            {
                Generic    = NSData.FromString(key),
                Account    = key,
                Accessible = SecAccessible.Always,
                Service    = service,
            };
            var match = SecKeyChain.QueryAsRecord(rec, out res);

            if (match != null)
            {
                // nsdata object :  match.ValueData;
                ret = match.ValueData.ToString(NSStringEncoding.UTF8);
            }
            return(ret);
        }
        void UpdateItemAsync()
        {
            var securityRecord = new SecRecord(SecKind.GenericPassword)
            {
                Service            = Text.SERVICE_NAME,
                UseOperationPrompt = Text.AUTH_TO_UPDATE
            };

            var recordUpdates = new SecRecord(SecKind.Identity)
            {
                ValueData = new NSString(Text.UPDATED_SECRET_PASSWORD_TEXT).Encode(NSStringEncoding.UTF8),
            };

            DispatchQueue.MainQueue.DispatchAsync(() => {
                var status = SecKeyChain.Update(securityRecord, recordUpdates);

                var message = string.Format(Text.SEC_ITEM_UPDATE_STATUS, status.GetDescription());
                PrintResult(textView, message);
            });
        }
示例#26
0
        public void IdentityRecordTest()
        {
            if (TestRuntime.CheckXcodeVersion(13, 0))
            {
                Assert.Ignore("code == errSecInternal (-26276)");
            }

            using (var identity = IdentityTest.GetIdentity())
                using (var rec = new SecRecord(identity)) {
                    SecStatusCode code = SecKeyChain.Add(rec);
                    Assert.True(code == SecStatusCode.DuplicateItem || code == SecStatusCode.Success, "Identity added");

                    var ret = rec.GetIdentity();
                    Assert.NotNull(ret, "ret is null");
                    Assert.That(identity.Handle, Is.EqualTo(ret.Handle), "Same Handle");

                    Assert.Throws <InvalidOperationException> (() => rec.GetKey(), "GetKey should throw");
                    Assert.Throws <InvalidOperationException> (() => rec.GetCertificate(), "GetCertificate should throw");
                }
        }
示例#27
0
        private static SecRecord FetchRecord(string username, out SecRecord searchRecord)
        {
            searchRecord = new SecRecord(SecKind.InternetPassword)
            {
                Service = ServiceName,
                Account = username
            };

            SecStatusCode code;
            var           data = SecKeyChain.QueryAsRecord(searchRecord, out code);

            if (code == SecStatusCode.Success)
            {
                return(data);
            }
            else
            {
                return(null);
            }
        }
示例#28
0
        public static string GetValue(string key)
        {
            var record = CreateSecRecord(key);

            try
            {
                var match = SecKeyChain.QueryAsRecord(record, out SecStatusCode resultCode);

                if (resultCode == SecStatusCode.Success)
                {
                    return(NSString.FromData(match.Generic, NSStringEncoding.UTF8));
                }
            }
            catch (Exception)
            {
                RemoveRecord(record);
            }

            return(String.Empty);
        }
        private static bool TryGetBrokerKey(out byte[] brokerKey)
        {
            SecRecord record = new SecRecord(SecKind.GenericPassword)
            {
                Generic = NSData.FromString(iOSBrokerConstants.LocalSettingsContainerName),
                Account = iOSBrokerConstants.BrokerKeyAccount,
                Service = iOSBrokerConstants.BrokerKeyService
            };

            NSData key = SecKeyChain.QueryAsData(record);

            if (key != null)
            {
                brokerKey = key.ToArray();
                return(true);
            }

            brokerKey = null;
            return(false);
        }
        /// <summary>
        /// Retrieves a password from the Keychain.
        /// </summary>
        /// <returns>The stored password if it exists. Else <c>null</c>.</returns>
        /// <param name="service">Service.</param>
        /// <param name="username">Username associated with the password.</param>
        /// <param name="synchronizable">Whether the item is synchronizable through iCloud.</param>
        private string GetPassword(string service, string username, bool synchronizable)
        {
            NonNull <string>(service, "service");
            NonNull(username, "username");

            SecRecord secRecord = new SecRecord(SecKind.GenericPassword)
            {
                Service        = service,
                Account        = username,
                Synchronizable = synchronizable
            };
            SecStatusCode secStatusCode;
            SecRecord     queryRecord = SecKeyChain.QueryAsRecord(secRecord, out secStatusCode);

            if (secStatusCode == SecStatusCode.Success && queryRecord != null && queryRecord.Generic != null)
            {
                return(NSString.FromData(queryRecord.Generic, NSStringEncoding.UTF8));
            }
            return(null);
        }