public void BeforeAccess(TokenCacheNotificationArgs args)
        {
            if (args.TokenCache.Count > 0)
            {
                // We assume that the cache has not changed since last write
                return;
            }

            try
            {
                SecStatusCode res;
                var rec = new SecRecord(SecKind.GenericPassword)
                {
                    Generic = NSData.FromString(LocalSettingsContainerName)
                };

                var match = SecKeyChain.QueryAsRecord(rec, out res);
                if (res == SecStatusCode.Success && match != null && match.ValueData != null)
                {
                    byte[] dataBytes = match.ValueData.ToArray();
                    if (dataBytes != null)
                    {
                        args.TokenCache.Deserialize(dataBytes);
                    }
                }
            }
            catch (Exception ex)
            {
                PlatformPlugin.Logger.Warning(null, "Failed to load cache: " + ex);
                // Ignore as the cache seems to be corrupt
            }
        }
        public void AfterAccess(TokenCacheNotificationArgs args)
        {
            if (args.TokenCache.HasStateChanged)
            {
                try
                {
                    var s = new SecRecord(SecKind.GenericPassword)
                    {
                        Generic = NSData.FromString(LocalSettingsContainerName)
                    };

                    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);
                }
            }
        }
Esempio n. 3
0
		// This method is invoked when the application has loaded its UI and its ready to run
		public override bool FinishedLaunching (UIApplication app, NSDictionary options)
		{
			var rec = new SecRecord (SecKind.GenericPassword){
				Generic = NSData.FromString ("foo")
			};
			
			SecStatusCode res;
			var match = SecKeyChain.QueryAsRecord (rec, out res);
			if (res == SecStatusCode.Success)
				DisplayMessage ("Key found, password is: {0}", match.ValueData);
			else
				DisplayMessage ("Key not found: {0}", res);
			
			var s = new SecRecord (SecKind.GenericPassword) {
				Label = "Item Label",
				Description = "Item description",
				Account = "Account",
				Service = "Service",
				Comment = "Your comment here",
				ValueData = NSData.FromString ("my-secret-password"),
				Generic = NSData.FromString ("foo")
			};
			
			var err = SecKeyChain.Add (s);
			
			if (err != SecStatusCode.Success && err != SecStatusCode.DuplicateItem)
				DisplayMessage ("Error adding record: {0}", err);
			
			window.MakeKeyAndVisible ();
			
			return true;
		}
		public static Result<bool> StoreCredential(Credential credential) {
			var result = QueryForRecord ();
			if (result.Success && result.Value.Username.Equals(credential.Username) && result.Value.Password.Equals (credential.Password)) {
				Console.WriteLine ("Credential already exists with username/that password.");
				return Result<bool>.Succeeded (true);
			}

			var record = new SecRecord (SecKind.GenericPassword) {
				Generic = NSData.FromString(KC_KEY),
				Label = "teentix",
				Account = credential.Username,
				Description = "TeenTix mobile app account credentials.",
				Comment = "TeenTix mobile app account credentials.",
				ValueData = NSData.FromString(credential.Password)
			};

			Console.WriteLine ("Saving credential: {0}", credential);
			var error = SecKeyChain.Add (record);

			if (error != SecStatusCode.Success && error != SecStatusCode.DuplicateItem) {
				string msg = string.Format ("Error adding record: {0}", error);
				Console.WriteLine (msg);
				return Result<bool>.Failed (msg);
			} else {
				Console.WriteLine ("Successfully wrote credential: {0}", credential);
				return Result<bool>.Succeeded (true);
			}
		}
		public void Store (string key, string value)
		{
			var recordToQueryWith = new SecRecord (SecKind.GenericPassword) {
				Generic = NSData.FromString (key)
			};

			var recordToAdd = new SecRecord (SecKind.GenericPassword) {
				Generic = NSData.FromString (key),
				ValueData = NSData.FromString (value),
				Account = key,
				Service = key
			};


			SecStatusCode queryStatus;
			SecKeyChain.QueryAsRecord (recordToQueryWith, out queryStatus);
			if (queryStatus == SecStatusCode.Success) //existing found
			{
				SecStatusCode removeStatus = SecKeyChain.Remove (recordToQueryWith);

				if (removeStatus != SecStatusCode.Success) {
					throw new Exception ("Could not remove existing key."); //TODO: need to use another exception?
				} 
			} 

			var addStatus = SecKeyChain.Add (recordToAdd);

			if (addStatus != SecStatusCode.Success && addStatus != SecStatusCode.DuplicateItem) {
				throw new Exception ("Could not add key successfully."); //TODO: need to use another exception?
			}

		}
		public string GetIdentifier()
		{
			string serial = string.Empty;
			var rec = new SecRecord(SecKind.GenericPassword)
			{
				Generic = NSData.FromString("uidNumber")
			};

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

			if (res == SecStatusCode.Success)
			{
				serial = match.ValueData.ToString();
			}
			else
			{
				var uidNumberRecord = new SecRecord(SecKind.GenericPassword)
				{
					Label = "uid",
					ValueData = NSData.FromString(Guid.NewGuid().ToString()),
					Generic = NSData.FromString("uidNumber")
				};

				var err = SecKeyChain.Add(uidNumberRecord);
				serial = uidNumberRecord.ValueData.ToString();
			}

			return serial;

		}
Esempio n. 7
0
		// This method is invoked when the application has loaded its UI and its ready to run
		public override bool FinishedLaunching (UIApplication app, NSDictionary options)
		{
			var rec = new SecRecord (SecKind.GenericPassword){
				Generic = NSData.FromString ("foo")
			};
			
			SecStatusCode res;
			var match = SecKeyChain.QueryAsRecord (rec, out res);
			if (res == SecStatusCode.Success)
				Console.WriteLine ("Key existed, the password is: {0}", match.ValueData.ToString ());
			else
				Console.WriteLine ("Key not found, code: {0}", res);
			
			
			var s = new SecRecord (SecKind.GenericPassword) {
				Label = "Item Label",
				Description = "Item description",
				Account = "Account",
				Service = "Service",
				Comment = "Your comment here",
				ValueData = NSData.FromString ("my-secret-password"),
				Generic = NSData.FromString ("foo")
			};
			
			var err = SecKeyChain.Add (s);
			
			window.MakeKeyAndVisible ();
			
			return true;
		}
        /// <summary>
        /// Gets a password for a specific username.
        /// </summary>
        /// <param name="username">the username to query. Not case sensitive.  May not be NULL.</param>
        /// <param name="serviceId">the service description to use. Not case sensitive.  May not be NULL.</param>
        /// <param name="synchronizable">
        /// Defines if the record you want to get 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>
        /// The password or NULL if no matching record was found.
        /// </returns>
        public static string GetPasswordForUsername( 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 (  );

                SecStatusCode code;
                // Query the record.
                SecRecord queryRec = new SecRecord ( SecKind.GenericPassword ) { Service = serviceId, Label = serviceId, Account = username, Synchronizable = synchronizable };
                queryRec = SecKeyChain.QueryAsRecord ( queryRec, out code );

                // If found, try to get password.
                if ( code == SecStatusCode.Success && queryRec != null && queryRec.Generic != null )
                {
                    // Decode from UTF8.
                    return NSString.FromData ( queryRec.Generic, NSStringEncoding.UTF8 );
                }

                // Something went wrong.
                return null;
        }
		public static bool SaveValueToKeyChain (string entryKey, string entryValue)
		{
			SecRecord record = new SecRecord(SecKind.GenericPassword) { 
				Account = entryKey, 
				Label = entryKey, 
				Service = _keyChainServiceName };

			SecStatusCode resultCode;
			SecKeyChain.QueryAsRecord(record, out resultCode);

			if (resultCode == SecStatusCode.Success) {
				if (SecKeyChain.Remove (record) != SecStatusCode.Success) {
					return false;
				}
			}

			resultCode = SecKeyChain.Add(new SecRecord(SecKind.GenericPassword) { 
				Label = entryKey, 
				Account = entryKey, 
				Service = _keyChainServiceName,
				Accessible = SecAccessible.WhenUnlockedThisDeviceOnly,
				Synchronizable = false,
				ValueData = NSData.FromString(entryValue, NSStringEncoding.UTF8)
			});

			return resultCode == SecStatusCode.Success;
		}
Esempio n. 10
0
        /// <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.
            var queryRec = new SecRecord(SecKind.GenericPassword)
            {
                Service = serviceId,
                Label = serviceId,
                Account = username,
                Synchronizable = synchronizable
            };
            var code = SecKeyChain.Remove(queryRec);
            return code;
        }
		public KeyValuePair<string, string>? Load()
		{
			SecStatusCode res;
			var rec = new SecRecord(SecKind.GenericPassword)
			{
				Account = "login",
				Label = "login",
				Service = "login",
			};
			var match = SecKeyChain.QueryAsRecord(rec, out res);

			SecStatusCode res2;
			var rec2 = new SecRecord(SecKind.GenericPassword)
			{
				Account = "password",
				Label = "password",
				Service = "password",
			};

			var match2 = SecKeyChain.QueryAsRecord(rec2, out res2);


			if (match != null && match2 != null)
			{
				return new KeyValuePair<string, string>(match.ValueData.ToString(), match2.ValueData.ToString());
			}

			return null;
		}
Esempio n. 12
0
 public static void StoreKeysInKeychain(string key, string value)
 {
     var s = new SecRecord (SecKind.GenericPassword) {
         ValueData = NSData.FromString (value),
         Generic = NSData.FromString (key)
     };
     var err = SecKeyChain.Add (s);
 }
Esempio n. 13
0
 public void Remove(string key) {
     var existingRecord = new SecRecord(SecKind.GenericPassword) {
         Account = key,
         Label = key,
         Service = NSBundle.MainBundle.BundleIdentifier
     };
     SecKeyChain.Remove(existingRecord);
 }
Esempio n. 14
0
        public void RemoveValue(string key, ApplicationSettingsMode mode)
        {
            var rec = new SecRecord(SecKind.GenericPassword)
            {
                Label = key,
                Service = ServiceName,
                Account = key
            };

            var res = SecKeyChain.Remove(rec);
        }
		Account FindAccount (string username, string serviceId)
		{
			var query = new SecRecord (SecKind.GenericPassword);
			query.Service = serviceId;
			query.Account = username;

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

			return record != null ?	GetAccountFromRecord (record) : null;
		}
Esempio n. 16
0
        private static SecRecord GetKeyRecord(string key, NSData data = null)
        {
            var record = new SecRecord(SecKind.GenericPassword)
            {
                Service = NSBundle.MainBundle.BundleIdentifier,
                Account = key
            };

            if (data != null) record.ValueData = data;

            return record;
        }
		public override IEnumerable<Account> FindAccountsForService (string serviceId)
		{
			var query = new SecRecord (SecKind.GenericPassword);
			query.Service = serviceId;

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

			return records != null ?
				records.Select (GetAccountFromRecord).ToList () :
				new List<Account> ();
		}
 public LicenseKey()
 {
     rec = new SecRecord (SecKind.GenericPassword) {
         Label = "NTS Apollo Mobile",
         Description = "",
         Account = "NTSApolloMobile",
         Service = "NTSApolloMobile",
         Comment = "",
         ValueData = NSData.FromString (""),
         Generic = NSData.FromString ("NTSApolloMobile")
     };
 }
Esempio n. 19
0
        internal static string GetSecured(string id, string clientId, string service)
        {
            var rec = new SecRecord (SecKind.GenericPassword){
                Generic = NSData.FromString (id),
                Service = $"{clientId} - {service}",
            };

            SecStatusCode res;
            var match = SecKeyChain.QueryAsRecord (rec, out res);
            if (res == SecStatusCode.Success)
                return match.ValueData.ToString ();
            return "";
        }
Esempio n. 20
0
        public string GetSecured(string id, string clientId, string service, string sharedGroupId)
        {
            var rec = new SecRecord(SecKind.GenericPassword)
            {
                Service = $"{clientId}-{id}-{service}",
            };

            SecStatusCode res;
            var match = SecKeyChain.QueryAsRecord(rec, out res);
            if (res == SecStatusCode.Success)
                return match.ValueData.ToString();
            return "";
        }
Esempio n. 21
0
        public static string GetRecordsFromKeychain(string key)
        {
            string result = string.Empty;
            SecStatusCode res;
            var rec = new SecRecord (SecKind.GenericPassword) {
                Generic = NSData.FromString (key)
            };
            var match = SecKeyChain.QueryAsRecord (rec, out res);
            if (match != null) {
                result = match.ValueData.ToString ();
            }

            return result;
        }
		public void Clear()
		{
			SecRecord query2 = new SecRecord(SecKind.GenericPassword);
			query2.Account = "login";
			query2.Label = "login";
			query2.Service = "login";
			var err2 = SecKeyChain.Remove(query2);

			SecRecord query3 = new SecRecord(SecKind.GenericPassword);
			query3.Account = "password";
			query3.Label = "password";
			query3.Service = "password";
			var err3 = SecKeyChain.Remove(query2);
		}
		private string GetOldDeviceId()
		{
			var record = new SecRecord(SecKind.GenericPassword)
			{
				Service = DONKY_DEVICE_ID
			};

			var match = SecKeyChain.QueryAsData(record);
			if (match != null)
			{
				return match.ToString();
			}

			return null;
		}
Esempio n. 24
0
		public static void ClearAddCredentialsToKeychain ()
		{
			Console.WriteLine ("Clearing Any existing credentials");

			var securityRecord = new SecRecord (SecKind.GenericPassword) {
				Service = "TextShield"
			};

			DispatchQueue.MainQueue.DispatchAsync (() => {
				var status = SecKeyChain.Remove (securityRecord);

				Console.WriteLine("Delete status: " + status.ToString());
				AddCredentials();
			});
		}
Esempio n. 25
0
        internal static 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);
        }
Esempio n. 26
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;
        }
		private static SecRecord GetRecordForKey(string key)
		{
			var query = new SecRecord(SecKind.GenericPassword)
			{
				Service = key,
				Account = key
			};

			SecStatusCode queryResult;
			var match = SecKeyChain.QueryAsRecord(query, out queryResult);
			if (queryResult != SecStatusCode.Success)
			{
				return null;
			}

			return match;
		}
Esempio n. 28
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;
			}

		}
Esempio n. 29
0
        private bool RecordExists(string key)
        {
            var rec = new SecRecord(SecKind.GenericPassword)
            {
                Service = ServiceName,
                Label = key,
                Account = key
            };

            SecStatusCode res;
            var match = SecKeyChain.QueryAsRecord(rec, out res);
            if (res == SecStatusCode.Success)
            {
                return true;
            }

            return false;
        }
		public static string GetValueFromKeyChain(string entryKey)
		{
			string result = string.Empty;

			SecRecord record = new SecRecord(SecKind.GenericPassword) { 
				Account = entryKey, 
				Label = entryKey, 
				Service = _keyChainServiceName };

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

			if (resultCode == SecStatusCode.Success) {
				result = NSString.FromData(data.ValueData, NSStringEncoding.UTF8);
			}

			return result;
		}
        private byte[] SignCore(string pairName, byte[] data)
        {
            using (var record = new SecRecord(SecKind.Key))
            {
                record.ApplicationTag = $"{pairName}_priv";
                record.KeyClass       = SecKeyClass.Private;
                record.KeyType        = SecKeyType.EC;

                var result = SecKeyChain.QueryAsConcreteType(record, out var status);

                if (status == SecStatusCode.Success)
                {
                    var privateKey = (SecKey)result;

                    using (var sha256 = SHA256.Create())
                    {
                        var hash = sha256.ComputeHash(data);

                        var signStatus = privateKey.RawSign(SecPadding.PKCS1, hash, out var signature);

                        if (signStatus == SecStatusCode.Success)
                        {
                            return(signature);
                        }
                        else
                        {
                            throw new SecurityException(signStatus);
                        }
                    }
                }
                else
                {
                    throw new SecurityException(status);
                }
            }
        }
Esempio n. 32
0
        void HabilitarTecladoDesbloqueo()
        {
            var secRecord = new SecRecord(SecKind.GenericPassword)
            {
                Label       = "Keychain Item",
                Description = "fake item for keychain access",
                Account     = "Account",
                Service     = "com.bncr.sinpePrueba",
                Comment     = "Your comment here",
                ValueData   = NSData.FromString("my-secret-password"),
                Generic     = NSData.FromString("foo")
            };

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

            var rec = new SecRecord(SecKind.GenericPassword)
            {
                Service            = "com.bncr.sinpePrueba",
                UseOperationPrompt = "Digite su contraseña"
            };
            SecStatusCode res;

            SecKeyChain.QueryAsRecord(rec, out res);
            if (SecStatusCode.Success == res || SecStatusCode.ItemNotFound == res)
            {
                //Validación exitosa del Pin
                SecKeyChain.Remove(rec);
                Xamarin.Forms.Application.Current.MainPage.DisplayAlert("Atención", "Ingreso mediante huella dactilar desbloqueado exitosamente.", "Aceptar");
            }
            else
            {
                //Fallo en validación de Pin
                Xamarin.Forms.Application.Current.MainPage.DisplayAlert("Atención", "Ingreso mediante huella dactilar no disponible", "Aceptar");
            }
        }
Esempio n. 33
0
        public void RoundtripRSA512PKCS1()
        {
            SecKey private_key;
            SecKey public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.RSA;
                record.KeySizeInBits = 512;                 // it's not a performance test :)

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                byte [] plain = new byte [20] {
                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                };
                byte [] cipher;
                Assert.That(public_key.Encrypt(SecPadding.PKCS1, plain, out cipher), Is.EqualTo(SecStatusCode.Success), "Encrypt");
                public_key.Dispose();

                byte[] result;
                Assert.That(private_key.Decrypt(SecPadding.PKCS1, cipher, out result), Is.EqualTo(SecStatusCode.Success), "Decrypt");
                Assert.That(plain, Is.EqualTo(result), "match");
                private_key.Dispose();
            }
        }
Esempio n. 34
0
        public void SaveRecord(string key, string item)
        {
            var record = new SecRecord(SecKind.GenericPassword)
            {
                ValueData = NSData.FromString(item),
                Generic   = NSData.FromString(key)
            };

            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 }");
            }
        }
Esempio n. 35
0
        Account FindAccount(string username, string serviceId)
        {
            Account a = null;

            try
            {
                SecRecord query = new SecRecord(SecKind.GenericPassword);
                query.Service = serviceId;
                query.Account = username;

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

                a = record != null?GetAccountFromRecord(record) : null;
            }
            catch (System.Exception exc)
            {
                string msg = String.Format("FindAccount error = {0}", exc.Message);
                Debug.WriteLine(msg);
                throw new InvalidOperationException(msg);
            }

            return(a);
        }
Esempio n. 36
0
        public Task DeleteAsync(Account account, string serviceId)
        {
            try
            {
                var query = new SecRecord(SecKind.GenericPassword);
                query.Service = serviceId;
                query.Account = account.Username;

                var statusCode = SecKeyChain.Remove(query);

                if (statusCode != SecStatusCode.Success)
                {
                    throw new InvalidOperationException("Could not delete account from KeyChain: " + statusCode);
                }
            }
            catch (System.Exception exc)
            {
                string msg = String.Format("DeleteAsync error = {0}", exc.Message);
                Debug.WriteLine(msg);
                throw new InvalidOperationException(msg);
            }

            return(Task.FromResult(true));
        }
Esempio n. 37
0
        static SecStatusCode SetID(Guid setID)
        {
            var queryRec = new SecRecord(SecKind.GenericPassword)
            {
                Service = "KEYCHAIN_SERVICE",
                Label   = "KEYCHAIN_SERVICE",
                Account = "KEYCHAIN_ACCOUNT"
            };
            var record = queryRec.Clone();

            record.Generic    = NSData.FromString(Convert.ToString(setID), NSStringEncoding.UTF8);
            record.Accessible = SecAccessible.Always;
            SecStatusCode code = SecKeyChain.Add(record);

            if (code == SecStatusCode.DuplicateItem)
            {
                code = SecKeyChain.Remove(queryRec);
                if (code == SecStatusCode.Success)
                {
                    code = SecKeyChain.Add(record);
                }
            }
            return(code);
        }
        public bool SetPassword(string password, string serviceName, string account)
        {
            var record = new SecRecord(SecKind.GenericPassword)
            {
                Service = serviceName,
                Account = account
            };

            var updateCode = SecKeyChain.Remove(record);

            if (updateCode == SecStatusCode.Success || updateCode == SecStatusCode.ItemNotFound)
            {
                var 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);
        }
Esempio n. 39
0
        public void Match()
        {
            var rec = new SecRecord(SecKind.GenericPassword)
            {
                Account = "Username",
            };

            Assert.Null(rec.MatchIssuers, "MatchIssuers");
            // we do not have a way (except the getter) to craete SecKeyChain instances
            Assert.Null(rec.MatchItemList, "MatchItemList");

            using (var data = new NSData()) {
                rec.MatchIssuers = new NSData[] { data };
                Assert.AreSame(rec.MatchIssuers [0], data, "MatchIssuers [0]");
            }

            if (!TestRuntime.CheckXcodeVersion(7, 0))
            {
                return;
            }
            Assert.That(rec.AuthenticationUI, Is.EqualTo(SecAuthenticationUI.NotSet), "AuthenticationUI-get");
            rec.AuthenticationUI = SecAuthenticationUI.Allow;
            Assert.That(rec.AuthenticationUI, Is.EqualTo(SecAuthenticationUI.Allow), "AuthenticationUI-set");
        }
Esempio n. 40
0
        public void Store(string key, string value)
        {
            var recordToQueryWith = new SecRecord(SecKind.GenericPassword)
            {
                Generic = NSData.FromString(key)
            };

            var recordToAdd = new SecRecord(SecKind.GenericPassword)
            {
                Generic   = NSData.FromString(key),
                ValueData = NSData.FromString(value),
                Account   = key,
                Service   = key
            };


            SecStatusCode queryStatus;

            SecKeyChain.QueryAsRecord(recordToQueryWith, out queryStatus);
            if (queryStatus == SecStatusCode.Success)             //existing found
            {
                SecStatusCode removeStatus = SecKeyChain.Remove(recordToQueryWith);

                if (removeStatus != SecStatusCode.Success)
                {
                    throw new Exception("Could not remove existing key.");                      //TODO: need to use another exception?
                }
            }

            var addStatus = SecKeyChain.Add(recordToAdd);

            if (addStatus != SecStatusCode.Success && addStatus != SecStatusCode.DuplicateItem)
            {
                throw new Exception("Could not add key successfully.");                  //TODO: need to use another exception?
            }
        }
Esempio n. 41
0
        SecStatusCode SetID(Guid setID)
        {
            var queryRec = new SecRecord(SecKind.GenericPassword)
            {
                Service = RecordService,
                Account = RecordAccount,
            };
            var record = queryRec.Clone();

            record.Generic    = NSData.FromString(Convert.ToString(setID), NSStringEncoding.UTF8);
            record.Accessible = SecAccessible.Always;
            record.Label      = RecordLabel;
            SecStatusCode code = SecKeyChain.Add(record);

            if (code == SecStatusCode.DuplicateItem)
            {
                code = RemoveID();
                if (code == SecStatusCode.Success)
                {
                    code = SecKeyChain.Add(record);
                }
            }
            return(code);
        }
Esempio n. 42
0
        Account GetAccountFromRecord(SecRecord r)
        {
            var serializedData = NSString.FromData(r.Generic, NSStringEncoding.UTF8);

            return(Account.Deserialize(serializedData));
        }
Esempio n. 43
0
 private string GetStringFromRecord(SecRecord record) => NSString.FromData(record.Generic, NSStringEncoding.UTF8);
Esempio n. 44
0
        public void AddConfig()
        {
            // The password for the VPN connection, add this to Keychain
            var password = new SecRecord(SecKind.GenericPassword)
            {
                Service   = "Password Service",
                ValueData = NSData.FromString("MY_PASSWORD", NSStringEncoding.UTF8),
                Generic   = NSData.FromString("VPNPas", NSStringEncoding.UTF8),
            };

            // The query for the VPN password. Use this to find the password in Keychain
            var queryPassword = new SecRecord(SecKind.GenericPassword)
            {
                Service = "Password Service",
                Generic = NSData.FromString("VPNPas", NSStringEncoding.UTF8),
            };

            // The shared secret for the VPN connection, add this to Keychain
            var secret = new SecRecord(SecKind.GenericPassword)
            {
                Service   = "Secret Service",
                ValueData = NSData.FromString("hide.io", NSStringEncoding.UTF8),
                Generic   = NSData.FromString("secret", NSStringEncoding.UTF8),
            };

            // The query for the VPN shared secret. Use this to find the shared secret in Keychain
            var querySecret = new SecRecord(SecKind.GenericPassword)
            {
                Service = "Secret Service",
                Generic = NSData.FromString("secret", NSStringEncoding.UTF8),
            };

            // First remove old Keychain entries, then add the new ones
            // Just for testing purposes: this is to make sure the keychain entries are correct
            var err = SecKeyChain.Remove(queryPassword);

            Console.WriteLine("Password remove: " + err);

            err = SecKeyChain.Remove(querySecret);
            Console.WriteLine("Secret remove: " + err);

            err = SecKeyChain.Add(password);
            Console.WriteLine("Password add: " + err);

            err = SecKeyChain.Add(secret);
            Console.WriteLine("Secret add: " + err);


            manager.LoadFromPreferences(error => {
                if (error != null)
                {
                    Console.WriteLine("Error loading preferences: ");
                    Console.WriteLine(error);
                }
                else
                {
                    NEVpnProtocol p = null;

                    // IKEv2 Protocol
                    NEVpnProtocolIke2 ike2    = new NEVpnProtocolIke2();
                    ike2.AuthenticationMethod = NEVpnIkeAuthenticationMethod.None;
                    //	ike2.LocalIdentifier = "";
                    ike2.RemoteIdentifier          = "hide.me";
                    ike2.UseExtendedAuthentication = true;
                    ike2.DisconnectOnSleep         = false;

                    // ipSec Protocol
                    NEVpnProtocolIpSec ipSec        = new NEVpnProtocolIpSec();
                    ipSec.AuthenticationMethod      = NEVpnIkeAuthenticationMethod.SharedSecret;
                    ipSec.UseExtendedAuthentication = true;
                    ipSec.DisconnectOnSleep         = false;
                    SecStatusCode res;

                    // Set the shared secret reference for ipSec:
                    // 1) Search for the secret in keychain and retrieve it as a persistent reference
                    // 2) Set the found secret to SharedSecretReference if the secret was found
                    var match = SecKeyChain.QueryAsData(querySecret, true, out res);
                    if (res == SecStatusCode.Success)
                    {
                        Console.WriteLine("Secret found, setting secret...");
                        ipSec.SharedSecretReference = match;
                    }
                    else
                    {
                        Console.WriteLine("Could not set secret:");
                        Console.WriteLine(res);
                    }

                    // Set the protocol to IKEv2 or ipSec
                    //		p = ike2;
                    p = ipSec;

                    // Set Accountname, Servername and description
                    p.Username      = "******";
                    p.ServerAddress = "free-nl.hide.me";
                    manager.LocalizedDescription = "hide.me VPN";

                    // Set the password reference for the protocol:
                    // 1) Search for the password in keychain and retrieve it as a persistent reference
                    // 2) Set the found password to PasswordReference if the secret was found
                    match = SecKeyChain.QueryAsData(queryPassword, true, out res);
                    if (res == SecStatusCode.Success)
                    {
                        Console.WriteLine("Password found, setting password...");
                        p.PasswordReference = match;
                    }
                    else
                    {
                        Console.WriteLine(res);
                    }
                    manager.OnDemandEnabled = false;

                    // Set the managers protocol and save it to the iOS custom VPN preferences
                    manager.ProtocolConfiguration = p;
                    manager.SaveToPreferences(error2 => {
                        if (error2 != null)
                        {
                            Console.WriteLine("Could not save VPN preferences");
                            Console.WriteLine(error2.DebugDescription);
                        }
                    });
                }
            });
        }
Esempio n. 45
0
        public override void StoreKeyValuePairs(KeyPair[] keypairs)
        {
            string         sAccessGroup        = KeyChainAccessGroup;
            List <KeyPair> successfullKeyPairs = new List <KeyPair>();
            List <KeyPair> failedKeyPairs      = new List <KeyPair>();

            foreach (KeyPair kp in keypairs)
            {
                SecRecord srNewEntry = new SecRecord(SecKind.GenericPassword)
                {
                    Account   = kp.Key,
                    Generic   = NSData.FromString(kp.Key),
                    ValueData = NSData.FromString(kp.Value)
                };

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


                if (this.GetPasscodeProtectedKeys().Contains(kp.Key))
                {
                    if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
                    {
                        SystemLogger.Log(SystemLogger.Module.PLATFORM,
                                         "StoreKeyValuePairs - Passcode protection applied to this keychain item (as configured in security-config.xml)");
                        srNewEntry.AccessControl = new SecAccessControl(SecAccessible.WhenPasscodeSetThisDeviceOnly, SecAccessControlCreateFlags.UserPresence);
                    }
                    else
                    {
                        SystemLogger.Log(SystemLogger.Module.PLATFORM,
                                         "StoreKeyValuePairs - Passcode protection is requested for this keychain item, but protection couldn't be applied due to device is iOS<8");
                    }
                }

                SecStatusCode code = SecKeyChain.Add(srNewEntry);
                if (code == SecStatusCode.DuplicateItem)
                {
                    SecRecord srDeleteExistingEntry = new SecRecord(SecKind.GenericPassword)
                    {
                        Account = kp.Key
                    };
                    if (sAccessGroup != null)
                    {
                        srDeleteExistingEntry.AccessGroup = sAccessGroup;
                    }
                    code = SecKeyChain.Remove(srDeleteExistingEntry);
                    if (code == SecStatusCode.Success)
                    {
                        SecKeyChain.Add(srNewEntry);
                    }
                }
                if (code == SecStatusCode.Success)
                {
                    successfullKeyPairs.Add(kp);
                }
                else
                {
                    failedKeyPairs.Add(kp);
                }
            }

            SystemLogger.Log(SystemLogger.Module.PLATFORM, "StoreKeyValuePairs - Success: " + successfullKeyPairs.Count + ", Failed: " + failedKeyPairs.Count);
            UIApplication.SharedApplication.InvokeOnMainThread(delegate {
                IPhoneUtils.GetInstance().FireUnityJavascriptEvent("Appverse.OnKeyValuePairsStoreCompleted", new object[] { successfullKeyPairs, failedKeyPairs });
            });
        }
Esempio n. 46
0
        protected INativeObject GetINativeInstance(Type t)
        {
            var ctor = t.GetConstructor(Type.EmptyTypes);

            if ((ctor != null) && !ctor.IsAbstract)
            {
                return(ctor.Invoke(null) as INativeObject);
            }

            if (!NativeObjectInterfaceType.IsAssignableFrom(t))
            {
                throw new ArgumentException("t");
            }
            switch (t.Name)
            {
            case "CFAllocator":
                return(CFAllocator.SystemDefault);

            case "CFBundle":
                var bundles = CFBundle.GetAll();
                if (bundles.Length > 0)
                {
                    return(bundles [0]);
                }
                else
                {
                    throw new InvalidOperationException(string.Format("Could not create the new instance for type {0}.", t.Name));
                }

            case "CFNotificationCenter":
                return(CFNotificationCenter.Darwin);

            case "CFReadStream":
            case "CFStream":
                CFReadStream  readStream;
                CFWriteStream writeStream;
                CFStream.CreatePairWithSocketToHost("www.google.com", 80, out readStream, out writeStream);
                return(readStream);

            case "CFWriteStream":
                CFStream.CreatePairWithSocketToHost("www.google.com", 80, out readStream, out writeStream);
                return(writeStream);

            case "CFUrl":
                return(CFUrl.FromFile("/etc"));

            case "CFPropertyList":
                return(CFPropertyList.FromData(NSData.FromString("<string>data</string>")).PropertyList);

            case "DispatchData":
                return(DispatchData.FromByteBuffer(new byte [] { 1, 2, 3, 4 }));

            case "AudioFile":
                var path = Path.GetFullPath("1.caf");
                var af   = AudioFile.Open(CFUrl.FromFile(path), AudioFilePermission.Read, AudioFileType.CAF);
                return(af);

            case "CFHTTPMessage":
                return(CFHTTPMessage.CreateEmpty(false));

            case "CFMutableString":
                return(new CFMutableString("xamarin"));

            case "CGBitmapContext":
                byte[] data = new byte [400];
                using (CGColorSpace space = CGColorSpace.CreateDeviceRGB()) {
                    return(new CGBitmapContext(data, 10, 10, 8, 40, space, CGBitmapFlags.PremultipliedLast));
                }

            case "CGContextPDF":
                var filename = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) + "/t.pdf";
                using (var url = new NSUrl(filename))
                    return(new CGContextPDF(url));

            case "CGColorConversionInfo":
                var cci = new GColorConversionInfoTriple()
                {
                    Space     = CGColorSpace.CreateGenericRgb(),
                    Intent    = CGColorRenderingIntent.Default,
                    Transform = CGColorConversionInfoTransformType.ApplySpace
                };
                return(new CGColorConversionInfo((NSDictionary)null, cci, cci, cci));

            case "CGDataConsumer":
                using (NSMutableData destData = new NSMutableData()) {
                    return(new CGDataConsumer(destData));
                }

            case "CGDataProvider":
                filename = "xamarin1.png";
                return(new CGDataProvider(filename));

            case "CGFont":
                return(CGFont.CreateWithFontName("Courier New"));

            case "CGPattern":
                return(new CGPattern(
                           new RectangleF(0, 0, 16, 16),
                           CGAffineTransform.MakeIdentity(),
                           16, 16,
                           CGPatternTiling.NoDistortion,
                           true,
                           (cgc) => {}));

            case "CMBufferQueue":
                return(CMBufferQueue.CreateUnsorted(2));

            case "CTFont":
                CTFontDescriptorAttributes fda = new CTFontDescriptorAttributes()
                {
                    FamilyName = "Courier",
                    StyleName  = "Bold",
                    Size       = 16.0f
                };
                using (var fd = new CTFontDescriptor(fda))
                    return(new CTFont(fd, 10));

            case "CTFontCollection":
                return(new CTFontCollection(new CTFontCollectionOptions()));

            case "CTFontDescriptor":
                fda = new CTFontDescriptorAttributes();
                return(new CTFontDescriptor(fda));

            case "CTTextTab":
                return(new CTTextTab(CTTextAlignment.Left, 2));

            case "CTTypesetter":
                return(new CTTypesetter(new NSAttributedString("Hello, world",
                                                               new CTStringAttributes()
                {
                    ForegroundColorFromContext = true,
                    Font = new CTFont("ArialMT", 24)
                })));

            case "CTFrame":
                var framesetter = new CTFramesetter(new NSAttributedString("Hello, world",
                                                                           new CTStringAttributes()
                {
                    ForegroundColorFromContext = true,
                    Font = new CTFont("ArialMT", 24)
                }));
                var bPath = UIBezierPath.FromRect(new RectangleF(0, 0, 3, 3));
                return(framesetter.GetFrame(new NSRange(0, 0), bPath.CGPath, null));

            case "CTFramesetter":
                return(new CTFramesetter(new NSAttributedString("Hello, world",
                                                                new CTStringAttributes()
                {
                    ForegroundColorFromContext = true,
                    Font = new CTFont("ArialMT", 24)
                })));

            case "CTGlyphInfo":
                return(new CTGlyphInfo("copyright", new CTFont("ArialMY", 24), "Foo"));

            case "CTLine":
                return(new CTLine(new NSAttributedString("Hello, world",
                                                         new CTStringAttributes()
                {
                    ForegroundColorFromContext = true,
                    Font = new CTFont("ArialMT", 24)
                })));

            case "CGImageDestination":
                var storage = new NSMutableData();
                return(CGImageDestination.Create(new CGDataConsumer(storage), "public.png", 1));

            case "CGImageMetadataTag":
                using (NSString name = new NSString("tagName"))
                    using (var value = new NSString("value"))
                        return(new CGImageMetadataTag(CGImageMetadataTagNamespaces.Exif, CGImageMetadataTagPrefixes.Exif, name, CGImageMetadataType.Default, value));

            case "CGImageSource":
                filename = "xamarin1.png";
                return(CGImageSource.FromUrl(NSUrl.FromFilename(filename)));

            case "SecPolicy":
                return(SecPolicy.CreateSslPolicy(false, null));

            case "SecIdentity":
                using (var options = NSDictionary.FromObjectAndKey(new NSString("farscape"), SecImportExport.Passphrase)) {
                    NSDictionary[] array;
                    var            result = SecImportExport.ImportPkcs12(farscape_pfx, options, out array);
                    if (result != SecStatusCode.Success)
                    {
                        throw new InvalidOperationException(string.Format("Could not create the new instance for type {0} due to {1}.", t.Name, result));
                    }
                    return(new SecIdentity(array [0].LowlevelObjectForKey(SecImportExport.Identity.Handle)));
                }

            case "SecTrust":
                X509Certificate x = new X509Certificate(mail_google_com);
                using (var policy = SecPolicy.CreateSslPolicy(true, "mail.google.com"))
                    return(new SecTrust(x, policy));

            case "SslContext":
                return(new SslContext(SslProtocolSide.Client, SslConnectionType.Stream));

            case "UIFontFeature":
                return(new UIFontFeature(CTFontFeatureNumberSpacing.Selector.ProportionalNumbers));

            case "NetworkReachability":
                return(new NetworkReachability(IPAddress.Loopback, null));

            case "VTCompressionSession":
            case "VTSession":
                return(VTCompressionSession.Create(1024, 768, CMVideoCodecType.H264, (sourceFrame, status, flags, buffer) => { }, null, (CVPixelBufferAttributes)null));

            case "VTFrameSilo":
                return(VTFrameSilo.Create());

            case "VTMultiPassStorage":
                return(VTMultiPassStorage.Create());

            case "CFString":
                return(new CFString("test"));

            case "DispatchBlock":
                return(new DispatchBlock(() => { }));

            case "DispatchQueue":
                return(new DispatchQueue("com.example.subsystem.taskXYZ"));

            case "DispatchGroup":
                return(DispatchGroup.Create());

            case "CGColorSpace":
                return(CGColorSpace.CreateDeviceCmyk());

            case "CGGradient":
                CGColor[] cArray = { UIColor.Black.CGColor, UIColor.Clear.CGColor, UIColor.Blue.CGColor };
                return(new CGGradient(null, cArray));

            case "CGImage":
                filename = "xamarin1.png";
                using (var dp = new CGDataProvider(filename))
                    return(CGImage.FromPNG(dp, null, false, CGColorRenderingIntent.Default));

            case "CGColor":
                return(UIColor.Black.CGColor);

            case "CMClock":
                return(CMClock.HostTimeClock);

            case "CMTimebase":
                return(new CMTimebase(CMClock.HostTimeClock));

            case "CVPixelBufferPool":
                return(new CVPixelBufferPool(
                           new CVPixelBufferPoolSettings(),
                           new CVPixelBufferAttributes(CVPixelFormatType.CV24RGB, 100, 50)
                           ));

            case "SecCertificate":
                using (var cdata = NSData.FromArray(mail_google_com))
                    return(new SecCertificate(cdata));

            case "SecCertificate2":
                using (var cdata = NSData.FromArray(mail_google_com))
                    return(new SecCertificate2(new SecCertificate(cdata)));

            case "SecTrust2":
                X509Certificate x2 = new X509Certificate(mail_google_com);
                using (var policy = SecPolicy.CreateSslPolicy(true, "mail.google.com"))
                    return(new SecTrust2(new SecTrust(x2, policy)));

            case "SecIdentity2":
                using (var options = NSDictionary.FromObjectAndKey(new NSString("farscape"), SecImportExport.Passphrase)) {
                    NSDictionary[] array;
                    var            result = SecImportExport.ImportPkcs12(farscape_pfx, options, out array);
                    if (result != SecStatusCode.Success)
                    {
                        throw new InvalidOperationException(string.Format("Could not create the new instance for type {0} due to {1}.", t.Name, result));
                    }
                    return(new SecIdentity2(new SecIdentity(array [0].LowlevelObjectForKey(SecImportExport.Identity.Handle))));
                }

            case "SecKey":
                SecKey private_key;
                SecKey public_key;
                using (var record = new SecRecord(SecKind.Key)) {
                    record.KeyType       = SecKeyType.RSA;
                    record.KeySizeInBits = 512;                     // it's not a performance test :)
                    SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key);
                    return(private_key);
                }

            case "SecAccessControl":
                return(new SecAccessControl(SecAccessible.WhenPasscodeSetThisDeviceOnly));

            default:
                throw new InvalidOperationException(string.Format("Could not create the new instance for type {0}.", t.Name));
            }
        }
Esempio n. 47
0
 static SecRecord SecKeychainFindInternetPassword(Uri uri, out SecRecord searchRecord)
 {
     return(SecKeychainFindInternetPassword(uri, GetSecProtocolType(uri.Scheme), out searchRecord));
 }
 string GetAccountFromRecord(SecRecord r)
 {
     return(NSString.FromData(r.Generic, NSStringEncoding.UTF8));
 }
Esempio n. 49
0
        public override Task SaveAsync(Account account, string serviceId)
        {
            try
            {
                SecStatusCode statusCode        = SecStatusCode.Success;
                string        serializedAccount = account.Serialize();
                NSData        data = NSData.FromString(serializedAccount, NSStringEncoding.UTF8);

                //
                // Remove any existing record
                //
                var existing = FindAccount(account.Username, serviceId);

                if (existing != null)
                {
                    var query = new SecRecord(SecKind.GenericPassword);
                    query.Service = serviceId;
                    query.Account = account.Username;

                    statusCode = SecKeyChain.Remove(query);
                    if (statusCode != SecStatusCode.Success)
                    {
                        throw new AuthException("Could not remove account from KeyChain: " + statusCode);
                    }
                }

                //
                // Add this record
                //
                SecRecord record = new SecRecord(SecKind.GenericPassword)
                {
                    Service = serviceId,
                    Account = account.Username,
                    //------------------------------------------------------
                    // mc++ mc#
                    // Mark Taparauskas suggetsion:
                    //      .Generic is not encrypted
                    #if TEST_MARK_T
                    Generic = data,
                    #else
                    ValueData = data,
                    #endif
                };
                //------------------------------------------------------
                record.Accessible =
                    //SecAccessible.WhenUnlocked
                    // Pull Request - manually added/fixed
                    //      Changed SecAccessible.WhenUnLocked to AfterFirstUnLocked #80
                    //      https://github.com/xamarin/Xamarin.Auth.Compat/pull/80
                    SecAccessible.AfterFirstUnlock             ////THIS IS THE FIX
                    // ???
                    // SecAccessible.AlwaysThisDeviceOnly
                ;

                statusCode = SecKeyChain.Add(record);

                if (statusCode != SecStatusCode.Success)
                {
                    StringBuilder sb = new StringBuilder("error = ");
                    sb.AppendLine("Could not save account to KeyChain: " + statusCode);
                    sb.AppendLine("Add Empty Entitlements.plist ");
                    sb.AppendLine(" File /+ New file /+ iOS /+ Entitlements.plist");

                    /*
                     *  Error: Could not save account to KeyChain -- iOS 10 #128
                     *  https://github.com/xamarin/Xamarin.Auth.Compat/issues/128
                     *  https://bugzilla.xamarin.com/show_bug.cgi?id=43514
                     *
                     *  sb.AppendLine("");
                     */
                    if ((int)statusCode == -34018)
                    {
                        // http://stackoverflow.com/questions/38456471/secitemadd-always-returns-error-34018-in-xcode-8-in-ios-10-simulator
                        // NOTE: code was not copy/pasted! That was iOS sample

                        sb.AppendLine("SecKeyChain.Add returned : " + statusCode);
                        sb.AppendLine("1. Add Keychain Access Groups to the Entitlements file.");
                        sb.AppendLine("2. Turn on the Keychain Sharing switch in the Capabilities section in the app.");
                    }
                    string msg = sb.ToString();

                    throw new AuthException(msg);
                }
            }
            catch (System.Exception exc)
            {
                string msg = String.Format("SaveAsync error = {0}", exc.Message);
                Debug.WriteLine(msg);
                throw new Xamarin.Auth.Compat.AccountStoreException(msg);
            }

            return(Task.FromResult(true));
        }
Esempio n. 50
0
        public override Task <List <Account> > FindAccountsForServiceAsync(string serviceId)
        {
            SecRecord[] records = null;

            try
            {
                var query = new SecRecord(SecKind.GenericPassword);
                query.Service = serviceId;

                // Workaround for https://bugzilla.xamarin.com/show_bug.cgi?id=29977
                var queryDict = SecRecord_queryDictGetter.Value.Invoke(query, new object[] { }) as NSMutableDictionary;
                queryDict.LowlevelSetObject(CFBoolean_TrueHandle.Value, Security_ReturnData.Value);

                SecStatusCode result;
                records = SecKeyChain.QueryAsRecord(query, 1000, out result);
            }
            catch (System.Exception exc)
            {
                string msg = String.Format("Search/Find FindAccountsForServiceAsync {0}", exc.Message);
                throw new Xamarin.Auth.Compat.AccountStoreException(msg, exc);
            }

            IEnumerable <Account> accounts_found       = null;
            IEnumerable <Account> ienumerable_accounts = null;

            if (records != null)
            {
                /*
                 * moljac note:
                 * ienumerable_accounts
                 *  {
                 *      System.Linq.Enumerable.WhereSelectArrayIterator
                 *                              <
                 *                                  MonoTouch.Security.SecRecord,
                 *                                  Xamarin.Auth.Compat.Account
                 *                              >
                 *  }
                 *  {
                 *      System.Linq.Enumerable.WhereSelectArrayIterator
                 *                              <
                 *                                  Security.SecRecord,
                 *                                  Xamarin.Auth.Compat.Account
                 *                              >
                 *  }
                 */
                ienumerable_accounts = records.Select(GetAccountFromRecord);

                /*
                 *  must check for empty IEnumerable
                 *  IEnumerable ToList()
                 *  Value cannot be null.
                 *  Parameter name: data
                 */
                try
                {
                    /*
                     *  Classic
                     *  accessing throws
                     *  > ienumerable_accounts.Count()
                     *  System.ArgumentNullException: Value cannot be null.
                     *  Parameter name: data
                     *  > ienumerable_accounts.LongCount()
                     *  System.ArgumentNullException: Value cannot be null.
                     *  Parameter name: data
                     */
                    if (ienumerable_accounts.Count() > 0 && ienumerable_accounts.LongCount() > 0)
                    {
                        /*
                         *  Unified enters
                         *  method call ToList() throws
                         *
                         *  > ienumerable_accounts.Count()
                         *  System.ArgumentNullException: Value cannot be null.
                         *  Parameter name: data
                         *  > ienumerable_accounts.LongCount()
                         *  System.ArgumentNullException: Value cannot be null.
                         *  Parameter name: data
                         *  > ienumerable_accounts.ToList()
                         *  System.ArgumentNullException: Value cannot be null.
                         *  Parameter name: data
                         */
                        accounts_found = ienumerable_accounts.ToList();
                    }
                    else
                    {
                        accounts_found = new List <Account>();
                    }
                }
                catch (System.Exception exc)
                {
                    string msg = exc.Message;
                    Debug.WriteLine("IEnumerable access excption = " + msg);
                    // throw new Xamarin.Auth.Compat.AccountStoreException("IEnumerable access excption = " + msg);
                }
            }
            else
            {
                accounts_found = new List <Account>();
            }

            List <Account> retval = new List <Account>(accounts_found);

            return(Task.FromResult(retval));
        }
Esempio n. 51
0
        static SecRecord SecKeychainFindInternetPassword(Uri uri, SecProtocol protocol, out SecRecord searchRecord)
        {
            // Look for an internet password for the given protocol and auth mechanism
            searchRecord = uri.ToSecRecord();
            if (protocol != SecProtocol.Invalid)
            {
                searchRecord.Protocol = protocol;
            }

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

            if (code == SecStatusCode.ItemNotFound)
            {
                // Fall back to looking for a password without use SecProtocol && SecAuthenticationType
                searchRecord.Protocol           = SecProtocol.Http;       // Http is the default used by SecKeyChain internally
                searchRecord.AuthenticationType = SecAuthenticationType.Default;

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

            if (code != SecStatusCode.Success)
            {
                return(null);
            }

            return(data);
        }
        private byte[] GenerateKeyPairCore(string name)
        {
            using (var parameters = new SecRecord(SecKind.Key))
            {
                parameters.AccessControl = new SecAccessControl(SecAccessible.WhenPasscodeSetThisDeviceOnly, SecAccessControlCreateFlags.TouchIDCurrentSet | SecAccessControlCreateFlags.PrivateKeyUsage);
                parameters.KeyType       = SecKeyType.EC;
                parameters.KeySizeInBits = 256;
                parameters.TokenID       = SecTokenID.SecureEnclave;

                var privateKeyParameters = new NSMutableDictionary();
                privateKeyParameters.Add(kSecAttrApplicationTag, new NSString($"{name}_priv"));
                privateKeyParameters.Add(kSecAttrIsPermanent, NSNumber.FromBoolean(true));

                var publicKeyParameters = new NSMutableDictionary();
                publicKeyParameters.Add(kSecAttrApplicationTag, new NSString($"{name}_pub"));
                publicKeyParameters.Add(kSecAttrIsPermanent, NSNumber.FromBoolean(false));

                var mutableDictionary = (NSMutableDictionary)parameters.ToDictionary();
                mutableDictionary.Add(kSecPrivateKeyAttrs, new NSDictionary(privateKeyParameters));
                mutableDictionary.Add(kSecPublicKeyAttrs, new NSDictionary(publicKeyParameters));

                var result = SecKey.GenerateKeyPair((NSDictionary)mutableDictionary, out var publicKey, out var privateKey);

                if (result == SecStatusCode.Success)
                {
                    privateKey.Dispose();

                    using (var record = new SecRecord(SecKind.Key))
                    {
                        record.KeyClass    = SecKeyClass.Public;
                        record.KeyType     = SecKeyType.EC;
                        record.IsPermanent = false;
                        record.Label       = "Public Key";
                        record.SetValueRef(publicKey);

                        var dict = (NSMutableDictionary)record.ToDictionary();
                        dict.Add(kSecReturnData, NSNumber.FromBoolean(true));

                        var status = SecItemAdd(dict.Handle, out var publicKeyDataPtr);

                        publicKey.Dispose();

                        if (status == SecStatusCode.Success)
                        {
                            var publicKeyData = ObjCRuntime.Runtime.GetINativeObject <NSData>(publicKeyDataPtr, true);

                            if (publicKeyData != null)
                            {
                                // Apple's SecurityFramework uses raw keys which need to be wrapped in proper ASN.1 for outside consumption
                                // See : https://forums.developer.apple.com/thread/8030

                                var header = NSData.FromArray(new byte[] { 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01,
                                                                           0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00 });

                                var buffer = new NSMutableData(header.Length + publicKeyData.Length);
                                buffer.AppendData(header);
                                buffer.AppendData(publicKeyData);

                                return(buffer.ToArray());
                            }
                        }

                        return(null);
                    }
                }
                else
                {
                    throw new SecurityException(result);
                }
            }
        }
Esempio n. 53
0
        public void RoundtripRSAMinPKCS1()
        {
            NSError error;
            SecKey  private_key;
            SecKey  public_key;
            var     label = $"KeyTest.RoundtripRSAMinPKCS1-{CFBundle.GetMain ().Identifier}-{GetType ().FullName}-{Process.GetCurrentProcess ().Id}";

            try {
                using (var record = new SecRecord(SecKind.Key)) {
                    record.KeyType       = SecKeyType.RSA;
                    record.KeySizeInBits = MinRsaKeySize;                     // it's not a performance test :)
                    record.Label         = label;

                    Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                    byte [] plain = new byte [20] {
                        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                    };
                    byte [] cipher;
                    if (TestRuntime.CheckXcodeVersion(8, 0))
                    {
                        Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "public/IsAlgorithmSupported/Encrypt");

#if MONOMAC
                        Assert.That(public_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), Is.EqualTo(TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 13)), "public/IsAlgorithmSupported/Decrypt");

                        using (var pub = public_key.GetPublicKey()) {
                            // macOS behaviour is not consistent - but the test main goal is to check we get a key
                            Assert.That(pub.Handle, Is.Not.EqualTo(IntPtr.Zero), "public/GetPublicKey");
                        }
#else
                        Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "public/IsAlgorithmSupported/Decrypt");

                        using (var pub = public_key.GetPublicKey())
                        {
                            // a new native instance of the key is returned (so having a new managed SecKey is fine)
                            Assert.False(pub.Handle == public_key.Handle, "public/GetPublicKey");
                        }
#endif

                        using (var attrs = public_key.GetAttributes()) {
                            Assert.That(attrs.Count, Is.GreaterThan((nuint)0), "public/GetAttributes");
                        }
                        using (var data = public_key.GetExternalRepresentation(out error)) {
                            Assert.Null(error, "public/error-1");
                            Assert.NotNull(data, "public/GetExternalRepresentation");

                            using (var key = SecKey.Create(data, SecKeyType.RSA, SecKeyClass.Public, MinRsaKeySize, null, out error)) {
                                Assert.Null(error, "public/Create/error-1");
                            }
                        }
                    }
                    Assert.That(public_key.Encrypt(SecPadding.PKCS1, plain, out cipher), Is.EqualTo(SecStatusCode.Success), "Encrypt");

                    byte[] result;
                    if (TestRuntime.CheckXcodeVersion(8, 0))
                    {
                        Assert.False(private_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "private/IsAlgorithmSupported/Encrypt");
                        Assert.True(private_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "private/IsAlgorithmSupported/Decrypt");

                        using (var pub2 = private_key.GetPublicKey()) {
                            // a new native instance of the key is returned (so having a new managed SecKey is fine)
                            Assert.That(pub2.Handle, Is.Not.EqualTo(public_key.Handle), "private/GetPublicKey");
                        }

                        using (var attrs = private_key.GetAttributes()) {
                            Assert.That(attrs.Count, Is.GreaterThan((nuint)0), "private/GetAttributes");
                        }
                        using (var data2 = private_key.GetExternalRepresentation(out error)) {
                            Assert.Null(error, "private/error-1");
                            Assert.NotNull(data2, "private/GetExternalRepresentation");

                            using (var key = SecKey.Create(data2, SecKeyType.RSA, SecKeyClass.Private, MinRsaKeySize, null, out error)) {
                                Assert.Null(error, "private/Create/error-1");
                            }
                        }
                    }
                    public_key.Dispose();
                    var expectedResult = SecStatusCode.Success;
#if __MACOS__
                    if (!TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 8))
                    {
                        expectedResult = SecStatusCode.InvalidData;
                    }
#endif
                    Assert.That(private_key.Decrypt(SecPadding.PKCS1, cipher, out result), Is.EqualTo(expectedResult), "Decrypt");
                    if (expectedResult != SecStatusCode.InvalidData)
                    {
                        Assert.That(plain, Is.EqualTo(result), "match");
                    }
                    private_key.Dispose();
                }
            } finally {
                // Clean up after us
                DeleteKeysWithLabel(label);
            }
        }
 public void Write <T>(SecRecord record, T value)
 {
     record.ValueData = NSData.FromString(JsonConvert.SerializeObject(value));
 }
 public T Read <T>(SecRecord record)
 {
     return(JsonConvert.DeserializeObject <T>(record.ValueData.ToString()));
 }
        private bool IsExists(SecRecord record)
        {
            var data = SecKeyChain.QueryAsData(record, false, out var status);

            return(status == SecStatusCode.Success && data.Length > 0);
        }
Esempio n. 57
0
        private NativeCredential GetCredentialFromRecord(SecRecord record)
        {
            var serializedNativeCredential = NSString.FromData(record.Generic, NSStringEncoding.UTF8);

            return(NativeCredential.Deserialize(serializedNativeCredential));
        }
Esempio n. 58
0
        public void RoundtripRSA512PKCS1()
        {
            NSError error;
            SecKey  private_key;
            SecKey  public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.RSA;
                record.KeySizeInBits = 512;                 // it's not a performance test :)

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                byte [] plain = new byte [20] {
                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                };
                byte [] cipher;
                if (TestRuntime.CheckXcodeVersion(8, 0))
                {
                    Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "public/IsAlgorithmSupported/Encrypt");
                    // I would have expect false
                    Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "public/IsAlgorithmSupported/Decrypt");

                    using (var pub = public_key.GetPublicKey()) {
                        // a new native instance of the key is returned (so having a new managed SecKey is fine)
                        Assert.That(pub.Handle, Is.Not.EqualTo(public_key.Handle), "public/GetPublicKey");
                    }
                    using (var attrs = public_key.GetAttributes()) {
                        Assert.That(attrs.Count, Is.GreaterThan(0), "public/GetAttributes");
                    }
                    using (var data = public_key.GetExternalRepresentation(out error)) {
                        Assert.Null(error, "public/error-1");
                        Assert.NotNull(data, "public/GetExternalRepresentation");

                        using (var key = SecKey.Create(data, SecKeyType.RSA, SecKeyClass.Public, 512, null, out error)) {
                            Assert.Null(error, "public/Create/error-1");
                        }
                    }
                }
                Assert.That(public_key.Encrypt(SecPadding.PKCS1, plain, out cipher), Is.EqualTo(SecStatusCode.Success), "Encrypt");

                byte[] result;
                if (TestRuntime.CheckXcodeVersion(8, 0))
                {
                    Assert.False(private_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "private/IsAlgorithmSupported/Encrypt");
                    Assert.True(private_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "private/IsAlgorithmSupported/Decrypt");

                    using (var pub2 = private_key.GetPublicKey()) {
                        // a new native instance of the key is returned (so having a new managed SecKey is fine)
                        Assert.That(pub2.Handle, Is.Not.EqualTo(public_key.Handle), "private/GetPublicKey");
                    }
                    using (var attrs = private_key.GetAttributes()) {
                        Assert.That(attrs.Count, Is.GreaterThan(0), "private/GetAttributes");
                    }
                    using (var data2 = private_key.GetExternalRepresentation(out error)) {
                        Assert.Null(error, "private/error-1");
                        Assert.NotNull(data2, "private/GetExternalRepresentation");

                        using (var key = SecKey.Create(data2, SecKeyType.RSA, SecKeyClass.Private, 512, null, out error)) {
                            Assert.Null(error, "private/Create/error-1");
                        }
                    }
                }
                public_key.Dispose();
                Assert.That(private_key.Decrypt(SecPadding.PKCS1, cipher, out result), Is.EqualTo(SecStatusCode.Success), "Decrypt");
                Assert.That(plain, Is.EqualTo(result), "match");
                private_key.Dispose();
            }
        }
Esempio n. 59
0
 void RemoveRecord(SecRecord record)
 {
     SecKeyChain.Remove(record);
 }