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); } } }
// 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; }
// 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; }
/// <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; }
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); }
public void Remove(string key) { var existingRecord = new SecRecord(SecKind.GenericPassword) { Account = key, Label = key, Service = NSBundle.MainBundle.BundleIdentifier }; SecKeyChain.Remove(existingRecord); }
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; }
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") }; }
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 ""; }
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 ""; }
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; }
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(); }); }
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); }
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; }
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; } }
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); } } }
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"); } }
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(); } }
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 }"); } }
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); }
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)); }
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); }
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"); }
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? } }
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); }
Account GetAccountFromRecord(SecRecord r) { var serializedData = NSString.FromData(r.Generic, NSStringEncoding.UTF8); return(Account.Deserialize(serializedData)); }
private string GetStringFromRecord(SecRecord record) => NSString.FromData(record.Generic, NSStringEncoding.UTF8);
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); } }); } }); }
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 }); }); }
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)); } }
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)); }
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)); }
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)); }
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); } } }
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); }
private NativeCredential GetCredentialFromRecord(SecRecord record) { var serializedNativeCredential = NSString.FromData(record.Generic, NSStringEncoding.UTF8); return(NativeCredential.Deserialize(serializedNativeCredential)); }
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(); } }
void RemoveRecord(SecRecord record) { SecKeyChain.Remove(record); }