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