From e18d36ebae30536c77c61cd5da123991e0ca1629 Mon Sep 17 00:00:00 2001 From: Rasmus Dahlberg Date: Sun, 31 Dec 2023 09:39:25 +0100 Subject: Add drafty prototype --- docs/http-api.md | 29 ----------------------------- docs/introduction.md | 32 +++++++------------------------- docs/state.md | 9 --------- docs/storage.md | 3 +++ docs/submission.md | 22 ++++++++++++++++++++++ 5 files changed, 32 insertions(+), 63 deletions(-) delete mode 100644 docs/http-api.md delete mode 100644 docs/state.md create mode 100644 docs/storage.md create mode 100644 docs/submission.md (limited to 'docs') diff --git a/docs/http-api.md b/docs/http-api.md deleted file mode 100644 index d78f2ee..0000000 --- a/docs/http-api.md +++ /dev/null @@ -1,29 +0,0 @@ -# HTTP API - -The monitor listens for HTTP POST requests on a well-known endpoint. For -example, the well-known endpoint might be `https://example.com/add-chain` or -`http://exampled3jsb2t6n2f5f6r4v4gkqmqd7h4hjucwb7y5.onion/add-chain`. - -The HTTP POST request body should be an X.509v3 chain in PEM format. The first -certificate must be a leaf. The remaining certificates must be CA certificates. - -To authenticate the node adding a certificate chain to the monitor, the HTTP -authorization header needs to be present and carry a valid value. - - Authorization: TYPE NAME:VALUE - -`TYPE`: custom HTTP authorization type used by the monitor, set to "silent-ct". - -`NAME`: identifier that the monitor uses to locate the right pre-shared secret. - -`VALUE`: HMAC with SHA256 as the hash function for the entire HTTP POST request -body. The HMAC key is derived by the node and the monitor from the pre-shared -secret `SECRET`, node name `NAME`, and HTTP authorization type `TYPE`. In Go: - - hkdf := hkdf.New(sha256.New, SECRET, TYPE, NAME) - key := make([]byte, 16) - io.ReadFull(hkdf, key) - -On successful processing of a request, the monitor outputs HTTP 200 OK. If the -HMAC value is incorrect or the node is not allowed to request certificates for -the domain names in the request body, the monitor outputs HTTP 401 Unauthorized. diff --git a/docs/introduction.md b/docs/introduction.md index 65b0366..b0d7e71 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -69,10 +69,9 @@ To filter out certificates that are not relevant, the monitor is configured with a list of domains to match on. Only matching certificates will be stored, which means there are nearly no storage requirements to run this type of monitor. -To achieve the property of _silence_, the trusted nodes push legitimately issued -certificates to the monitor which listens for such requests using an HTTP API. -The monitor will use the feedback from these nodes to further filter the -downloaded certificates that matched based on which ones are legitimate. If any +To get the property of _silence_, the monitor pulls the trusted nodes +periodically (HTTP GET) for legitimately issued certificates. The monitor will +use this feedback to filter the downloaded certificates that matched. If any certificates are found that no node pushed to the monitor, an alert is created. The communication channel between the trusted nodes and the monitor can be @@ -83,30 +82,13 @@ Owning that the communication channel is insecure helps avoid misconfiguration. A pre-shared secret is used for each node to authenticate with the monitor. That secret is never shown on the wire (an HMAC key is derived from it), which means that all a man-in-the-middle attacker can do is replay and block messages. -Accounting for replayed messages is either way a good thing, because it makes it -easy to overcome temporary issues like a spotty network, a monitor reboot, etc. -In other words, nodes can periodically (re)submit their legitimate certificates. -Blocked messages can not be solved by cryptography and will result in alerts. - -To keep the attack surface of the monitor down, one may optionally choose to -operate it as a Tor onion service, restrict access using WireGuard, or similar. -Or in the case of a single-node deployment, run everything on the same system. - -## Open questions - - - What do we do about certificates that appear in the logs after time `T`, but - which were issued with a `NotBefore` timestamp that is before time `T`? We - want to minimize noise, but also not open up for CA backdating threats. - - What options for generating alerts should be supported other than stdout, if - any? Most deployments already have ways to integrate with dashboards/email. +"Replays" can happen either way because the monitor polls periodically, i.e., +the monitor needs to account for the fact that it may poll the same thing twice. +Blocking can not be solved by cryptography and would simply result in alerts. ## Further documentation - - [HTTP API](./http-api.md): read more about how the trusted nodes - authenticate with the monitor to submit legitimately issued certificates. - - [State directory](./state.md): read more about how the trusted monitor keeps - track of its state as plaintext files in a given directory. Staying away - from a database is meant to ease debugging, silencing of alerts, etc. +docdoc ## Future ideas diff --git a/docs/state.md b/docs/state.md deleted file mode 100644 index fbb965d..0000000 --- a/docs/state.md +++ /dev/null @@ -1,9 +0,0 @@ -# State - -All state is managed by the silent-ct [manager](../internal/manager). All such -state is persisted to disk in a common directory as a collection of files. Not -having any database simplifies setup and manual debugging, should it be needed. - -## Structure of the state directory - -docdoc diff --git a/docs/storage.md b/docs/storage.md new file mode 100644 index 0000000..a0616ed --- /dev/null +++ b/docs/storage.md @@ -0,0 +1,3 @@ +# Storage + +docdoc diff --git a/docs/submission.md b/docs/submission.md new file mode 100644 index 0000000..357f07a --- /dev/null +++ b/docs/submission.md @@ -0,0 +1,22 @@ +# Submission + +docdoc + +## Format + + NAME MAC + + silent-ct:separator + ... + + +`NAME`: identifier that the monitor uses to locate the right secret. + +`MAC`: HMAC with SHA256 as the hash function, computed for line two and forward. +The HMAC key is derived by the node and the monitor from their shared secret: + + hkdf := hkdf.New(sha256.New, SECRET, []byte("silent-ct"), NAME) + key := make([]byte, 16) + io.ReadFull(hkdf, key) + +``: certificate chain in PEM format the node considers legitimate. -- cgit v1.2.3