/// <inheritdoc />
        public void StoreElement(XElement element, string friendlyName)
        {
            using (var scope = _services.CreateScope())
            {
                var context             = scope.ServiceProvider.GetRequiredService <TContext>();
                IHostingEnvironment env = scope.ServiceProvider.GetRequiredService <IHostingEnvironment>();
                if (env == null)
                {
                    throw new ArgumentNullException(nameof(IHostingEnvironment));
                }

                if (!Enum.TryParse <EnvEnum>(env.EnvironmentName, true, out var env_enum))
                {
                    throw new NotSupportedException("bad env parsing");
                }

                var newKey = new DataProtectionKey()
                {
                    FriendlyName = $"{env.EnvironmentName}_{friendlyName}",
                    Xml          = element.ToString(SaveOptions.DisableFormatting),
                    // Environment = env_enum,
                };

                context.DataProtectionKeys.Add(newKey);
                _logger.LogSavingKeyToDbContext(friendlyName, typeof(TContext).Name);
                context.SaveChanges();
            }
        }
示例#2
0
        public async Task ChangeProtectionPasswordAsync(string oldPassword, string newPassword)
        {
            try
            {
                if (_protectionBusy)
                {
                    throw new Exception("Data protection is busy.");
                }
                _protectionBusy = true;

                if (!_protectionActivated)
                {
                    throw new Exception("Data protection is not activated");
                }

                var oldDataProtectionEntity = await ReadDataProtectionEntity();

                if (oldDataProtectionEntity == null)
                {
                    throw new Exception("Data protection parameters not found.");
                }

                var oldKey = new DataProtectionKey(oldDataProtectionEntity.Id, oldDataProtectionEntity.Params);

                if (!oldKey.ValidatePassword(oldPassword))
                {
                    throw new Exception("Incorrect old password");
                }

                using (TransactionScope transactionScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    // Creating the key for the new password
                    var prms = DataProtectionKey.CreateParams(newPassword);
                    var newDataProtectionEntity = await SaveDataProtectionEntity(prms);

                    var newKey = new DataProtectionKey(newDataProtectionEntity.Id, newDataProtectionEntity.Params);
                    newKey.ValidatePassword(newPassword);

                    await ReencryptDatabase(oldKey, newKey);

                    // Delete old key
                    await DeleteDataProtectionEntity(oldKey.KeyId);

                    // Set new key as a current key
                    _key = newKey;
                    transactionScope.Complete();
                }

                // Set activated if detected the not finished password change operation.
                _protectionActivated = true;
            }
            finally
            {
                _protectionBusy = false;
            }
        }
示例#3
0
        public async Task DisableProtectionAsync(string password)
        {
            try
            {
                if (_protectionBusy)
                {
                    throw new Exception("Data protection is busy.");
                }
                _protectionBusy = true;

                if (!_protectionEnabled)
                {
                    throw new Exception("Data protection is not enabled.");
                }

                if (!_protectionActivated)
                {
                    throw new Exception("Data protection is not activated.");
                }


                var dataProtectionEntity = await ReadDataProtectionEntity();

                if (dataProtectionEntity == null)
                {
                    throw new Exception("Data protection parameters not found.");
                }

                var key = new DataProtectionKey(dataProtectionEntity.Id, dataProtectionEntity.Params);

                if (!key.ValidatePassword(password))
                {
                    throw new Exception("Incorrect password");
                }

                using (TransactionScope transactionScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    await DeleteDataProtectionEntity(key.KeyId);
                    await DecryptDatabase(key);

                    transactionScope.Complete();
                }

                _key = null;
                _protectionActivated = false;
                _protectionEnabled   = false;
            }
            finally
            {
                _protectionBusy = false;
            }
        }
示例#4
0
    /// <inheritdoc />
    public void StoreElement(XElement element, string friendlyName)
    {
        using (var scope = _services.CreateScope())
        {
            var context = scope.ServiceProvider.GetRequiredService <TContext>();
            var newKey  = new DataProtectionKey()
            {
                FriendlyName = friendlyName,
                Xml          = element.ToString(SaveOptions.DisableFormatting)
            };

            context.DataProtectionKeys.Add(newKey);
            _logger.LogSavingKeyToDbContext(friendlyName, typeof(TContext).Name);
            context.SaveChanges();
        }
    }
示例#5
0
        public void StoreElement(XElement element, string friendlyName)
        {
            string serialisedKey = element.ToString();
            string encryptedKey  = Encryption.EncryptData(serialisedKey);

            var dataProtectionKey = new DataProtectionKey
            {
                FriendlyName = friendlyName,
                Xml          = encryptedKey
            };

            IDataRepository dataRepository = Global.ContainerIoC.Resolve <IDataRepository>();

            dataRepository.Insert(dataProtectionKey);
            dataRepository.SaveChanges();
        }
        /// <summary>
        /// If a key is already in the database, then update it; else, add it.
        /// </summary>
        /// <param name="element"></param>
        /// <param name="friendlyName"></param>
        public void StoreElement(XElement element, string friendlyName)
        {
            using (var context = _contextFactory())
            {
                var entity = context.DataProtectionKeys.Find(friendlyName);
                if (entity is null)
                {
                    entity = new DataProtectionKey
                    {
                        FriendlyName = friendlyName,
                    };
                    context.DataProtectionKeys.Add(entity);
                }

                entity.XmlData = element.ToString(SaveOptions.DisableFormatting);
                context.SaveChanges();
            }
        }
示例#7
0
        public void should_store_key()
        {
            var dataProtectionKey = new DataProtectionKey
            {
                FriendlyName = "Key1",
                Xml          = "NotReallyXML"
            };

            _context = new KeyStorageContext(_builder.Options);
            _context.DataProtectionKeys.Add(dataProtectionKey);
            _context.SaveChanges();
            _context.DataProtectionKeys.Count().ShouldEqual(1);

            var updatedEntity = _context.DataProtectionKeys.Find(dataProtectionKey.Id);

            updatedEntity.FriendlyName.ShouldEqual(dataProtectionKey.FriendlyName);
            updatedEntity.Id.ShouldEqual(1);
            updatedEntity.Xml.ShouldEqual(dataProtectionKey.Xml);
        }
示例#8
0
        public void StoreElement_PersistsData()
        {
            var element      = XElement.Parse("<Element1/>");
            var friendlyName = "Element1";
            var key          = new DataProtectionKey()
            {
                FriendlyName = friendlyName, Xml = element.ToString()
            };

            var services = GetServices(nameof(StoreElement_PersistsData));
            var service  = new EntityFrameworkCoreXmlRepository <DataProtectionKeyContext>(services, NullLoggerFactory.Instance);

            service.StoreElement(element, friendlyName);

            // Use a separate instance of the context to verify correct data was saved to database
            using (var context = services.CreateScope().ServiceProvider.GetRequiredService <DataProtectionKeyContext>())
            {
                Assert.Equal(1, context.DataProtectionKeys.Count());
                Assert.Equal(key.FriendlyName, context.DataProtectionKeys.Single()?.FriendlyName);
                Assert.Equal(key.Xml, context.DataProtectionKeys.Single()?.Xml);
            }
        }
示例#9
0
        public async Task <bool> ActivateProtectionAsync(string password)
        {
            try
            {
                if (_protectionBusy)
                {
                    throw new Exception("Data protection is busy.");
                }
                _protectionBusy = true;

                if (string.IsNullOrWhiteSpace(password))
                {
                    throw new ArgumentNullException(nameof(password));
                }

                if (_protectionActivated)
                {
                    throw new Exception("Data protection is already activated.");
                }

                var dataProtectionEntity = await ReadDataProtectionEntity();

                if (dataProtectionEntity == null)
                {
                    throw new Exception("Data protection parameters not found.");
                }

                _key = new DataProtectionKey(dataProtectionEntity.Id, dataProtectionEntity.Params);

                _protectionActivated = _key.ValidatePassword(password);

                return(_protectionActivated);
            }
            finally
            {
                _protectionBusy = false;
            }
        }
示例#10
0
        public async Task EnableProtectionAsync(string password)
        {
            try
            {
                if (_protectionBusy)
                {
                    throw new Exception("Data protection is busy.");
                }
                _protectionBusy = true;

                if (string.IsNullOrWhiteSpace(password))
                {
                    throw new ArgumentNullException(nameof(password));
                }

                if (_protectionEnabled)
                {
                    throw new Exception("Data protection is already enabled.");
                }

                var prms = DataProtectionKey.CreateParams(password);

                var dataProtectionEntity = await SaveDataProtectionEntity(prms);

                _key = new DataProtectionKey(dataProtectionEntity.Id, dataProtectionEntity.Params);
                _key.ValidatePassword(password);

                await EncryptDatabase(_key);

                _protectionEnabled   = true;
                _protectionActivated = true;
            }
            finally
            {
                _protectionBusy = false;
            }
        }
示例#11
0
        private async Task DecryptDatabase(DataProtectionKey key)
        {
            using var scope = Services.CreateScope();

            // Accounts
            var scopedAccountRepository = scope.ServiceProvider.GetRequiredService <IAsyncRepository <Account> >();
            var accounts = await scopedAccountRepository.Query().ToListAsync();

            foreach (var account in accounts)
            {
                if (account.Password != null)
                {
                    account.Password = key.Decrypt(account.Password);
                }
                if (account.OtpSecret != null)
                {
                    account.OtpSecret = key.Decrypt(account.OtpSecret);
                }
            }

            // AppSettings
            var scopedAppSettingsRepository = scope.ServiceProvider.GetRequiredService <IAsyncRepository <AppSettings> >();
            var domainSettings = await scopedAppSettingsRepository.GetByIdAsync(ServerConstants.Domain);

            if (domainSettings != null)
            {
                var settings = JsonConvert.DeserializeObject <LdapSettings>(domainSettings.Value);
                settings.Password = key.Decrypt(settings.Password);
                var json = JsonConvert.SerializeObject(settings);
                domainSettings.Value = json;
            }
            var licenseSettings = await scopedAppSettingsRepository.GetByIdAsync(ServerConstants.Licensing);

            if (licenseSettings != null)
            {
                var settings = JsonConvert.DeserializeObject <LicensingSettings>(licenseSettings.Value);
                settings.ApiKey = key.Decrypt(settings.ApiKey);
                var json = JsonConvert.SerializeObject(settings);
                licenseSettings.Value = json;
            }

            // HardwareVaultsActivations
            var scopedHardwareVaultActivationRepository = scope.ServiceProvider.GetRequiredService <IAsyncRepository <HardwareVaultActivation> >();
            var hardwareVaultActivations = await scopedHardwareVaultActivationRepository.Query().ToListAsync();

            foreach (var hardwareVaultActivation in hardwareVaultActivations)
            {
                hardwareVaultActivation.AcivationCode = key.Decrypt(hardwareVaultActivation.AcivationCode);
            }

            // HardwareVaults
            var scopedHardwareVaultRepository = scope.ServiceProvider.GetRequiredService <IAsyncRepository <HardwareVault> >();
            var hardwareVaults = await scopedHardwareVaultRepository.Query().ToListAsync();

            foreach (var hardwareVault in hardwareVaults)
            {
                if (hardwareVault.MasterPassword != null)
                {
                    hardwareVault.MasterPassword = key.Decrypt(hardwareVault.MasterPassword);
                }
            }

            // HardwareVaultTasks
            var scopedHardwareVaultTaskRepository = scope.ServiceProvider.GetRequiredService <IAsyncRepository <HardwareVaultTask> >();
            var hardwareVaultTasks = await scopedHardwareVaultTaskRepository.Query().ToListAsync();

            foreach (var task in hardwareVaultTasks)
            {
                if (task.Password != null)
                {
                    task.Password = key.Decrypt(task.Password);
                }
                if (task.OtpSecret != null)
                {
                    task.OtpSecret = key.Decrypt(task.OtpSecret);
                }
            }

            // SharedAccounts
            var scopedSharedAccountRepository = scope.ServiceProvider.GetRequiredService <IAsyncRepository <SharedAccount> >();
            var sharedAccounts = await scopedSharedAccountRepository.Query().ToListAsync();

            foreach (var account in sharedAccounts)
            {
                if (account.Password != null)
                {
                    account.Password = key.Decrypt(account.Password);
                }
                if (account.OtpSecret != null)
                {
                    account.OtpSecret = key.Decrypt(account.OtpSecret);
                }
            }

            // SoftwareVaultInvitations
            //var scopedSoftwareVaultInvitationRepository = scope.ServiceProvider.GetRequiredService<IAsyncRepository<SoftwareVaultInvitation>>();
            //var softwareVaultInvitations = await scopedSoftwareVaultInvitationRepository.Query().ToListAsync();
            //foreach (var softwareVaultInvitation in softwareVaultInvitations)
            //{
            //    softwareVaultInvitation.ActivationCode = key.Encrypt(softwareVaultInvitation.ActivationCode);
            //}

            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                await scopedAccountRepository.UpdateOnlyPropAsync(accounts, new string[] { nameof(Account.Password), nameof(Account.OtpSecret) });

                if (domainSettings != null)
                {
                    await scopedAppSettingsRepository.UpdateAsync(domainSettings);
                }
                if (licenseSettings != null)
                {
                    await scopedAppSettingsRepository.UpdateAsync(licenseSettings);
                }
                await scopedHardwareVaultActivationRepository.UpdateOnlyPropAsync(hardwareVaultActivations, new string[] { nameof(HardwareVaultActivation.AcivationCode) });

                await scopedHardwareVaultRepository.UpdateOnlyPropAsync(hardwareVaults, new string[] { nameof(HardwareVault.MasterPassword) });

                await scopedHardwareVaultTaskRepository.UpdateOnlyPropAsync(hardwareVaultTasks, new string[] { nameof(HardwareVaultTask.Password), nameof(HardwareVaultTask.OtpSecret) });

                await scopedSharedAccountRepository.UpdateOnlyPropAsync(sharedAccounts, new string[] { nameof(SharedAccount.Password), nameof(SharedAccount.OtpSecret) });

                //await scopedSoftwareVaultInvitationRepository.UpdateOnlyPropAsync(softwareVaultInvitations, new string[] { nameof(SoftwareVaultInvitation.ActivationCode) });
                transactionScope.Complete();
            }
        }