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

110 lines
5.8 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.14, tagged
`spec-v0.14`, that this module implements (see `docs/traceability.md`), the CLI, and the handling of
Docs at spec v0.11 and the draft v0.12: READMEs, SECURITY, traceability, CHANGELOG The session that closed v0.11 left the documentation at v0.10 (review of 2 October, G14). - README.md and README.es.md say the same again: the reference implements v0.11, tagged, and the branch v0.12 the draft; SpecVersion 0.11; the area of 32 KiB in the picture of BODY; the table of modules with authorkey, internal/cms, internal/der, locator, wordkey and the public note; and what the CLI does now: encrypt -sign shows the key and the code of AUTHOR_MESSAGE before it signs, decrypt -expect-author writes nothing unless the key of an F4 matches, the lines of the verdicts break behind a mark, and decrypt and inspect say when a public note is not shown. The security properties no longer say that no signature is checked. - SECURITY.md: the scope is v0.11 and the draft v0.12; the limits of a signature, a seal and a key of words; the standard library among the cryptographic dependencies. - docs/traceability.md at the draft v0.12: rows for 24.1, 29.8 to 29.12, 38.1 and 44.1, and rows 29.2, 29.3, 29.7, 62.1, 64, 67, 70, 72 and 76 up to date, with the code and the tests of each. The cases of spec 64 that security_cms.json and locator.json still lack are marked pending. - CHANGELOG.md: an entry for the draft v0.12: the review and its fixes, the draft, the CMS reader with its own profile, the addresses of the locator, the CLI, the new test data, and what is pending. - capsule/format3.go: the comments of EncodeSecurityWith, EncodeAuthorSignature and EncodeSeal no longer say that this version defines no alg and no seal_type. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
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).
Docs at spec v0.11 and the draft v0.12: READMEs, SECURITY, traceability, CHANGELOG The session that closed v0.11 left the documentation at v0.10 (review of 2 October, G14). - README.md and README.es.md say the same again: the reference implements v0.11, tagged, and the branch v0.12 the draft; SpecVersion 0.11; the area of 32 KiB in the picture of BODY; the table of modules with authorkey, internal/cms, internal/der, locator, wordkey and the public note; and what the CLI does now: encrypt -sign shows the key and the code of AUTHOR_MESSAGE before it signs, decrypt -expect-author writes nothing unless the key of an F4 matches, the lines of the verdicts break behind a mark, and decrypt and inspect say when a public note is not shown. The security properties no longer say that no signature is checked. - SECURITY.md: the scope is v0.11 and the draft v0.12; the limits of a signature, a seal and a key of words; the standard library among the cryptographic dependencies. - docs/traceability.md at the draft v0.12: rows for 24.1, 29.8 to 29.12, 38.1 and 44.1, and rows 29.2, 29.3, 29.7, 62.1, 64, 67, 70, 72 and 76 up to date, with the code and the tests of each. The cases of spec 64 that security_cms.json and locator.json still lack are marked pending. - CHANGELOG.md: an entry for the draft v0.12: the review and its fixes, the draft, the CMS reader with its own profile, the addresses of the locator, the CLI, the new test data, and what is pending. - capsule/format3.go: the comments of EncodeSecurityWith, EncodeAuthorSignature and EncodeSeal no longer say that this version defines no alg and no seal_type. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
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 |
|---|---|
Docs at spec v0.11 and the draft v0.12: READMEs, SECURITY, traceability, CHANGELOG The session that closed v0.11 left the documentation at v0.10 (review of 2 October, G14). - README.md and README.es.md say the same again: the reference implements v0.11, tagged, and the branch v0.12 the draft; SpecVersion 0.11; the area of 32 KiB in the picture of BODY; the table of modules with authorkey, internal/cms, internal/der, locator, wordkey and the public note; and what the CLI does now: encrypt -sign shows the key and the code of AUTHOR_MESSAGE before it signs, decrypt -expect-author writes nothing unless the key of an F4 matches, the lines of the verdicts break behind a mark, and decrypt and inspect say when a public note is not shown. The security properties no longer say that no signature is checked. - SECURITY.md: the scope is v0.11 and the draft v0.12; the limits of a signature, a seal and a key of words; the standard library among the cryptographic dependencies. - docs/traceability.md at the draft v0.12: rows for 24.1, 29.8 to 29.12, 38.1 and 44.1, and rows 29.2, 29.3, 29.7, 62.1, 64, 67, 70, 72 and 76 up to date, with the code and the tests of each. The cases of spec 64 that security_cms.json and locator.json still lack are marked pending. - CHANGELOG.md: an entry for the draft v0.12: the review and its fixes, the draft, the CMS reader with its own profile, the addresses of the locator, the CLI, the new test data, and what is pending. - capsule/format3.go: the comments of EncodeSecurityWith, EncodeAuthorSignature and EncodeSeal no longer say that this version defines no alg and no seal_type. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
| `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 |
Docs at spec v0.11 and the draft v0.12: READMEs, SECURITY, traceability, CHANGELOG The session that closed v0.11 left the documentation at v0.10 (review of 2 October, G14). - README.md and README.es.md say the same again: the reference implements v0.11, tagged, and the branch v0.12 the draft; SpecVersion 0.11; the area of 32 KiB in the picture of BODY; the table of modules with authorkey, internal/cms, internal/der, locator, wordkey and the public note; and what the CLI does now: encrypt -sign shows the key and the code of AUTHOR_MESSAGE before it signs, decrypt -expect-author writes nothing unless the key of an F4 matches, the lines of the verdicts break behind a mark, and decrypt and inspect say when a public note is not shown. The security properties no longer say that no signature is checked. - SECURITY.md: the scope is v0.11 and the draft v0.12; the limits of a signature, a seal and a key of words; the standard library among the cryptographic dependencies. - docs/traceability.md at the draft v0.12: rows for 24.1, 29.8 to 29.12, 38.1 and 44.1, and rows 29.2, 29.3, 29.7, 62.1, 64, 67, 70, 72 and 76 up to date, with the code and the tests of each. The cases of spec 64 that security_cms.json and locator.json still lack are marked pending. - CHANGELOG.md: an entry for the draft v0.12: the review and its fixes, the draft, the CMS reader with its own profile, the addresses of the locator, the CLI, the new test data, and what is pending. - capsule/format3.go: the comments of EncodeSecurityWith, EncodeAuthorSignature and EncodeSeal no longer say that this version defines no alg and no seal_type. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
| 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
Docs at spec v0.11 and the draft v0.12: READMEs, SECURITY, traceability, CHANGELOG The session that closed v0.11 left the documentation at v0.10 (review of 2 October, G14). - README.md and README.es.md say the same again: the reference implements v0.11, tagged, and the branch v0.12 the draft; SpecVersion 0.11; the area of 32 KiB in the picture of BODY; the table of modules with authorkey, internal/cms, internal/der, locator, wordkey and the public note; and what the CLI does now: encrypt -sign shows the key and the code of AUTHOR_MESSAGE before it signs, decrypt -expect-author writes nothing unless the key of an F4 matches, the lines of the verdicts break behind a mark, and decrypt and inspect say when a public note is not shown. The security properties no longer say that no signature is checked. - SECURITY.md: the scope is v0.11 and the draft v0.12; the limits of a signature, a seal and a key of words; the standard library among the cryptographic dependencies. - docs/traceability.md at the draft v0.12: rows for 24.1, 29.8 to 29.12, 38.1 and 44.1, and rows 29.2, 29.3, 29.7, 62.1, 64, 67, 70, 72 and 76 up to date, with the code and the tests of each. The cases of spec 64 that security_cms.json and locator.json still lack are marked pending. - CHANGELOG.md: an entry for the draft v0.12: the review and its fixes, the draft, the CMS reader with its own profile, the addresses of the locator, the CLI, the new test data, and what is pending. - capsule/format3.go: the comments of EncodeSecurityWith, EncodeAuthorSignature and EncodeSeal no longer say that this version defines no alg and no seal_type. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
`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.