mirror of
				https://github.com/kunkundi/crossdesk.git
				synced 2025-10-26 20:25:34 +08:00 
			
		
		
		
	[feat] generate random AES128 key and iv during initialization, save them in cache file and load when program starts
This commit is contained in:
		| @@ -154,7 +154,7 @@ int Render::ShowRecentConnections() { | ||||
|     } | ||||
|  | ||||
|     if (delete_connection_) { | ||||
|       if (!thumbnail_.DeleteThumbnail(it->first)) { | ||||
|       if (!thumbnail_->DeleteThumbnail(it->first)) { | ||||
|         reload_recent_connections_ = true; | ||||
|         delete_connection_ = false; | ||||
|       } | ||||
|   | ||||
| @@ -74,13 +74,13 @@ Render::Render() {} | ||||
| Render::~Render() {} | ||||
|  | ||||
| int Render::SaveSettingsIntoCacheFile() { | ||||
|   std::lock_guard<std::mutex> lock(cd_cache_mutex_); | ||||
|   cd_cache_file_ = fopen("cache.cd", "w+"); | ||||
|   cd_cache_mutex_.lock(); | ||||
|   std::ofstream cd_cache_file_("cache.cd", std::ios::binary); | ||||
|   if (!cd_cache_file_) { | ||||
|     cd_cache_mutex_.unlock(); | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   fseek(cd_cache_file_, 0, SEEK_SET); | ||||
|   memset(&cd_cache_.client_id, 0, sizeof(cd_cache_.client_id)); | ||||
|   strncpy(cd_cache_.client_id, client_id_, sizeof(client_id_)); | ||||
|   memset(&cd_cache_.password, 0, sizeof(cd_cache_.password)); | ||||
| @@ -93,8 +93,10 @@ int Render::SaveSettingsIntoCacheFile() { | ||||
|          sizeof(video_encode_format_button_value_)); | ||||
|   memcpy(&cd_cache_.enable_hardware_video_codec, &enable_hardware_video_codec_, | ||||
|          sizeof(enable_hardware_video_codec_)); | ||||
|   fwrite(&cd_cache_, sizeof(cd_cache_), 1, cd_cache_file_); | ||||
|   fclose(cd_cache_file_); | ||||
|  | ||||
|   cd_cache_file_.write(reinterpret_cast<char*>(&cd_cache_), sizeof(CDCache)); | ||||
|   cd_cache_file_.close(); | ||||
|   cd_cache_mutex_.unlock(); | ||||
|  | ||||
|   config_center_.SetLanguage((ConfigCenter::LANGUAGE)language_button_value_); | ||||
|   config_center_.SetVideoQuality( | ||||
| @@ -109,11 +111,15 @@ int Render::SaveSettingsIntoCacheFile() { | ||||
| } | ||||
|  | ||||
| int Render::LoadSettingsFromCacheFile() { | ||||
|   std::lock_guard<std::mutex> lock(cd_cache_mutex_); | ||||
|   cd_cache_file_ = fopen("cache.cd", "r+"); | ||||
|   cd_cache_mutex_.lock(); | ||||
|   std::ifstream cd_cache_file_("cache.cd", std::ios::binary); | ||||
|   if (!cd_cache_file_) { | ||||
|     cd_cache_mutex_.unlock(); | ||||
|  | ||||
|     LOG_INFO("Init cache file by using default settings"); | ||||
|     memset(password_saved_, 0, sizeof(password_saved_)); | ||||
|     memset(aes128_key_, 0, sizeof(aes128_key_)); | ||||
|     memset(aes128_iv_, 0, sizeof(aes128_iv_)); | ||||
|     language_button_value_ = 0; | ||||
|     video_quality_button_value_ = 0; | ||||
|     video_encode_format_button_value_ = 1; | ||||
| @@ -126,12 +132,18 @@ int Render::LoadSettingsFromCacheFile() { | ||||
|         (ConfigCenter::VIDEO_ENCODE_FORMAT)video_encode_format_button_value_); | ||||
|     config_center_.SetHardwareVideoCodec(enable_hardware_video_codec_); | ||||
|  | ||||
|     thumbnail_ = std::make_unique<Thumbnail>(); | ||||
|     thumbnail_->GetKeyAndIv(aes128_key_, aes128_iv_); | ||||
|     thumbnail_->DeleteAllFilesInDirectory(); | ||||
|  | ||||
|     SaveSettingsIntoCacheFile(); | ||||
|  | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   fseek(cd_cache_file_, 0, SEEK_SET); | ||||
|   fread(&cd_cache_, sizeof(cd_cache_), 1, cd_cache_file_); | ||||
|   fclose(cd_cache_file_); | ||||
|   cd_cache_file_.read(reinterpret_cast<char*>(&cd_cache_), sizeof(CDCache)); | ||||
|   cd_cache_file_.close(); | ||||
|   cd_cache_mutex_.unlock(); | ||||
|  | ||||
|   memset(&client_id_, 0, sizeof(client_id_)); | ||||
|   strncpy(client_id_, cd_cache_.client_id, sizeof(client_id_)); | ||||
| @@ -139,6 +151,12 @@ int Render::LoadSettingsFromCacheFile() { | ||||
|   if (0 != strcmp(password_saved_, "") && 7 == sizeof(password_saved_)) { | ||||
|     password_inited_ = true; | ||||
|   } | ||||
|  | ||||
|   memcpy(aes128_key_, cd_cache_.key, sizeof(cd_cache_.key)); | ||||
|   memcpy(aes128_iv_, cd_cache_.iv, sizeof(cd_cache_.iv)); | ||||
|  | ||||
|   thumbnail_ = std::make_unique<Thumbnail>(aes128_key_, aes128_iv_); | ||||
|  | ||||
|   language_button_value_ = cd_cache_.language; | ||||
|   video_quality_button_value_ = cd_cache_.video_quality; | ||||
|   video_encode_format_button_value_ = cd_cache_.video_encode_format; | ||||
| @@ -802,7 +820,7 @@ int Render::Run() { | ||||
|           DestroyStreamWindowContext(); | ||||
|  | ||||
|           if (dst_buffer_) { | ||||
|             thumbnail_.SaveToThumbnail( | ||||
|             thumbnail_->SaveToThumbnail( | ||||
|                 (char*)dst_buffer_, video_width_, video_height_, remote_id_, | ||||
|                 host_name_, remember_password_ ? remote_password_ : ""); | ||||
|             recent_connection_image_save_time_ = SDL_GetTicks(); | ||||
| @@ -911,7 +929,7 @@ int Render::Run() { | ||||
|       // loal recent connection thumbnails after saving for 1 second | ||||
|       uint32_t now_time = SDL_GetTicks(); | ||||
|       if (now_time - recent_connection_image_save_time_ >= 1000) { | ||||
|         int ret = thumbnail_.LoadThumbnail( | ||||
|         int ret = thumbnail_->LoadThumbnail( | ||||
|             main_renderer_, recent_connection_textures_, | ||||
|             &recent_connection_image_width_, &recent_connection_image_height_); | ||||
|         if (!ret) { | ||||
|   | ||||
| @@ -11,6 +11,7 @@ | ||||
|  | ||||
| #include <atomic> | ||||
| #include <chrono> | ||||
| #include <fstream> | ||||
| #include <string> | ||||
|  | ||||
| #include "../../thirdparty/projectx/src/interface/x.h" | ||||
| @@ -122,10 +123,13 @@ class Render { | ||||
|     int video_quality; | ||||
|     int video_encode_format; | ||||
|     bool enable_hardware_video_codec; | ||||
|  | ||||
|     unsigned char key[16]; | ||||
|     unsigned char iv[16]; | ||||
|   } CDCache; | ||||
|  | ||||
|  private: | ||||
|   FILE *cd_cache_file_ = nullptr; | ||||
|   std::ifstream cd_cache_file_; | ||||
|   CDCache cd_cache_; | ||||
|   std::mutex cd_cache_mutex_; | ||||
|  | ||||
| @@ -238,9 +242,10 @@ class Render { | ||||
|   SDL_Rect stream_render_rect_; | ||||
|   uint32_t stream_pixformat_ = 0; | ||||
|   std::string host_name_ = ""; | ||||
|   std::string image_path_ = "thumbnails"; | ||||
|  | ||||
|   Thumbnail thumbnail_; | ||||
|   unsigned char aes128_key_[16]; | ||||
|   unsigned char aes128_iv_[16]; | ||||
|   std::unique_ptr<Thumbnail> thumbnail_; | ||||
|  | ||||
|   bool resizable_ = false; | ||||
|   bool label_inited_ = false; | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| #include <openssl/aes.h> | ||||
| #include <openssl/crypto.h> | ||||
| #include <openssl/evp.h> | ||||
| #include <openssl/rand.h> | ||||
|  | ||||
| #include <chrono> | ||||
| #include <fstream> | ||||
| @@ -63,7 +64,17 @@ void ScaleYUV420pToABGR(char* dst_buffer_, int video_width_, int video_height_, | ||||
|   } | ||||
| } | ||||
|  | ||||
| Thumbnail::Thumbnail() { std::filesystem::create_directory(image_path_); } | ||||
| Thumbnail::Thumbnail() { | ||||
|   RAND_bytes(aes128_key_, sizeof(aes128_key_)); | ||||
|   RAND_bytes(aes128_iv_, sizeof(aes128_iv_)); | ||||
|   std::filesystem::create_directory(image_path_); | ||||
| } | ||||
|  | ||||
| Thumbnail::Thumbnail(unsigned char* aes128_key, unsigned char* aes128_iv) { | ||||
|   memcpy(aes128_key_, aes128_key, sizeof(aes128_key_)); | ||||
|   memcpy(aes128_iv_, aes128_iv, sizeof(aes128_iv_)); | ||||
|   std::filesystem::create_directory(image_path_); | ||||
| } | ||||
|  | ||||
| Thumbnail::~Thumbnail() { | ||||
|   if (rgba_buffer_) { | ||||
| @@ -95,7 +106,7 @@ int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height, | ||||
|       image_name = remote_id + "Y" + password + host_name; | ||||
|     } | ||||
|  | ||||
|     std::string ciphertext = AES_encrypt(image_name, key_, iv_); | ||||
|     std::string ciphertext = AES_encrypt(image_name, aes128_key_, aes128_iv_); | ||||
|     std::string file_path = image_path_ + ciphertext; | ||||
|     stbi_write_png(file_path.data(), thumbnail_width_, thumbnail_height_, 4, | ||||
|                    rgba_buffer_, thumbnail_width_ * 4); | ||||
| @@ -214,7 +225,7 @@ int Thumbnail::LoadThumbnail(SDL_Renderer* renderer, | ||||
|       size_t pos1 = image_paths[i].string().find('/') + 1; | ||||
|       std::string cipher_image_name = image_paths[i].string().substr(pos1); | ||||
|       std::string original_image_name = | ||||
|           AES_decrypt(cipher_image_name, key_, iv_); | ||||
|           AES_decrypt(cipher_image_name, aes128_key_, aes128_iv_); | ||||
|       std::string image_path = image_path_ + cipher_image_name; | ||||
|       textures[original_image_name] = nullptr; | ||||
|       LoadTextureFromFile(image_path.c_str(), renderer, | ||||
| @@ -226,7 +237,7 @@ int Thumbnail::LoadThumbnail(SDL_Renderer* renderer, | ||||
| } | ||||
|  | ||||
| int Thumbnail::DeleteThumbnail(const std::string& file_name) { | ||||
|   std::string ciphertext = AES_encrypt(file_name, key_, iv_); | ||||
|   std::string ciphertext = AES_encrypt(file_name, aes128_key_, aes128_iv_); | ||||
|   std::string file_path = image_path_ + ciphertext; | ||||
|   if (std::filesystem::exists(file_path)) { | ||||
|     std::filesystem::remove(file_path); | ||||
| @@ -236,6 +247,19 @@ int Thumbnail::DeleteThumbnail(const std::string& file_name) { | ||||
|   } | ||||
| } | ||||
|  | ||||
| int Thumbnail::DeleteAllFilesInDirectory() { | ||||
|   if (std::filesystem::exists(image_path_) && | ||||
|       std::filesystem::is_directory(image_path_)) { | ||||
|     for (const auto& entry : std::filesystem::directory_iterator(image_path_)) { | ||||
|       if (std::filesystem::is_regular_file(entry.status())) { | ||||
|         std::filesystem::remove(entry.path()); | ||||
|       } | ||||
|     } | ||||
|     return 0; | ||||
|   } | ||||
|   return -1; | ||||
| } | ||||
|  | ||||
| std::string Thumbnail::AES_encrypt(const std::string& plaintext, | ||||
|                                    unsigned char* key, unsigned char* iv) { | ||||
|   EVP_CIPHER_CTX* ctx; | ||||
|   | ||||
| @@ -15,6 +15,7 @@ | ||||
| class Thumbnail { | ||||
|  public: | ||||
|   Thumbnail(); | ||||
|   explicit Thumbnail(unsigned char* aes128_key, unsigned char* aes128_iv); | ||||
|   ~Thumbnail(); | ||||
|  | ||||
|  public: | ||||
| @@ -29,6 +30,24 @@ class Thumbnail { | ||||
|  | ||||
|   int DeleteThumbnail(const std::string& file_name); | ||||
|  | ||||
|   int DeleteAllFilesInDirectory(); | ||||
|  | ||||
|   int GetKey(unsigned char* aes128_key) { | ||||
|     memcpy(aes128_key, aes128_key_, sizeof(aes128_key_)); | ||||
|     return sizeof(aes128_key_); | ||||
|   } | ||||
|  | ||||
|   int GetIv(unsigned char* aes128_iv) { | ||||
|     memcpy(aes128_iv, aes128_iv_, sizeof(aes128_iv_)); | ||||
|     return sizeof(aes128_iv_); | ||||
|   } | ||||
|  | ||||
|   int GetKeyAndIv(unsigned char* aes128_key, unsigned char* aes128_iv) { | ||||
|     memcpy(aes128_key, aes128_key_, sizeof(aes128_key_)); | ||||
|     memcpy(aes128_iv, aes128_iv_, sizeof(aes128_iv_)); | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   std::vector<std::filesystem::path> FindThumbnailPath( | ||||
|       const std::filesystem::path& directory); | ||||
| @@ -46,8 +65,8 @@ class Thumbnail { | ||||
|   std::string image_path_ = "thumbnails/"; | ||||
|   std::map<std::time_t, std::filesystem::path> thumbnails_sorted_by_write_time_; | ||||
|  | ||||
|   unsigned char* key_ = (unsigned char*)"01234567890123456789012345678901"; | ||||
|   unsigned char* iv_ = (unsigned char*)"01234567890123456"; | ||||
|   unsigned char aes128_key_[16]; | ||||
|   unsigned char aes128_iv_[16]; | ||||
|   unsigned char ciphertext_[64]; | ||||
|   unsigned char decryptedtext_[64]; | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user