1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
# System Transparency Log
This document provides a sketch of System Transparency (ST) logging. The basic
idea is to insert hashes of system artifacts into a public, append-only, and
tamper-evident transparency log, such that any enforcing client can be sure that
they see the same system artifacts as everyone else. A system artifact could
be an operating system image, a Debian package, or generally just a checksum of
something opaque.
An ST log can be implemented on-top of
[Trillian](https://trillian.transparency.dev) using a custom STFE personality.
For reference you may look at Certificate Transparency (CT) logging and
[CTFE](https://github.com/google/certificate-transparency-go/tree/master/trillian/ctfe),
which implements [RFC 6962](https://tools.ietf.org/html/rfc6962).
We reuse RFC 6962 and its follow-up specification [RFC
6962/bis](https://datatracker.ietf.org/doc/draft-ietf-trans-rfc6962-bis/) to the
largest extent possible.
## Log parameters
A log is defined by the following immutable parameters:
- Log identifier: a unique identifier
- Public key: a unique public key
- Base URL: where can this log be reached? E.g., example.com:1234/log
- Hash algorithm: e.g., SHA256
- Signature algorithm: e.g., ECDSA on a given curve.
Note that **there is no MMD**. The idea is to merge added entries as soon as
possible, and no client should trust that something is logged until an inclusion
proof can be provided that references a trustworthy STH.
## Minimum acceptance criteria
A log should accept a submission if it is:
- Well-formed, see below.
- Digitally signed
- Proves who submitted an entry for logging
- The signing key must chain back to a valid trust anchor
## Data structure definitions
We encode everything that is digitally signed as in [RFC
5246](https://tools.ietf.org/html/rfc5246). Therefore, we use the same
description language for our data structures. A definition of the log's Merkle
tree can be found in RFC 6962, see
[§2](https://tools.ietf.org/html/rfc6962#section-2).
### Repurposing `TransItem` as `Item`
A general-purpose `TransItem` is defined by RFC 6962/bis. Below we define our
own `TransItem`, but name it `Item` to emphasize that they are not the same.
Some definitions are re-used and others are added.
```
enum {
reserved(0),
signed_tree_head_v1(1), // defined in RFC 6962/bis, §4.10
signed_debug_info_v1(2), // defined below, think "almost SCT"
consistency_proof_v1(3), // defined in RFC 6962/bis, §4.11
inclusion_proof_v1(4), // defined in RFC 6962/bis, §4.12
leaf_checksum_v1(5), // defined below, think "leaf data"
(65535)
} Format;
struct {
Format format;
select (format) {
case signed_tree_head_v1: SignedTreeHeadV1;
case signed_debug_info_v1: SignedDebugInfoV1;
case consistency_proof_v1: ConsistencyProofV1;
case inclusion_proof_v1: InclusionProofV1;
case leaf_checksum_v1: LeafChecksumV1;
} message;
} Item;
```
An `Item` can be serialized into an `ItemList` as described in RFC 6962/bis, see
[§6.2](https://datatracker.ietf.org/doc/html/draft-ietf-trans-rfc6962-bis-34#section-6.2).
### Merkle tree leaf types
In the future there will likely be several types of leaves. Say, one for
operating system packages, another one for Debian packages, and a third one for
general-purpose checksums. For now we only define the latter.
#### Checksum
A checksum entry contains a timestamp that corresponds to `UTC.now()`, a package
identifier such as `foobar-1.2.3`, and an artifact hash that uses the log's
configured hash function. An entry must be signed by the submitter to be
accepted by the log, and the resulting signature is part of the leaf's Appendix.
```
struct {
uint64 timestamp; // format defined by RFC 6962/bis, added by submitter
opaque package<0..2^8-1>; // package identifier
opaque checksum<32..2^8-1>; // artifact hash that used the log's hash func
} LeafChecksumV1;
```
For example, the checksum type could be used by Firefox to [enforce public
binary logging before accepting a new software
update](https://wiki.mozilla.org/Security/Binary_Transparency). It is assumed
that the entities relying on the checksum type know how to find the artifact
source (if not already at hand) and then reproduce the logged hash from it.
Note that the entry timestamp allows anyone to derive rough statistics on the
time between submission and merge into the log's Merkle tree. Base such a diff
on the first STH (timestamp) that incorporated a given entry.
### Signed Debug Info
RFC 6962 uses Signed Certificate Timestamps (SCTs) as promises of public
logging within a time known as the Maximum Merge Delay (MMD). We provide no
such promise: a Signed Debug Info (SDI) is an intent to log because the
submitter is authorized to do so and the entry appears to be valid. It will be
merged into the log's Merkle tree as soon as possible on a best-effort basis.
If an unexpected delay is encountered, the submitter can present the issued SFI
to the log operator (who can then investigate the underlying reason further).
```
struct {
LogID log_id; // defined in RFC 6962
opaque message<0..2^16-1> // debug string that is only meant for the log
opaque signature; // computed by the log over LeafChecksumV1
} SignedDebugInfoV1;
```
## Public endpoints
Clients talk to the log with HTTPS GET/POST requests as in RFC 6962,
[§4](https://tools.ietf.org/html/rfc6962#section-4). Namely, POST parameters
are JSON objects, GET parameters are URL encoded, and binary data is first
expressed as base-64.
### add-checksum
### get-entries
### get-trust-anchors
### get-proof-by-hash
### get-consistency-proof
### get-sth
|