aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/api.md114
1 files changed, 66 insertions, 48 deletions
diff --git a/doc/api.md b/doc/api.md
index 4f43d2c..57ad119 100644
--- a/doc/api.md
+++ b/doc/api.md
@@ -9,13 +9,12 @@ It can be found
This is a work-in-progress document that may be moved or modified.
## Overview
-The log implements an HTTP(S) API:
+Logs implement an HTTP(S) API for accepting requests and sending
+responses.
-- Requests to the log use the HTTP GET method.
-- Input data (in requests) and output data (in responses) are
- expressed as ASCII-encoded key/value pairs.
-- Requests use HTTP entity headers for input data while responses use
- the HTTP message body for output data.
+- Input data in requests and output data in responses are expressed as
+ ASCII-encoded key/value pairs.
+- Requests with input data use HTTP POST to send the data to a log.
- Binary data is hex-encoded before being transmitted.
The motivation for using a text based key/value format for request and
@@ -29,12 +28,12 @@ wire-format in use by the Tor project.
## Primitives
### Cryptography
-The log uses the same Merkle tree hash strategy as
+Logs use the same Merkle tree hash strategy as
[RFC 6962,ยง2](https://tools.ietf.org/html/rfc6962#section-2).
The hash functions must be
[SHA256](https://csrc.nist.gov/csrc/media/publications/fips/180/4/final/documents/fips180-4-draft-aug2014.pdf).
-The log must sign tree heads using
-[Ed25519](https://tools.ietf.org/html/rfc8032). The log's witnesses
+Logs must sign tree heads using
+[Ed25519](https://tools.ietf.org/html/rfc8032). Log witnesses
must also sign tree heads using Ed25519.
All other parts that are not Merkle tree related also use SHA256 as
@@ -75,7 +74,7 @@ you may use it though. The main point of using Trunnel is that it
makes a simple format explicit and unambiguous.
#### Merkle tree head
-Tree heads are signed by the log and its witnesses. It contains a
+Tree heads are signed both by a log and its witnesses. It contains a
timestamp, a tree size, and a root hash. The timestamp is included so
that monitors can ensure _liveliness_. It is the time since the UNIX
epoch (January 1, 1970 00:00 UTC) in seconds. The tree size
@@ -95,7 +94,7 @@ not cosign a tree head if it is inconsistent with prior history or if
the timestamp is backdated or future-dated more than 12 hours.
#### Merkle tree leaf
-The log supports a single leaf type. It contains a shard hint, a
+Logs support a single leaf type. It contains a shard hint, a
checksum over whatever the submitter wants to log a checksum for, a
signature that the submitter computed over the shard hint and the
checksum, and a hash of the submitter's public verification key, that
@@ -115,8 +114,8 @@ struct tree_leaf {
```
`message` is composed of the `shard_hint`, chosen by the submitter to
-match the shard interval for the log, and the submitter's `checksum`
-to be logged.
+match the shard interval for the log it's submitting to, and the
+submitter's `checksum` to be logged.
`signature_over_message` is a signature over `message`, using the
submitter's verification key. It must be possible to verify the
@@ -134,27 +133,23 @@ Every log has a base URL that identifies it uniquely. The only
constraint is that it must be a valid HTTP(S) URL that can have the
`/st/v0/<endpoint>` suffix appended. For example, a complete endpoint
URL could be
-`https://log.example.com/2021/st/v0/get-signed-tree-head`.
+`https://log.example.com/2021/st/v0/get-tree-head-cosigned`.
-Input data (in requests) is sent as ASCII key/value pairs as HTTP
-entity headers, with their keys prefixed with the string
-`stlog-`. Example: For sending `treee_size=4711` as input a client
-would send the HTTP header `stlog-tree_size: 4711`.
+Input data (in requests) is POST:ed in the HTTP message body as ASCII
+key/value pairs.
Output data (in replies) is sent in the HTTP message body in the same
format as the input data, i.e. as ASCII key/value pairs on the format
-`Key: Value`. Example: For sending `tree_size=4711` as output a log
-would send an HTTP message body consisting of `stlog-tree_size: 4711`.
+`Key=Value`
The HTTP status code is 200 OK to indicate success. A different HTTP
-status code is used to indicate failure. The log should set the value
-value for the key `error` to a human-readable string describing what
-went wrong. For example, `error: invalid signature`, `error: rate
-limit exceeded`, or `error: unknown leaf hash`.
+status code is used to indicate failure, in which case a log should
+respond with a human-readable string describing what went wrong using
+the key `error`. Example: `error=Invalid signature.`.
### get-tree-head-cosigned
Returns the latest cosigned tree head. Used together with
-`get-proof-by-hash` and `get-consistency-proof` for verifying the log.
+`get-proof-by-hash` and `get-consistency-proof` for verifying the tree.
```
GET <base url>/st/v0/get-tree-head-cosigned
@@ -168,8 +163,9 @@ Output on success:
seconds since the UNIX epoch.
- `tree_size`: `tree_head.tree_size` ASCII-encoded decimal number.
- `root_hash`: `tree_head.root_hash` hex-encoded.
-- `signature`: hex-encoded Ed25519 signature over `tree_head`
- serialzed as described in section `Merkle tree head`.
+- `signature`: hex-encoded Ed25519 signature over `timestamp`,
+ `tree_size` and `root_hash` serialized into a `tree_head` as
+ described in section `Merkle tree head`.
- `key_hash`: a hash of the public verification key (belonging to
either the log or to one of its witnesses), which can be used to
verify the most recent `signature`. The key is encoded as defined
@@ -197,8 +193,9 @@ Output on success:
seconds since the UNIX epoch.
- `tree_size`: `tree_head.tree_size` ASCII-encoded decimal number.
- `root_hash`: `tree_head.root_hash` hex-encoded.
-- `signature`: hex-encoded Ed25519 signature over `tree_head`
- serialzed as described in section `Merkle tree head`.
+- `signature`: hex-encoded Ed25519 signature over `timestamp`,
+ `tree_size` and `root_hash` serialized into a `tree_head` as
+ described in section `Merkle tree head`.
- `key_hash`: a hash of the log's public verification key, which can
be used to verify `signature`. The key is encoded as defined in
[RFC 8032, section 5.1.2](https://tools.ietf.org/html/rfc8032#section-5.1.2),
@@ -224,8 +221,9 @@ Output on success:
seconds since the UNIX epoch.
- `tree_size`: `tree_head.tree_size` ASCII-encoded decimal number.
- `root_hash`: `tree_head.root_hash` hex-encoded.
-- `signature`: hex-encoded Ed25519 signature over `tree_head`
- serialzed as described in section `Merkle tree head`.
+- `signature`: hex-encoded Ed25519 signature over `timestamp`,
+ `tree_size` and `root_hash` serialized into a `tree_head` as
+ described in section `Merkle tree head`.
- `key_hash`: a hash of the log's public verification key that can be
used to verify `signature`. The key is encoded as defined in
[RFC 8032, section 5.1.2](https://tools.ietf.org/html/rfc8032#section-5.1.2),
@@ -237,7 +235,7 @@ There is exactly one `signature` and one `key_hash` field. The
### get-proof-by-hash
```
-GET <base url>/st/v0/get-proof-by-hash
+POST <base url>/st/v0/get-proof-by-hash
```
Input:
@@ -260,9 +258,12 @@ other words, `SHA256(0x00 | tree_leaf)`.
proof of zero or more node hashes. The order of node hashes follow
from the hash strategy, see RFC 6962.
+Example: `echo "leaf_hash=241fd4538d0a35c2d0394e4710ea9e6916854d08f62602fb03b55221dcdac90f
+tree_size=4711" | curl --data-binary @- localhost/st/v0/get-proof-by-hash`
+
### get-consistency-proof
```
-GET <base url>/st/v0/get-consistency-proof
+POST <base url>/st/v0/get-consistency-proof
```
Input:
@@ -283,9 +284,12 @@ Output on success:
consistency proof of zero or more node hashes. The order of node
hashes follow from the hash strategy, see RFC 6962.
+Example: `echo "new_size=4711
+old_size=42" | curl --data-binary @- localhost/st/v0/get-consistency-proof`
+
### get-leaves
```
-GET <base url>/st/v0/get-leaves
+POST <base url>/st/v0/get-leaves
```
Input:
@@ -306,12 +310,15 @@ value in each list refers to the first leaf, the second value in each
list refers to the second leaf, etc. The size of each list must
match.
-The log may return fewer leaves than requested. At least one leaf
+A log may return fewer leaves than requested. At least one leaf
must be returned on HTTP status code 200 OK.
+Example: `echo "start_size=42
+end_size=4711" | curl --data-binary @- localhost/st/v0/get-leaves`
+
### add-leaf
```
-GET <base url>/st/v0/add-leaf
+POST <base url>/st/v0/add-leaf
```
Input:
@@ -337,11 +344,11 @@ match a hash over `verification_key`.
The submission may also not be accepted if the second-level domain
name exceeded its rate limit. By coupling every add-leaf request to
-a second-level domain, it becomes more difficult to spam the log. You
+a second-level domain, it becomes more difficult to spam logs. You
would need an excessive number of domain names. This becomes costly
if free domain names are rejected.
-The log does not publish domain-name to key bindings because key
+Logs don't publish domain-name to key bindings because key
management is more complex than that.
Public logging should not be assumed to have happened until an
@@ -349,9 +356,15 @@ inclusion proof is available. An inclusion proof should not be relied
upon unless it leads up to a trustworthy signed tree head. Witness
cosigning can make a tree head trustworthy.
+Example: `echo "shard_hint=1640995200
+checksum=cfa2d8e78bf273ab85d3cef7bde62716261d1e42626d776f9b4e6aae7b6ff953
+signature_over_message=c026687411dea494539516ee0c4e790c24450f1a4440c2eb74df311ca9a7adf2847b99273af78b0bda65dfe9c4f7d23a5d319b596a8881d3bc2964749ae9ece3
+verification_key=c9a674888e905db1761ba3f10f3ad09586dddfe8581964b55787b44f318cbcdf
+domain_hint=example.com" | curl --data-binary @- localhost/st/v0/add-leaf`
+
### add-cosignature
```
-GET <base url>/st/v0/add-cosignature
+POST <base url>/st/v0/add-cosignature
```
Input:
@@ -364,17 +377,22 @@ Input:
Output on success:
- None
-`key_hash` can be used to identify which witness signed the log's tree
+`key_hash` can be used to identify which witness signed the tree
head. A key-hash, rather than the full verification key, is used to
motivate verifiers to locate the appropriate key and make an explicit
trust decision.
+Example: `echo "signature=d1b15061d0f287847d066630339beaa0915a6bbb77332c3e839a32f66f1831b69c678e8ca63afd24e436525554dbc6daa3b1201cc0c93721de24b778027d41af
+key_hash=662ce093682280f8fbea9939abe02fdba1f0dc39594c832b411ddafcffb75b1d" | curl --data-binary @- localhost/st/v0/add-cosignature`
+
## Summary of log parameters
-- **Public key**: an Ed25519 verification key that can be used to
- verify the log's tree head signatures.
-- **Log identifier**: the hashed public verification key using SHA256.
-- **Shard interval**: the time during which the log accepts logging
- requests. The shard interval's start and end are inclusive and
- expressed as the number of seconds since the UNIX epoch.
-- **Base URL**: where the log can be reached over HTTP(S). It is the
- prefix before a version-0 specific endpoint.
+- **Public key**: The Ed25519 verification key to be used for
+ verifying tree head signatures.
+- **Log identifier**: The public verification key `Public key` hashed
+ using SHA256.
+- **Shard interval start**: The earliest time at which logging
+ requests are accepted as the number of seconds since the UNIX epoch.
+- **Shard interval end**: The latest time at which logging
+ requests are accepted as the number of seconds since the UNIX epoch.
+- **Base URL**: Where the log can be reached over HTTP(S). It is the
+ prefix to be used to construct a version 0 specific endpoint.