-
Notifications
You must be signed in to change notification settings - Fork 13
Description
Operating systems often ship a list of trusted certificates in a well-known location. The go source code is a nice place for an overview of where Linux stores its trusted roots. It might be nice to recommend a file structure as part of the RFC as well.
Relying Party
I propose the following structure for a relying party, mainly inspired by Debian/Ubuntu:
etc
└─ ssl
└─ mtc
└─ <issuer_id>
├─ ca-params
├─ validity-window
└─ signature
I think the prefix of the storage location may be different per distribution. For example, etc/ssl/mtc for Debian and /etc/pki/tls/mtc for Fedora/RHEL. What is more interesting is the structure thereafter.
Each CA would live in its own subdirectory with the Issuer ID (i.e., TAI/OID) as the directory name. This directory contains the CA parameters, the root hashes of the validity window, and optionally the signature over the validity window. The CA parameters would be the following binary representation:
struct {
TrustAnchorIdentifier issuer;
SignatureScheme signature_scheme;
opaque public_key<1..2^16-1>;
ProofType proof_type;
uint64 start_time;
uint64 batch_duration;
uint64 lifetime;
uint32 validity_window_size;
uint64 storage_window_size;
opaque http_server<1..2^16-1>;
}
The validity window would contain the batch number and all currently valid root hashes, like defined in the draft already:
struct {
uint32 batch_number;
TreeHead tree_heads[validity_window_size*hash.length];
} ValidityWindow;
The signature seems optional to me. If the relying party trusts its trust services, there might not be a need to sync them as well.
This would also save quite some bandwidth, depending on how often an RP gets updated and how many CAs exist.
That is also the reason I would like to have the signature and validity window separate, as it simplifies the update service to fetch only the missing tree heads and optionally the signature.
For the CA parameters, I am not sure if all information is actually required on the RP side. At the same time, the size is not very important here, as it would get updated only occasionally. Mainly, either the validity window size or lifetime might be left out, and the HTTP server location of the CA might be irrelevant as updates should get fetched from the transparency services.
Authenticating Party
For the authenticating party, a common structure does not seem as relevant; still, it might be nice to recommend one:
I propose to store the certificates the server can choose from as <batch_number>.mtc in separate files and reuse the same format as for the RP for the CA parameters. To my understanding, the CA parameters are only required to know when a certificate becomes invalid, but keeping the other information in the struct allows reusing a parser that was written for the RP.
The private key is necessary to authenticate the handshake. It may be stored somewhere else as well.
<some directory>
└─ <issuer_id>
├─ 0.mtc
├─ 240.mtc
├─ ca-params
└─ private-key.pem
Any comments on the proposed structure, as well as the need to include this as a recommendation, are welcome.