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 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); } } }