@@ -13,8 +13,7 @@ This document proposes a new signature scheme for use by, among others, the
13
13
[ in-toto] and [ TUF] projects. This signature scheme (a) avoids relying on
14
14
canonicalization for security and (b) reduces the possibility of
15
15
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.
18
17
19
18
## Overview
20
19
@@ -40,14 +39,13 @@ The signature format is a JSON message of the following form:
40
39
```
41
40
42
41
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.
45
43
46
44
Parameters:
47
45
48
46
* SERIALIZED_BODY is the byte sequence to be signed.
49
47
50
- * PAYLOAD_TYPE is an authenticated( * ) URI indicating how to interpret
48
+ * PAYLOAD_TYPE is an authenticated URI indicating how to interpret
51
49
SERIALIZED_BODY. It encompasses the content type (JSON, Canonical-JSON,
52
50
CBOR, etc.), the purpose, and the schema version of the payload. This
53
51
obviates the need for the ` _type ` field within [ in-toto] /[ TUF] payloads.
@@ -59,9 +57,6 @@ Parameters:
59
57
- https://theupdateframework.com/Root/v1.0.5
60
58
- etc...
61
59
62
- (* ) Exception: PAYLOAD_TYPE is unauthenticated if `signature.sigType ==
63
- "raw-json-no-payload-type"`.
64
-
65
60
* KEYID is an optional, unauthenticated hint indicating what key and algorithm
66
61
was used to sign the message. As with Sign(), details are agreed upon
67
62
out-of-band by the signer and verifier. It ** MUST NOT** be used for security
@@ -95,7 +90,6 @@ Functions:
95
90
Out of band:
96
91
97
92
- Agree on a PAYLOAD_TYPE and cryptographic details.
98
- - Decide if [backwards compatible signature] mode should be allowed.
99
93
100
94
To sign:
101
95
@@ -109,9 +103,6 @@ To sign:
109
103
110
104
To verify:
111
105
112
- - If `sigType == "raw-json-no-payload-type"`, use
113
- [backwards compatible signature] instead. Reject if `sigType` is any other
114
- non-empty value.
115
106
- Base64-decode `payload`; call this SERIALIZED_BODY. Reject if the decoding
116
107
fails.
117
108
- Base64-decode `sig` and verify PAE(UTF8(PAYLOAD_TYPE), SERIALIZED_BODY).
@@ -123,57 +114,6 @@ To verify:
123
114
Either standard or URL-safe base64 encodings are allowed. Signers may use
124
115
either, and verifiers **MUST** accept either.
125
116
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
-
177
117
### Multiple signatures
178
118
179
119
A file may have more than one signature, which is equivalent to separate files
@@ -208,8 +148,10 @@ do so in the future.
208
148
209
149
### Differentiating between old and new formats
210
150
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).
213
155
214
156
## Design considerations
215
157
@@ -315,15 +257,6 @@ Rationales for specific decisions:
315
257
payloadType were not signed.
316
258
- Also, URIs don't need to be registered while Media Types do.
317
259
318
- - Why use payloadType "raw-json-no-payload-type" instead of assuming backwards
319
- compatible mode if payloadType is absent?
320
-
321
- - We wanted to leave open the possibility of having an
322
- application-specific "default" value if payloadType is unspecified,
323
- rather than forcing the default to be backwards compatibility mode.
324
- - Note that specific applications can still choose backwards compatibility
325
- to be the default.
326
-
327
260
- Why not stay backwards compatible by requiring the payload to always be JSON
328
261
with a "_ type" field? Then if you want a non-JSON payload, you could simply
329
262
have a field that contains the real payload, e.g. `{"_ type":"my-thing",
@@ -340,47 +273,14 @@ Rationales for specific decisions:
340
273
2 . It would incur double base64 encoding overhead for non-JSON payloads.
341
274
3 . It is more complex than PAE.
342
275
343
- ## Backwards compatibility with existing TUF and in-toto signatures
344
-
345
- ### Current format
346
-
347
- The
348
- [ old signature format] ( https://github.com/in-toto/docs/blob/master/in-toto-spec.md#42-file-formats-general-principles )
349
- used by [ TUF] and [ in-toto] has a BODY that is a regular JSON object and a
350
- signature over the [ Canonical JSON] serialization of BODY.
351
-
352
- ``` json
353
- {
354
- "signed" : <BODY>,
355
- "signatures" : [{
356
- "keyid" : " <KEYID>" ,
357
- "sig" : " <Hex(Sign(CanonicalJson(BODY)))>"
358
- }]
359
- }
360
- ```
361
-
362
- To verify, the consumer parses the whole JSON file, re-serializes BODY using
363
- Canonical JSON, then verifies the signature.
364
-
365
- ### Detect if a document is using old format
366
-
367
- To detect whether a signature is in the old or new format:
368
-
369
- - If it contains a ` payload ` field, assume it is in the new format.
370
- - If it contains a ` signed ` field, assume it is in the old format.
371
-
372
- To convert an existing signature to the new format:
373
-
374
- - ` new.payload = base64encode(CanonicalJson(orig.signed)) `
375
- - ` new.signatures[*].sigType = "raw-json-no-payload-type" `
376
- - ` new.signatures[*].sig = base64encode(hexdecode(orig.signatures[*].sig)) `
377
- - ` new.signatures[*].keyid = orig.signatures[*].keyid `
378
-
379
- To convert a [ backwards compatible signature] to the old format:
276
+ ## Backwards Compatibility
380
277
381
- - ` old.signed = jsonparse(base64decode(new.payload)) `
382
- - ` old.signatures[*].sig = hexencode(base64decode(new.signatures[*].sig)) `
383
- - ` old.signatures[*].keyid = new.signatures[*].keyid `
278
+ Backwards compatibility with the old format will be handled by the application
279
+ and explained in the corresponding application-specific change proposal, namely
280
+ [ ITE-5] ( https://github.com/in-toto/ITE/pull/13 ) for in-toto and via the
281
+ principles laid out in
282
+ [ TAP-14] ( https://github.com/theupdateframework/taps/blob/master/tap14.md ) for
283
+ TUF.
384
284
385
285
## Testing
386
286
@@ -432,7 +332,6 @@ Signed wrapper:
432
332
- [ JWS]
433
333
- [ PASETO]
434
334
435
- [ backwards compatible signature ] : #backwards-compatible-signatures
436
335
[ Canonical JSON ] : http://wiki.laptop.org/go/Canonical_JSON
437
336
[ in-toto ] : https://in-toto.io
438
337
[ JWS ] : https://tools.ietf.org/html/rfc7515
0 commit comments