diff options
| author | Rasmus Dahlberg <rasmus.dahlberg@kau.se> | 2021-05-31 13:35:36 +0200 | 
|---|---|---|
| committer | Rasmus Dahlberg <rasmus.dahlberg@kau.se> | 2021-05-31 13:35:36 +0200 | 
| commit | 4a9eddf4d45391c060a67f4464e4c0136aeaad21 (patch) | |
| tree | 47cdb05951119a7feb8f5810e6aa8a5530b3052a | |
| parent | f3465d2088f54e49c4939137116d23e5e26c3d22 (diff) | |
| parent | fe2e20f346e5f8a66c92016d77f32241498b790e (diff) | |
Merge branch 'design' of github.com:system-transparency/stfe into design
| -rw-r--r-- | doc/api.md | 114 | 
1 files changed, 66 insertions, 48 deletions
| @@ -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. | 
