Skip to content

Repository files navigation

TODO

  • use mr stroustrup's guidelines from github to enforce best practices on identifiers - DONE

  • implement cmake --fresh option - DONE

  • Make CLI first then lets move to the watcher logic part.- DONE

  • Service implementation, we should be able to observe file changes from service - DONE

  • Modularize to files - DONE

  • FileRename not working fix - DONE

  • Create simple logger - DONE

  • Migrate Logger to use - DONE

  • File not available and then renamed to watching file not working - File created after watcher now available - DONE

  • Add log levels/configuration to logger & migrate update the logs - DONE

  • Integrate log levels with build flags( Rel, RelDbg, Debug) ? - DONE

  • Integrate CLI11 cli argument parser - DONE

  • Create file logging based on flag - DONE

  • Include clang-tidy as part of CMake build system - DONE

  • Include clang-format configuration for consistent formatting - DONE

  • Add AddressSanitizer (ASan) build configuration - InProgress

  • Add UndefinedBehaviorSanitizer (UBSan) build configuration

  • Enable a strong compiler warning set (-Wall, -Wextra, -Wpedantic)

  • Stop at CMake if there's any issue during build

  • Make verbose build logs optional

  • Add CMAKE_GENERATOR environment variable/flag to select build generator (Ninja or Make)

  • Define ownership-focused classes for OS/OpenSSL resources

  • Implement RAII wrappers for OpenSSL and Windows handles

  • Add scope-guard or RAII-based cleanup for directory handles

  • Use std::expected (C++23) for cleaner error handling

  • Extract encryption logic into reusable helper lambdas or functions to reduce duplication

  • Refactor toward an OOP application structure

  • Loop password prompt 3 times before giving up and exiting

  • Avoid std::string for passwords; research immutable/string memory behavior in C++

  • Protect password in memory to avoid exposure in dumps (secure byte buffer / secure allocator / OpenSSL cleansing; research more)

  • Handle CloseHandle on abrupt close of exe (Ctrl+C); use SetConsoleCtrlHandler for graceful shutdown on Windows

  • Encrypt file to specific destination

  • Only decrypt in main.cpp when required

  • Decide when to decrypt/open files using Windows/default app to make them available to the user

  • Define a complete open/decrypt/re-encrypt workflow(protocol handler , custom file extension? check for more): decrypt when the file is opened, then re-encrypt when changes are done

  • Fix duplicate/rapid modify events by capturing deltas as required (Notepad++, VS Code dual modified calls)

  • Add multi-threading to the application logic

  • Create multi-threaded logger

  • Implement config watcher to get logger level instead of environment variable, use std::atomic

  • Add ThreadSanitizer (TSan) build configuration and validate watch mode

  • Separate the encryption engine into a reusable core library CLI becomes one frontend Future GUI becomes another frontend Keep encryption logic independent of UI

  • Introduce a formal project directory layout (src, include, platform, crypto, watcher, logger, service, cmake, scripts, docs, tests, external)

  • Install and initialize as a Windows service

  • Implement support for Linux,

  • Implement support for macOS

  • Evaluate migrating third-party dependencies to vcpkg if dependency count grows

  • Add automated unit tests

  • Add encryption/decryption regression tests

  • Add watcher tests

  • Add CLI tests

  • Add logger tests

  • Add fuzz testing for encrypted file parser and decryption logic (maybe?)

  • GUI - Maybe last when most of the things are completed

  • Disabling default file logging till GUI is integrated, Enable it back onc GUI is up

  • By default file logging is disabled and console is enabled, reverse this after GUI is integrated

  • If console log is enabled log to console. if console isn't open open a new window and start logging there


Overview

  • Simple application to encrypt file using AES-256-CBC with password-derived(PBKDF2) key
  • NOTE: DO NOT USE THIS IS NOT SECURE YET
  • File watcher to encrypt based on file changes. Probably will create a OS service in future that reads writes from source to destination
  • Why did I created this? Because I will use it.

Dev Environment Setup

PREREQUISTE

  • Ofcourse git cli
  • Clang 20.1.1 (Used std: C++23)
  • OpenSSL 3.4.1 (Library: OpenSSL 3.4.1 11 Feb 2025)
  • Python 3.10.11 (Build script)
  • VS Code Extension: clangd with clang-tidy integration
  • Configuration: .clang-tidy file for naming rules
  • Optional for clangd users: clangd installed and in PATH,
  • Other packages that are required in PATH: clangd, cmake, clang++, python, lldb NOTE: Versions and compiler aren't mandatory but are used when this was being developed

Windows (Recommended: MSYS2 CLANG64)

  • Toolchain: MSYS2 / MinGW-w64 (CLANG64)
  • If switching environments, delete the existing build/ directory and configure again.
  • Default MSYS2 CLANG64 paths:
    • Toolchain root: C:/msys64/clang64
    • Binaries/PATH entry: C:/msys64/clang64/bin
    • OpenSSL root for CMake: C:/msys64/clang64 (In case installed via msys2 below)

Install dependencies from the MSYS2 CLANG64 terminal:

pacman -Syu
pacman -S mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-compiler-rt mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-ninja mingw-w64-clang-x86_64-openssl mingw-w64-clang-x86_64-python

#Optional clang-tidy
pacman -S mingw-w64-clang-x86_64-clang-tools-extra

compiler-rt is required for sanitizer builds such as AddressSanitizer.

Windows PowerShell configuration

If building from PowerShell, add the CLANG64 binary path before other toolchains so CMake finds the MSYS2 tools first:

# Encrypter Project (MSYS2 CLANG64)
$env:PATH = "C:/msys64/clang64/bin;" + $env:PATH
$env:OPENSSL_ROOT_DIR = "C:/msys64/clang64"
$env:MSYSTEM = "CLANG64"

Pwsh Function for project path update in case required :

function Start-EncrypterEnv {
    $env:PATH = "C:/msys64/clang64/bin;" + $env:PATH
    $env:OPENSSL_ROOT_DIR = "C:/msys64/clang64"
    $env:MSYSTEM = "CLANG64"
    Write-Host "Encrypter CLANG64 environment loaded." -ForegroundColor Green
}

Windows CMD

REM Encrypter Project (MSYS2 CLANG64)
set PATH=C:/msys64/clang64/bin;%PATH%
set OPENSSL_ROOT_DIR=C:/msys64/clang64
set MSYSTEM=CLANG64

Linux/macOS Bash:

TBU

Git Submodules

This project uses Git submodules for external dependencies such as external/CLI11.

First-time clone

git clone --recurse-submodules <repo-url>
cd encrypter

If you already cloned without --recurse-submodules, run:

git submodule update --init --recursive

Existing clone

When pulling latest changes, also update submodules:

git pull
git submodule update --init --recursive

If a submodule was updated to a newer remote commit and you want to fetch that latest remote state:

git submodule update --remote --merge

VS Code Setup

  1. Install clangd extension from VS Code Marketplace
  2. Create settings.json in workspace root (already created)
  3. Real-time naming violations will appear as squiggles and in Problems panel

Build-time Enforcement

  • .clang-tidy file configured for naming rules
  • VS Code Intellisense: VS Code with clangd extension
  • Conditional Build: python build.py --build-action rebuild --clang-tidy-check (only when flag passed)
  • CMake Target: cmake --build build --target clang-tidy-check (only when enabled)
  • Manual: clang-tidy src/main.cpp --checks='readability-identifier-naming'

Code Conventions (C++ Core Guidelines NL Section)

  • Functions: snake_case (NL.10)
  • Variables: snake_case (NL.10)
  • Constants: UPPER_CASE (NL.9 spirit)
  • Types: PascalCase (conventional)
  • Parameters: snake_case (NL.10)
  • Private members: snake_case_ (conventional)

Layout Guidelines (C++ Core Guidelines NL Section)

  • NL.17: K&R-derived layout
  • NL.18: C++-style declarator layout
  • NL.20: Single statements per line
  • NL.4: Consistent indentation

BUILD

Build Command Details

python build.py [--build-action {rebuild,clean,fresh}] [--build-type {debug,release,relwithdebinfo}] [--clang-tidy-check]

NOTE: Default values if not mentioned : clean release build without clang-tidy chec

Build Actions:

  • rebuild: Normal incremental build
  • clean: Clean build targets then rebuild
  • fresh: Complete rebuild with fresh configuration

Build type

Usage Examples:

# Rebuild with naming checks
python build.py --build-action rebuild --clang-tidy-check

# Clean build without naming checks
python build.py --build-action clean

# Fresh build with naming checks
python build.py --build-action fresh --clang-tidy-check

# Fresh build without naming checks
python build.py --build-action fresh --build-type debug

Debugging build script available in launch.json file

  • Keybindings for build using vscode tasks
    Path:
      Win: C:\Users\<YourUsername>\AppData\Roaming\Code\User\keybindings.json
      MacOS: ~/Library/Application Support/Code/User/keybindings.json
      Linux: ~/.config/Code/User/keybindings.json

    Paste the below json in keybindings.json edit keybindings if required:
      [
        {
          "key": "ctrl+alt+r",
          "command": "workbench.action.tasks.runTask",
          "args": "Build Encrypter"
        },
        {
          "key": "ctrl+alt+t",
          "command": "workbench.action.tasks.runTask",
          "args": "Encrypter CMake Clean Build"
        },
        {
          "key": "ctrl+alt+e",
          "command": "workbench.action.tasks.runTask",
          "args": "Encrypter Fresh Rebuild"
        }
      ]

Observation in Windows for file watcher using neovim

* nvim creates a temporary file from original file and write data on it
* when we save using :write or :w it first deletes the original file
* then renames the temporary file to original file.
* this creates two events i.e delete and create. 
    Try to avoid using neovim to edit the file we're wathing in windows.

About

Simple application to encrypt file using AES

Resources

Stars

Watchers

Forks

Contributors

Languages