public bool TryGetSecret(KeychainSecretName name, out KeychainSecret secret) { using (var serviceName = new KeychainMemory(name.Service)) using (var accountName = new KeychainMemory(name.Account)) { var itemRef = IntPtr.Zero; var result = SecKeychainFindGenericPassword( IntPtr.Zero, serviceName.Length, serviceName.Buffer, accountName.Length, accountName.Buffer, out var secretValueLength, out var secretValuePtr, ref itemRef); if (result == SecStatus.ItemNotFound) { secret = null; return(false); } if (result != SecStatus.Success) { throw new AppleSecurityException( nameof(SecKeychainFindGenericPassword), result); } try { var passwordData = new byte [secretValueLength]; Marshal.Copy(secretValuePtr, passwordData, 0, (int)secretValueLength); secret = KeychainSecret.Create(name, passwordData); return(true); } finally { SecKeychainItemFreeContent(IntPtr.Zero, secretValuePtr); } } }
public void RoundtripString(string key, string value) { KeychainSecretName name = (serviceName, key); keychain.StoreSecret(KeychainSecret.Create(name, value)); Assert.True(keychain.TryGetSecret(name, out var secret)); Assert.Equal(value, secret.GetUtf8StringValue()); }
public void StoreSecret() { KeychainSecretName name = (serviceName, "dont-update-me"); keychain.StoreSecret(KeychainSecret.Create(name, "initial value")); Assert.Throws <KeychainItemAlreadyExistsException> (() => keychain.StoreSecret( KeychainSecret.Create(name, "new value"), updateExisting: false)); }
public void RoundtripBytes() { var random = new Random(); var value = new byte [1024 * 1024]; random.NextBytes(value); KeychainSecretName name = (serviceName, "randomblob"); keychain.StoreSecret(KeychainSecret.Create(name, value)); Assert.True(keychain.TryGetSecret(name, out var secret)); Assert.Equal(value, secret.Value); }
public void StoreSecret(KeychainSecret secret, bool updateExisting = true) { var secretPath = GetSecretPath(secret.Name); if (!updateExisting && File.Exists(secretPath)) { throw new KeychainItemAlreadyExistsException( $"'{secret.Name}' already exists"); } Directory.CreateDirectory(Path.GetDirectoryName(secretPath)); File.WriteAllBytes(secretPath, Protect((byte [])secret.Value)); }
public bool TryGetSecret(KeychainSecretName name, out KeychainSecret secret) { var secretPath = GetSecretPath(name); if (!File.Exists(secretPath)) { secret = null; return(false); } secret = KeychainSecret.Create( name, Unprotect(File.ReadAllBytes(secretPath))); return(true); }
static void Main(string [] args) { var processPath = Process .GetCurrentProcess() .MainModule .FileName; var targetFramework = typeof(Program) .Assembly.GetCustomAttribute <TargetFrameworkAttribute> () .FrameworkName; Console.WriteLine(" This process path: {0}", processPath); Console.WriteLine(" Target framework: {0}", targetFramework); var secretName = ("dnc-apple-security-regression", $"secret-{args [0]}"); Keychain.StoreSecret( KeychainSecret.Create( secretName, "super secret value")); try { if (Keychain.TryGetSecret(secretName, out var secret)) { Console.WriteLine(" Read secret: {0} = {1}", secretName, secret.GetUtf8StringValue()); } else { Console.WriteLine(" Secret does not exist: {0}", secretName); } } catch (Exception e) { Console.WriteLine(" Exception reading secret:"); foreach (var line in e.ToString().Split("\n")) { Console.WriteLine($" {line}"); } } }
public void StoreSecret(KeychainSecret secret, bool updateExisting = true) { using (var serviceName = new KeychainMemory(secret.Name.Service)) using (var accountName = new KeychainMemory(secret.Name.Account)) using (var secretValue = new KeychainMemory((byte[])secret.Value)) { var itemRef = IntPtr.Zero; var result = SecKeychainAddGenericPassword( IntPtr.Zero, serviceName.Length, serviceName.Buffer, accountName.Length, accountName.Buffer, secretValue.Length, secretValue.Buffer, ref itemRef); if (result == SecStatus.DuplicateItem) { if (!updateExisting) { throw new KeychainItemAlreadyExistsException( $"'{secret.Name}' already exists", new AppleSecurityException( nameof(SecKeychainAddGenericPassword), result)); } result = SecKeychainFindGenericPassword( IntPtr.Zero, serviceName.Length, serviceName.Buffer, accountName.Length, accountName.Buffer, IntPtr.Zero, IntPtr.Zero, ref itemRef); if (result != SecStatus.Success) { throw new AppleSecurityException( nameof(SecKeychainFindGenericPassword), result); } result = SecKeychainItemModifyContent( itemRef, IntPtr.Zero, secretValue.Length, secretValue.Buffer); if (result != SecStatus.Success) { throw new AppleSecurityException( nameof(SecKeychainItemModifyContent), result); } return; } if (result != SecStatus.Success) { throw new AppleSecurityException( nameof(SecKeychainAddGenericPassword), result); } } }
public void StoreSecret(KeychainSecret secret, bool updateExisting = true) => keychain.StoreSecret(secret, updateExisting);
public bool TryGetSecret(KeychainSecretName name, out KeychainSecret secret) => keychain.TryGetSecret(name, out secret);