You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DateKeys/SECURITY.md

5.9 KiB

Security policy

Reporting a vulnerability

Please report vulnerabilities privately, not in public issues:

  • Send an e-mail to the maintainers at info@activething.com with "DateKeys security" in the subject. Ask for an encrypted channel before sending sensitive material.
  • Do not open an issue on the repository for a vulnerability.

Include a reproducible case: ideally a .dkc or .dkk file, or a test in the style of capsule/mutation_test.go. We aim to acknowledge reports within three working days.

Supported versions

The module is pre-1.0 (v0.x). Only the latest v0.x release receives fixes.

Scope and assumptions

In scope: every rule of the DateKeys Protocol Specification v0.11, tagged spec-v0.11, and of the draft v0.12 of the branch v0.12, that this module implements (see docs/traceability.md), the CLI, and the handling of untrusted input (.dkc, .dkk, relay responses, author key files). Among it: the paths and texts of a format 3 head, which the CLI writes to disk and to a terminal; the signatures, certificates and seals of the security area, whose names reach the lines of the verdicts; the public note; and the locator of a .dkk, with its addresses.

The protocol's own limits, which are not vulnerabilities of this module:

  • The Quicknet timelock is not post-quantum; long-lived ciphertexts are exposed to harvest-now, decrypt-later (spec §7.7, §53).
  • Time confidentiality depends on drand's threshold assumption (spec §7.6).
  • time_only and time_and_key do not authenticate the creator (spec §36.1). In format 3 the declared author, the comment, the public note and the modification times are text of the creator that proves nothing (spec §24.1, §29.7, §55.1).
  • An author signature of alg 1 proves that someone with the secret key signed, not who holds it (spec §29.9, §29.12). For a signature with certificates (alg 2) and for a seal, the module checks the cryptography and the dates, never who issued a certificate or a seal, or whether it was revoked: an official validator does (spec §29.10, §29.11). Whoever can open a capsule can remake its security area, so only a valid seal says that it was signed before the date (spec §7.9). The verdicts never decide the opening (spec §29.3).
  • A key of words is as strong as its words: after the date, whoever holds the .dkc can try words offline (spec §38.1).
  • Opening a mature capsule years later needs the historical release (spec §50).
  • A compromised device can copy plaintext or secrets (spec §7.8).
  • Go cannot guarantee that secrets are erased from memory. The module wipes its own buffers (I_PAYLOAD, CONTROL_CBOR, .dkk material) on a best effort basis and promises no more.

Cryptographic dependencies

No cryptography is implemented in this module. It depends on:

Dependency Role
filippo.io/age v1.3.2 age files, X25519, STREAM, header MAC; scrypt for the files of author keys
github.com/drand/tlock v1.2.0 TimeLock, TimeUnlock, ciphertext encoding
github.com/drand/drand/v2 v2.1.7 BLS verification (crypto.Scheme), chain-info hash
github.com/drand/kyber, github.com/drand/kyber-bls12381 BLS12-381 pairing
The Go standard library crypto/ed25519 (with the strict checks of internal/ed25519strict), crypto/rsa, crypto/ecdsa and SHA-2: author signatures and seals; crypto/pbkdf2: the key of words

Deterministic CBOR (spec §58) is implemented by the module itself, in package codec, without dependencies. So are DER and the reading of CMS signatures, X.509 certificates and RFC 3161 tokens (spec §29.10, §29.11), in internal/der and internal/cms: they read the structures with the profile of the specification, and the standard library verifies the signatures.

All versions are pinned in go.mod and verified through go.sum. Changes to age, tlock, drand or kyber are reviewed manually.

Known risks under watch

  • github.com/kilic/bls12-381 is archived. kyber-bls12381 builds on it, and both drand and tlock depend on that stack. Mitigation: pinned versions, govulncheck on every change and nightly, and this plan if a vulnerability appears or the dependency becomes untenable: (1) move to a maintained fork adopted by drand, or (2) extract BLS verification onto a maintained BLS12-381 implementation, keeping the golden vectors and fixtures as the acceptance test.
  • tlock has had no tagged release since August 2024. Only its exported core (TimeLock, TimeUnlock, CiphertextToBytes, BytesToCiphertext) is used, pinned by version.
  • drand/v2 brings gRPC and protobuf into the binary through common/chain, used for the chain-hash self-check of profiles. With the google.golang.org/grpc v1.81.1 that drand/v2 v2.1.7 selects, govulncheck reported GO-2026-6348 and GO-2026-6061 as reachable, so go.mod requires grpc v1.84.0, and golang.org/x/crypto v0.57.0 for GO-2026-6354 and GO-2026-6355. With those, govulncheck v1.8.0 on Go 1.26.8 finds no reachable vulnerability (25 September 2026); two unreachable advisories without a released fix remain, GO-2026-6443 (grpc) and GO-2026-5932 (x/crypto). Build with a patched Go toolchain: Go 1.26.0 itself has reachable standard-library advisories fixed in 1.26.1 and later. Plan §11 item 5 (extracting BLS verification onto kyber-bls12381 alone) would remove gRPC from the graph entirely.
  • Fixtures over past rounds rely on the embedded signatures being genuine; every test run verifies them against the pinned public key.

Supply chain

  • Reproducible builds: -trimpath, CGO_ENABLED=0, pinned toolchain in CI.
  • Releases publish SHA-256 checksums and a CycloneDX SBOM, and are signed with cosign using the project's signing key.
  • The Quicknet root of trust is compiled into the binary and checked against its pinned profile_hash (4147645109798ecbc9f630c2f709835bb5846fe7911a6bd5c5755e25ade2ada4).

Powered by TurnKey Linux.