Files
m2pack-secure/docs/client-integration.md
2026-04-14 11:33:35 +02:00

2.9 KiB

Client integration

Your current client already has a custom PackLib using zstd and XChaCha20. This project should become the next iteration, not a parallel dead tool.

Suggested migration

  1. Keep the current PackManager interface stable.
  2. Add a new loader beside the current pack code, for example:
    • src/PackLib/M2PackArchive.h
    • src/PackLib/M2PackArchive.cpp
  3. Route CPackManager::AddPack() by extension:
    • legacy format for old .pack
    • new format for .m2p
  4. Embed only the signing public key in the client.
  5. Resolve the content decryption key from:
    • launcher-provided memory
    • machine-bound cache
    • or a derived release secret

Client key header

For the current implementation, the client expects:

  • src/PackLib/M2PackKeys.h

Generate it from the release key material with:

m2pack export-client-config \
  --key keys/master.key \
  --public-key keys/signing.pub \
  --output /path/to/m2dev-client-src/src/PackLib/M2PackKeys.h

That keeps loader constants aligned with the archive builder.

Runtime validation

Minimum validation:

  • verify header magic and version
  • compare manifest hash
  • verify manifest signature
  • reject duplicate paths
  • reject path traversal
  • verify AEAD tag before decompression

Launcher key delivery

The client now supports runtime key overrides and no longer has to rely only on the compiled fallback key.

Supported inputs, highest priority last:

  1. shared memory mapping
  2. environment variables
  3. command line arguments

Command line

--m2pack-key-hex <64-hex-master-key>
--m2pack-pubkey-hex <64-hex-public-key>
--m2pack-key-map <mapping-name>

Environment

M2PACK_MASTER_KEY_HEX
M2PACK_SIGN_PUBKEY_HEX
M2PACK_KEY_MAP

Shared memory

Default mapping name:

Local\M2PackSharedKeys

Binary layout:

struct M2PackSharedKeys {
  char magic[8];           // "M2KEYS1\0"
  uint32_t version;        // 1
  uint32_t flags;          // reserved
  uint8_t master_key[32];
  uint8_t sign_public_key[32];
};

Recommended production path:

  • launcher fetches or unwraps the current content key
  • launcher creates the shared mapping
  • launcher starts the client with --m2pack-key-map Local\\M2PackSharedKeys
  • client reads runtime keys during startup
  • compiled fallback key remains only as migration fallback and should be removed later

Loader notes

  • Use memory-mapped I/O for the archive.
  • Keep a path-to-entry map in lowercase normalized form.
  • Decrypt per request, not by unpacking the full archive.
  • Keep a small decompression scratch buffer pool if the client reads in parallel.

Release model

  • master.key: private content encryption key
  • signing.key: private release signing key
  • signing.pub: embedded client verifier key

The signing key belongs in CI or a secured release box. The public key belongs in the client binary or in a protected launcher manifest.