@@ -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
## Motivation
215
157
@@ -289,15 +231,6 @@ Rationales for specific decisions:
289
231
payloadType were not signed.
290
232
- Also, URIs don't need to be registered while Media Types do.
291
233
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
-
301
234
- Why not stay backwards compatible by requiring the payload to always be JSON
302
235
with a "_ type" field? Then if you want a non-JSON payload, you could simply
303
236
have a field that contains the real payload, e.g. `{"_ type":"my-thing",
@@ -314,48 +247,6 @@ Rationales for specific decisions:
314
247
2 . It would incur double base64 encoding overhead for non-JSON payloads.
315
248
3 . It is more complex than PAE.
316
249
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
-
359
250
## Testing
360
251
361
252
See [ reference implementation] ( reference_implementation.ipynb ) . Here is an
@@ -406,7 +297,6 @@ Signed wrapper:
406
297
- [ JWS]
407
298
- [ PASETO]
408
299
409
- [ backwards compatible signature ] : #backwards-compatible-signatures
410
300
[ Canonical JSON ] : http://wiki.laptop.org/go/Canonical_JSON
411
301
[ in-toto ] : https://in-toto.io
412
302
[ JWS ] : https://tools.ietf.org/html/rfc7515
0 commit comments