Skip to content

Latest commit

 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vault

A small C++17 library for password-protected files, with three operations: create, read, and update.

Vault uses AES-256-GCM authenticated encryption and scrypt password derivation. OpenSSL 3.5 or newer is the only external dependency. The test executable uses a small local harness.

Build and test

Requirements: CMake 3.24+, a C++17 compiler, and OpenSSL 3.5+ development files. OpenSSL 3.5 is the LTS baseline; use a current patched release of a supported series. On macOS with Homebrew:

brew install cmake openssl@3
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \
  -DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)"
cmake --build build --parallel
ctest --test-dir build --output-on-failure

On Linux, install a supported OpenSSL development package (or build a supported release) and use the same CMake commands. Set OPENSSL_ROOT_DIR when OpenSSL is outside standard search paths. On Windows, use Visual Studio 2022 and vcpkg's openssl:x64-windows, passing its CMake toolchain file when configuring; build with --config Release and test with -C Release.

Use -DBUILD_TESTING=OFF for library-only builds, -DBUILD_SHARED_LIBS=ON for a shared library, or -DVAULT_BUILD_EXAMPLES=ON to build vault_example. The example accepts an output path and overwrites that file. GCC/Clang on Unix also support -DVAULT_ENABLE_SANITIZERS=ON in a separate Debug build.

Usage

#include <vault.h>

int main() {
    vault::userdata_t initial{'h', 'i'};
    // Example only: obtain a real password securely rather than hardcoding it.
    auto token = vault::create("example.vault", "example password", initial);
    vault::update("example.vault", token, {'h', 'e', 'l', 'l', 'o'});
    auto data = vault::read("example.vault", token);
    vault::wipe(token);
    vault::wipe(data);

    auto reopened = vault::read("example.vault", "example password");
    vault::wipe(reopened);
}

read(path, password, &token) can also return a reusable token. The optional output token is unchanged if the read fails. All failures throw std::runtime_error, except standard allocation failures. Exception messages are for diagnostics, not a stable machine-readable API.

Behavioral and security contracts

  • Reads verify the complete GCM tag before releasing plaintext. The header is authenticated too. Wrong credentials and modified ciphertext are rejected.
  • Each create uses a new random 16-byte salt; each write uses a fresh random 12-byte nonce. The authentication tag is 16 bytes.
  • scrypt uses fixed N=131072, r=8, p=1 parameters (about 128 MiB working memory), with a 256 MiB OpenSSL memory ceiling. Files cannot request arbitrary KDF work.
  • Tokens contain the raw 32-byte key and are bearer secrets. Anyone holding one can read and update that vault. They remain valid across updates; recreating the file invalidates old tokens. Copies of the same vault share token access.
  • wipe() cleanses the current bytes of a vector. It cannot erase copies, previously reallocated storage, caller-owned password strings, or OS snapshots. Internal keys and unsuccessful decryption buffers are cleansed automatically.
  • Passwords must contain 1–1,048,576 bytes; embedded NUL bytes are supported. Payloads may be empty and are limited to 64 MiB. Operations buffer files in memory.
  • Writes use exclusive temporary files in the destination directory, flush file contents, and replace the destination. Failures before replacement preserve the original. POSIX files have owner-only permissions; Windows files inherit directory ACLs. Existing ownership, permissions, hard links, and extended attributes are not preserved. A destination symlink is replaced rather than followed on POSIX.
  • Paths are UTF-8. Parent directories must exist and be trusted. Coordinate writers externally: there is no locking, compare-and-swap, rollback protection, or promise of persistence across power loss (the parent directory is not explicitly synced). Atomic replacement depends on the filesystem's rename/replacement guarantees.
  • Password strength still matters. This library does not provide memory locking, secure deletion of old files, or a separately audited cryptographic implementation.

See the format specification for byte layouts.

Install and consume

cmake --install build --prefix /your/install/prefix

Consumers set CMAKE_PREFIX_PATH to that prefix and use:

find_package(vault 1 CONFIG REQUIRED)
target_link_libraries(your_application PRIVATE vault::vault)

License

MIT; see LICENSE.

About

A small C++17 library for password-protected files using AES-256-GCM authenticated encryption and scrypt, powered by OpenSSL.

Topics

Resources

Stars

9 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages