Skip to content

Commit abe4661

Browse files
committed
Remove backwards compatibility mode.
This mode allowed for the old signature protocol to be represented in the new data structure. However, there was no known use case for this. True backwards compatibility requires supporting both protocol *and* data structure. Thus, backwards compatibility can be handled at the application (TUF or in-toto). Fixes #14.
1 parent 6be03cf commit abe4661

File tree

1 file changed

+7
-117
lines changed

1 file changed

+7
-117
lines changed

specification.md

Lines changed: 7 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ This document proposes a new signature scheme for use by, among others, the
1313
[in-toto] and [TUF] projects. This signature scheme (a) avoids relying on
1414
canonicalization for security and (b) reduces the possibility of
1515
misinterpretation of the payload. The serialized payload is encoded as a string
16-
and verified by the recipient _before_ deserializing. A backwards compatible
17-
variant is available.
16+
and verified by the recipient _before_ deserializing.
1817

1918
## Overview
2019

@@ -40,14 +39,13 @@ The signature format is a JSON message of the following form:
4039
```
4140

4241
Empty fields may be omitted. [Multiple signatures](#multiple-signatures) are
43-
allowed. Note that an optional `signature.sigType` field may be present but
44-
empty for compatibility with [backwards compatible signature] mode.
42+
allowed.
4543

4644
Parameters:
4745

4846
* SERIALIZED_BODY is the byte sequence to be signed.
4947

50-
* PAYLOAD_TYPE is an authenticated(*) URI indicating how to interpret
48+
* PAYLOAD_TYPE is an authenticated URI indicating how to interpret
5149
SERIALIZED_BODY. It encompasses the content type (JSON, Canonical-JSON,
5250
CBOR, etc.), the purpose, and the schema version of the payload. This
5351
obviates the need for the `_type` field within [in-toto]/[TUF] payloads.
@@ -59,9 +57,6 @@ Parameters:
5957
- https://theupdateframework.com/Root/v1.0.5
6058
- etc...
6159

62-
(*) Exception: PAYLOAD_TYPE is unauthenticated if `signature.sigType ==
63-
"raw-json-no-payload-type"`.
64-
6560
* KEYID is an optional, unauthenticated hint indicating what key and algorithm
6661
was used to sign the message. As with Sign(), details are agreed upon
6762
out-of-band by the signer and verifier. It **MUST NOT** be used for security
@@ -95,7 +90,6 @@ Functions:
9590
Out of band:
9691
9792
- Agree on a PAYLOAD_TYPE and cryptographic details.
98-
- Decide if [backwards compatible signature] mode should be allowed.
9993
10094
To sign:
10195
@@ -109,9 +103,6 @@ To sign:
109103
110104
To verify:
111105
112-
- If `sigType == "raw-json-no-payload-type"`, use
113-
[backwards compatible signature] instead. Reject if `sigType` is any other
114-
non-empty value.
115106
- Base64-decode `payload`; call this SERIALIZED_BODY. Reject if the decoding
116107
fails.
117108
- Base64-decode `sig` and verify PAE(UTF8(PAYLOAD_TYPE), SERIALIZED_BODY).
@@ -123,57 +114,6 @@ To verify:
123114
Either standard or URL-safe base64 encodings are allowed. Signers may use
124115
either, and verifiers **MUST** accept either.
125116
126-
### Backwards compatible signatures
127-
128-
To convert existing signatures from the current format to the new format,
129-
`"raw-json-no-payload-type"` is added to the payload type URI to indicate that
130-
the signature is over the raw payload. This allows the signatures to remain
131-
valid while avoiding the verifier from having to use [Canonical JSON].
132-
133-
```json
134-
{
135-
"payload": "<Base64(SERIALIZED_BODY)>",
136-
"signatures" : [{
137-
"keyid": "<KEYID>",
138-
"sigType": "raw-json-no-payload-type",
139-
"sig" : "<Base64(Sign(SERIALIZED_BODY))>"
140-
}]
141-
}
142-
```
143-
144-
Support for this backwards compatibility mode is optional and should be disabled
145-
by default.
146-
147-
To sign:
148-
149-
- The message **MUST** be an object type (`{...}`).
150-
- Serialize the message as [Canonical JSON]; call this SERIALIZED_BODY.
151-
- Sign SERIALIZED_BODY, base64-encode the result, and store it in `sig`.
152-
- Store `"raw-json-no-payload-type"` in `sigType`.
153-
- Optionally, compute a KEYID and store it in `keyid`.
154-
- Base64-encode SERIALIZED_BODY and store it in `payload`.
155-
156-
To verify:
157-
158-
- If `sigType != "raw-json-no-payload-type"`, use the
159-
[normal verification process](#steps) instead of this one.
160-
- Base64-decode `payload`; call this SERIALIZED_BODY. Reject if the decoding
161-
fails.
162-
- Base64-decode `sig` and verify SERIALIZED_BODY. Reject if either the
163-
decoding or the signature verification fails.
164-
- Parse SERIALIZED_BODY as a JSON object. Reject if the parsing fails or if
165-
the result is not a JSON object. In particular, the first byte of
166-
SERIALIZED_BODY **MUST** be `{`. Verifiers **MUST NOT** require
167-
SERIALIZED_BODY to be Canonical JSON.
168-
- Discard `payloadType` if present.
169-
170-
Backwards compatible signatures are not recommended because they lack the
171-
authenticated payloadType indicator.
172-
173-
This scheme is safe from rollback attacks because the first byte of
174-
SERIALIZED_BODY is 0x7b (`{`) in backwards compatibility mode and 0x02 in
175-
regular mode.
176-
177117
### Multiple signatures
178118
179119
A file may have more than one signature, which is equivalent to separate files
@@ -208,8 +148,10 @@ do so in the future.
208148

209149
### Differentiating between old and new formats
210150

211-
Verifiers can differentiate between the old and new wrapper format by detecting
212-
the presence of the `payload` field vs `signed` field.
151+
Verifiers can differentiate between the
152+
[old](https://github.com/in-toto/docs/blob/master/in-toto-spec.md#42-file-formats-general-principles)
153+
and new wrapper format by detecting the presence of the `payload` field (new
154+
format) vs `signed` field (old format).
213155

214156
## Motivation
215157

@@ -289,15 +231,6 @@ Rationales for specific decisions:
289231
payloadType were not signed.
290232
- Also, URIs don't need to be registered while Media Types do.
291233

292-
- Why use payloadType "raw-json-no-payload-type" instead of assuming backwards
293-
compatible mode if payloadType is absent?
294-
295-
- We wanted to leave open the possibility of having an
296-
application-specific "default" value if payloadType is unspecified,
297-
rather than forcing the default to be backwards compatibility mode.
298-
- Note that specific applications can still choose backwards compatibility
299-
to be the default.
300-
301234
- Why not stay backwards compatible by requiring the payload to always be JSON
302235
with a "_type" field? Then if you want a non-JSON payload, you could simply
303236
have a field that contains the real payload, e.g. `{"_type":"my-thing",
@@ -314,48 +247,6 @@ Rationales for specific decisions:
314247
2. It would incur double base64 encoding overhead for non-JSON payloads.
315248
3. It is more complex than PAE.
316249

317-
## Backwards compatibility with existing TUF and in-toto signatures
318-
319-
### Current format
320-
321-
The
322-
[old signature format](https://github.com/in-toto/docs/blob/master/in-toto-spec.md#42-file-formats-general-principles)
323-
used by [TUF] and [in-toto] has a BODY that is a regular JSON object and a
324-
signature over the [Canonical JSON] serialization of BODY.
325-
326-
```json
327-
{
328-
"signed": <BODY>,
329-
"signatures": [{
330-
"keyid": "<KEYID>",
331-
"sig": "<Hex(Sign(CanonicalJson(BODY)))>"
332-
}]
333-
}
334-
```
335-
336-
To verify, the consumer parses the whole JSON file, re-serializes BODY using
337-
Canonical JSON, then verifies the signature.
338-
339-
### Detect if a document is using old format
340-
341-
To detect whether a signature is in the old or new format:
342-
343-
- If it contains a `payload` field, assume it is in the new format.
344-
- If it contains a `signed` field, assume it is in the old format.
345-
346-
To convert an existing signature to the new format:
347-
348-
- `new.payload = base64encode(CanonicalJson(orig.signed))`
349-
- `new.signatures[*].sigType = "raw-json-no-payload-type"`
350-
- `new.signatures[*].sig = base64encode(hexdecode(orig.signatures[*].sig))`
351-
- `new.signatures[*].keyid = orig.signatures[*].keyid`
352-
353-
To convert a [backwards compatible signature] to the old format:
354-
355-
- `old.signed = jsonparse(base64decode(new.payload))`
356-
- `old.signatures[*].sig = hexencode(base64decode(new.signatures[*].sig))`
357-
- `old.signatures[*].keyid = new.signatures[*].keyid`
358-
359250
## Testing
360251

361252
See [reference implementation](reference_implementation.ipynb). Here is an
@@ -406,7 +297,6 @@ Signed wrapper:
406297
- [JWS]
407298
- [PASETO]
408299

409-
[backwards compatible signature]: #backwards-compatible-signatures
410300
[Canonical JSON]: http://wiki.laptop.org/go/Canonical_JSON
411301
[in-toto]: https://in-toto.io
412302
[JWS]: https://tools.ietf.org/html/rfc7515

0 commit comments

Comments
 (0)