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_onlyandtime_and_keydo 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
alg1 proves that someone with the secret key signed, not who holds it (spec §29.9, §29.12). For a signature with certificates (alg2) 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
.dkccan 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,.dkkmaterial) 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-381is archived.kyber-bls12381builds on it, and bothdrandandtlockdepend on that stack. Mitigation: pinned versions,govulncheckon 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.tlockhas had no tagged release since August 2024. Only its exported core (TimeLock,TimeUnlock,CiphertextToBytes,BytesToCiphertext) is used, pinned by version.drand/v2brings gRPC and protobuf into the binary throughcommon/chain, used for the chain-hash self-check of profiles. With thegoogle.golang.org/grpcv1.81.1 thatdrand/v2v2.1.7 selects,govulncheckreported GO-2026-6348 and GO-2026-6061 as reachable, sogo.modrequires grpc v1.84.0, andgolang.org/x/cryptov0.57.0 for GO-2026-6354 and GO-2026-6355. With those,govulncheckv1.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 ontokyber-bls12381alone) 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).