Implement secure key via KDF for transparent data encryption/decryption #60
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				BlockStorage/repertory/pipeline/head This commit looks good
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	BlockStorage/repertory/pipeline/head This commit looks good
				
			This commit is contained in:
		| @@ -740,9 +740,13 @@ auto encrypt_provider::process_directory_entry( | ||||
|           utils::path::get_relative_path(dir_entry.get_path(), cfg.path), | ||||
|       }; | ||||
|  | ||||
|       i_file_db::file_data file_data{}; | ||||
|       auto file_res{file_db_->get_file_data(api_path, file_data)}; | ||||
|       if (file_res != api_error::success) { | ||||
|       auto file_res{ | ||||
|           file_db_->get_file_api_path(dir_entry.get_path(), api_path)}; | ||||
|       if (file_res == api_error::success) { | ||||
|         return true; | ||||
|       } | ||||
|  | ||||
|       if (file_res != api_error::item_not_found) { | ||||
|         // TODO raise error | ||||
|         return false; | ||||
|       } | ||||
| @@ -763,38 +767,34 @@ auto encrypt_provider::process_directory_entry( | ||||
|             do_add_directory(utils::path::get_parent_path(relative_path)); | ||||
|       } | ||||
|  | ||||
|       if (file_res == api_error::item_not_found) { | ||||
|         utils::encryption::encrypting_reader reader( | ||||
|             utils::path::strip_to_file_name(relative_path), | ||||
|             dir_entry.get_path(), | ||||
|             []() -> bool { return app_config::get_stop_requested(); }, | ||||
|             master_key_, file_data.kdf_configs, | ||||
|             utils::path::get_parent_path(relative_path)); | ||||
|         api_path = utils::path::create_api_path( | ||||
|             api_parent + "/" + reader.get_encrypted_file_name()); | ||||
|       utils::encryption::encrypting_reader reader( | ||||
|           utils::path::strip_to_file_name(relative_path), dir_entry.get_path(), | ||||
|           []() -> bool { return app_config::get_stop_requested(); }, | ||||
|           master_key_, get_encrypt_config().kdf_cfg, std::nullopt); | ||||
|       api_path = utils::path::create_api_path(api_parent + "/" + | ||||
|                                               reader.get_encrypted_file_name()); | ||||
|  | ||||
|         file_res = file_db_->add_or_update_file(i_file_db::file_data{ | ||||
|             .api_path = api_path, | ||||
|             .file_size = dynamic_cast<const utils::file::i_file *>(&dir_entry) | ||||
|                              ->size() | ||||
|                              .value_or(0U), | ||||
|             .iv_list = reader.get_iv_list(), | ||||
|             .kdf_configs = | ||||
|                 { | ||||
|                     *reader.get_kdf_config_for_data(), | ||||
|                     *reader.get_kdf_config_for_path(), | ||||
|                 }, | ||||
|             .source_path = dir_entry.get_path(), | ||||
|         }); | ||||
|         if (file_res != api_error::success) { | ||||
|           // TODO raise error | ||||
|           return false; | ||||
|         } | ||||
|  | ||||
|         event_system::instance().raise<filesystem_item_added>( | ||||
|             api_parent, api_path, false, function_name); | ||||
|       file_res = file_db_->add_or_update_file(i_file_db::file_data{ | ||||
|           .api_path = api_path, | ||||
|           .file_size = dynamic_cast<const utils::file::i_file *>(&dir_entry) | ||||
|                            ->size() | ||||
|                            .value_or(0U), | ||||
|           .iv_list = reader.get_iv_list(), | ||||
|           .kdf_configs = | ||||
|               { | ||||
|                   *reader.get_kdf_config_for_data(), | ||||
|                   *reader.get_kdf_config_for_path(), | ||||
|               }, | ||||
|           .source_path = dir_entry.get_path(), | ||||
|       }); | ||||
|       if (file_res != api_error::success) { | ||||
|         // TODO raise error | ||||
|         return false; | ||||
|       } | ||||
|  | ||||
|       event_system::instance().raise<filesystem_item_added>( | ||||
|           api_parent, api_path, false, function_name); | ||||
|  | ||||
|       return true; | ||||
|     } | ||||
|   } catch (const std::exception &ex) { | ||||
| @@ -966,12 +966,25 @@ auto encrypt_provider::start(api_item_added_callback /*api_item_added*/, | ||||
|   if (encrypt_config_.kdf_cfg.checksum == 0U) { | ||||
|     i_file_db::directory_data data{}; | ||||
|     if (file_db_->get_directory_data("/", data) == api_error::success) { | ||||
|       encrypt_config_.kdf_cfg = data.kdf_configs.first; | ||||
|       if (data.kdf_configs.first.checksum == 0U) { | ||||
|         encrypt_config_.kdf_cfg.seal(); | ||||
|       } else { | ||||
|         encrypt_config_.kdf_cfg = data.kdf_configs.first; | ||||
|       } | ||||
|     } else { | ||||
|       encrypt_config_.kdf_cfg.seal(); | ||||
|     } | ||||
|  | ||||
|     config_.set_encrypt_config(encrypt_config_); | ||||
|     data.kdf_configs = { | ||||
|         encrypt_config_.kdf_cfg, | ||||
|         encrypt_config_.kdf_cfg, | ||||
|     }; | ||||
|     auto res = file_db_->add_or_update_directory(data); | ||||
|     if (res != api_error::success) { | ||||
|       throw startup_exception(fmt::format("failed to update existing kdf|{}", | ||||
|                                           api_error_to_string(res))); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (encrypt_config_.kdf_cfg.checksum != | ||||
|   | ||||
| @@ -158,14 +158,17 @@ const auto create_file = [](repertory::i_provider &provider, | ||||
| const auto decrypt_parts = [](const repertory::app_config &cfg, | ||||
|                               std::string &path) { | ||||
|   if (path != "/" && path != "." && path != "..") { | ||||
|     repertory::utils::hash::hash_256_t key{}; | ||||
|     EXPECT_TRUE(repertory::utils::encryption::recreate_key_argon2id( | ||||
|         cfg.get_encrypt_config().encryption_token, | ||||
|         cfg.get_encrypt_config().kdf_cfg, key)); | ||||
|     auto parts = repertory::utils::string::split(path, '/', false); | ||||
|     for (auto &part : parts) { | ||||
|       if (part.empty()) { | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       EXPECT_EQ(true, repertory::utils::encryption::decrypt_file_name( | ||||
|                           cfg.get_encrypt_config().encryption_token, part)); | ||||
|       EXPECT_TRUE(repertory::utils::encryption::decrypt_file_name(key, part)); | ||||
|     } | ||||
|     path = repertory::utils::string::join(parts, '/'); | ||||
|   } | ||||
| @@ -492,9 +495,9 @@ static void get_directory_items(const app_config &cfg, i_provider &provider) { | ||||
|     EXPECT_STREQ("/test.txt", file->api_path.c_str()); | ||||
|     EXPECT_STREQ("/", file->api_parent.c_str()); | ||||
| #if defined(_WIN32) | ||||
|     EXPECT_EQ(std::size_t(47U), file->size); | ||||
|     EXPECT_EQ(std::size_t(83U), file->size); | ||||
| #else | ||||
|     EXPECT_EQ(std::size_t(46U), file->size); | ||||
|     EXPECT_EQ(std::size_t(82U), file->size); | ||||
| #endif | ||||
|  | ||||
|     auto source_path = | ||||
| @@ -522,9 +525,9 @@ static void get_directory_items(const app_config &cfg, i_provider &provider) { | ||||
|     EXPECT_STREQ("/sub10/moose.txt", file2->api_path.c_str()); | ||||
|     EXPECT_STREQ("/sub10", file2->api_parent.c_str()); | ||||
| #if defined(_WIN32) | ||||
|     EXPECT_EQ(std::size_t(46U), file2->size); | ||||
|     EXPECT_EQ(std::size_t(82U), file2->size); | ||||
| #else | ||||
|     EXPECT_EQ(std::size_t(45U), file2->size); | ||||
|     EXPECT_EQ(std::size_t(81U), file2->size); | ||||
| #endif | ||||
|     return; | ||||
|   } | ||||
| @@ -633,9 +636,9 @@ static void get_file(const app_config &cfg, i_provider &provider) { | ||||
|     EXPECT_STREQ("/test.txt", file.api_path.c_str()); | ||||
|     EXPECT_STREQ("/", file.api_parent.c_str()); | ||||
| #if defined(_WIN32) | ||||
|     EXPECT_EQ(std::size_t(47U), file.file_size); | ||||
|     EXPECT_EQ(std::size_t(83U), file.file_size); | ||||
| #else | ||||
|     EXPECT_EQ(std::size_t(46U), file.file_size); | ||||
|     EXPECT_EQ(std::size_t(82U), file.file_size); | ||||
| #endif | ||||
|     EXPECT_STREQ(source_path.c_str(), file.source_path.c_str()); | ||||
|     return; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user