internal object AccessValue(EncryptedInstance instance, PropertyInfo property, byte[] bytes)
        {
            if (bytes != null && bytes.Length > 0)
            {
                var keyDescriptor = GetEncryptionKey(instance, property);
                if (keyDescriptor != null && !keyDescriptor.Locked)
                {
                    byte[] decrypted;
                    try
                    {
                        decrypted = keyDescriptor.Decrypt(property, bytes);
                    }
                    catch (Exception ex)
                    {
                        if (ThrowExceptionOnAccessorFailure)
                        {
                            throw new UnauthorizedAccessException("Cannot read value from encrypted memory.", ex);
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    return(ProxyDeserializeFunction(property, decrypted));
                }
                else if (ThrowExceptionOnAccessorFailure)
                {
                    throw new UnauthorizedAccessException("No key data loaded for required name '" + GetEncryptionKeyName(property) + "' or key is locked.");
                }
            }

            return(null);
        }
        internal bool IsPeriodicallyAccessibleKey(EncryptedInstance instance, PropertyInfo property)
        {
            var keyDescriptor = GetEncryptionKey(instance, property);

            if (keyDescriptor == null)
            {
                throw new UnauthorizedAccessException("Key '" + GetEncryptionKeyName(property) + "' not loaded");
            }
            return(keyDescriptor.KeyData.IsPeriodicallyAccessibleKey(property));
        }
        private KeyDescriptor GetEncryptionKey(EncryptedInstance instance, PropertyInfo propertyInfo)
        {
            var keyAlias       = GetEncryptionKeyName(propertyInfo);
            var unifiedKeyring = instance.Reference.Target.GetReadOnlyUnifiedKeyring();

            if (keyAlias != null && unifiedKeyring.HasKey(keyAlias))
            {
                return(unifiedKeyring.Keys.FirstOrDefault(k => k.Name == keyAlias));
            }
            return(null);
        }
        internal byte[] MutateValue(EncryptedInstance instance, PropertyInfo property, object obj)
        {
            if (ProxySerializeFunction == null)
            {
                throw new Exception("ProxySerializeFunction not bound.");
            }

            if (obj != null)
            {
                var keyDescriptor = GetEncryptionKey(instance, property);
                if (keyDescriptor != null && !keyDescriptor.Locked)
                {
                    var serialized = ProxySerializeFunction(property, obj);
                    try
                    {
                        return(keyDescriptor.Encrypt(property, serialized));
                    }
                    catch (Exception ex)
                    {
                        if (ThrowExceptionOnMutatorFailure)
                        {
                            throw new UnauthorizedAccessException("Cannot set value to encrypted memory.", ex);
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }
                else if (ThrowExceptionOnMutatorFailure)
                {
                    throw new UnauthorizedAccessException("No key data loaded for required name '" + GetEncryptionKeyName(property) + "' or key is locked.");
                }
            }

            return(null);
        }