diff --git a/POUFs/reference-POUF/pouf1.md b/POUFs/reference-POUF/pouf1.md index b4b8c67a..fb0b3d85 100644 --- a/POUFs/reference-POUF/pouf1.md +++ b/POUFs/reference-POUF/pouf1.md @@ -1,11 +1,11 @@ * POUF: 1 -* Title: Reference Implementation Using Canonical JSON -* Version: 2 -* Last-Modified: 06-May-2020 +* Title: Reference Implementation Using Canonical JSON and DSSE +* Version: 3 +* Last-Modified: 21-Jun-2021 * Author: Marina Moore, Joshua Lock * Status: Draft * TUF Version Implemented: 1.0 -* Implementation Version(s) Covered: v0.12.* +* Implementation Version(s) Covered: TODO * Content-Type: text/markdown * Created: 25-November-2018 @@ -14,7 +14,7 @@ This POUF describes the protocol, operations, usage, and formats for the TUF ref The reference implementation includes all required features of the TUF standard, as well as many of the optional features as a reference for anyone wishing to implement TUF. The implementation uses Canonical JSON encoding. -This version of the POUF covers v0.12.* of the reference implementation and has been updated to reflect that: snapshot.json only lists targets metadata (top-level and delegated), and timestamp.json includes hashes and length in METAFILES. +This version of the POUF covers v0.12.* of the reference implementation and has been updated to reflect that: snapshot.json only lists targets metadata (top-level and delegated), and timestamp.json includes hashes and length in METAFILES. TODO: update this bit # Protocol @@ -67,19 +67,22 @@ The following steps must be completed before any updates can be installed: # Formats ## General Principals -All signed metadata objects have the format: - - { "signed" : ROLE, - "signatures" : [ - { "keyid" : KEYID, - "sig" : SIGNATURE } - , ... ] +All signed metadata use v1 of [Dead Simple Signing Envelope (DSSE)](https://github.com/secure-systems-lab/dsse): + + { + "payload": "", + "payloadType": "", + "signatures": [{ + "keyid": "", + "sig": "" + }] } - where: - * ROLE is a dictionary whose "_type" field describes the role type. + * SERIALIZED_BODY is a dictionary whose "_type" field describes the role type. + + * PAYLOAD_TYPE is fixed as "application/vnd.tuf.pouf1+json" identifying it as TUF metadata. * KEYID is the identifier of the key signing the ROLE dictionary. @@ -400,13 +403,79 @@ matching paths will only be tried if downloading from earlier mirrors fails. This behavior can be modified by the client code that uses the framework to, for example, randomly select from the listed mirrors. +# Transitioning from the old signature wrapper + +The shift to DSSE as the signature wrapper for TUF metadata generated by the +reference implementation is backwards incompatible. There may be scenarios where +clients are unable to immediately move to the new style of metadata. In such +situations, +[TAP-14](https://github.com/theupdateframework/taps/blob/master/tap14.md), +authored by Marina Moore, can be leveraged until clients are updated with +support for DSSE metadata. + +On the other hand, in situations where clients can be easily updated but +repositories cannot, the clients must process the document as follows: + +Inputs: + +* `file`: JSON-encoded TUF document +* `recognizedSigners`: collection of (`name`, `publicKey`) pairs + +Outputs: + +* `message`: the signed message as an implementation-language-specific object +* `signers`: set of recognized names that have signed the message + +Steps: + +* `envelope` := JsonDecode(`file`); raise error if the decoding fails +* If `envelope.payload` exists (new-style envelope): + * If `payloadType` != `application/vnd.tuf.pouf1+json`, raise error + * `preauthEncoding` := PAE(UTF8(`envelope.payloadType`), + `envelope.payload`) as per + [DSSE](https://github.com/secure-systems-lab/dsse/blob/master/protocol.md#signature-definition) + * `signers` := set of `name` for which Verify(`preauthEncoding`, + `signature.sig`, `publicKey`) succeeds, for all combinations of + (`signature`) in `envelope.signatures` and (`name`, `publicKey`) in + `recognizedSigners` + * `message` := JsonDecode(`envelope.payload`) +* Else if `envelope.signed` exists (old-style envelope): + * `preauthEncoding` := CanonicalJsonEncode(`envelope.signed`) + * `signers` := set of `name` for which Verify(`preauthEncoding`, + `signature.sig`, `publicKey`) succeeds, for all combinations of + (`signature`) in `envelope.signatures` and (`name`, `publicKey`) in + `recognizedSigners` + * `message` := `envelope.signed` +* Else, raise error +* Raise error if `signers` is empty +* Return `message` and `signers` + +Note: This workflow was authored by Mark Lodato (@MarkLodato) for in-toto. # Security Audit -This profile was included in TUF security audits available at https://theupdateframework.github.io/audits.html. +This profile was included in TUF security audits available at https://theupdateframework.github.io/audits.html. TODO: the new wrapper has not been audited # Version History +## 3 +Update to propose a transition to using DSSE as the underlying signature wrapper for TUF metadata. + ## 2 Updated to reflect the latest (v0.12.2) reference implementation. * snapshot.json lists only the top-level and delegated targets metadata * timestamp.json includes hashes and length of snapshot.json + { "signed" : ROLE, + "signatures" : [ + { "keyid" : KEYID, + "sig" : SIGNATURE } + , ... ] + } + + + where: + + * ROLE is a dictionary whose "_type" field describes the role type. + + * KEYID is the identifier of the key signing the ROLE dictionary. + + * SIGNATURE is a hex-encoded signature of the canonical JSON form of ROLE.