Skip to content

Commit cb8467e

Browse files
committed
Merge branch 'master' into cleanups
2 parents f03d543 + e6ae241 commit cb8467e

File tree

1 file changed

+49
-15
lines changed

1 file changed

+49
-15
lines changed

specification.md

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,16 @@ The signature format is a JSON message of the following form:
3333
"payload": "<Base64(SERIALIZED_BODY)>",
3434
"payloadType": "<PAYLOAD_TYPE>",
3535
"signatures": [{
36-
,
36+
"keyid": "<KEYID>",
3737
"sig": "<Base64(Sign(PAE(UTF8(PAYLOAD_TYPE), SERIALIZED_BODY)))>"
38-
}, ]
38+
}]
3939
}
4040
```
4141

42-
where:
42+
Empty fields may be omitted. [Multiple signatures](#multiple-signatures) are
43+
allowed.
44+
45+
Parameters:
4346

4447
* SERIALIZED_BODY is the byte sequence to be signed.
4548

@@ -55,6 +58,14 @@ where:
5558
- https://theupdateframework.com/Root/v1.0.5
5659
- etc...
5760

61+
* KEYID is an optional, unauthenticated hint indicating what key and algorithm
62+
was used to sign the message. As with Sign(), details are agreed upon
63+
out-of-band by the signer and verifier. It **MUST NOT** be used for security
64+
decisions; it may only be used to narrow the selection of possible keys to
65+
try.
66+
67+
Functions:
68+
5869
* PAE() is the
5970
[PASETO Pre-Authentication Encoding](https://github.com/paragonie/paseto/blob/master/docs/01-Protocol-Versions/Common.md#authentication-padding),
6071
where parameters `type` and `body` are byte sequences:
@@ -64,7 +75,7 @@ where:
6475
le64(n) := 64-bit little-endian encoding of `n`, where 0 <= n < 2^63
6576
```
6677
67-
* Sign() is an arbitrary digital signature format. Details must be agreed upon
78+
* Sign() is an arbitrary digital signature format. Details are agreed upon
6879
out-of-band by the signer and verifier. This specification places no
6980
restriction on the signature algorithm or format.
7081
@@ -88,6 +99,7 @@ To sign:
8899
SERIALIZED_BODY.
89100
- Sign PAE(UTF8(PAYLOAD_TYPE), SERIALIZED_BODY), base64-encode the result, and
90101
store it in `sig`.
102+
- Optionally, compute a KEYID and store it in `keyid`.
91103
- Base64-encode SERIALIZED_BODY and store it in `payload`.
92104
- Store PAYLOAD_TYPE in `payloadType`.
93105
@@ -102,33 +114,34 @@ To verify:
102114
fails.
103115
104116
Either standard or URL-safe base64 encodings are allowed. Signers may use
105-
either, and verifiers must accept either.
117+
either, and verifiers **MUST** accept either.
106118
107119
### Backwards compatible signatures
108120
109121
To convert existing signatures from the current format to the new format,
110-
`"backwards-compatible-json"` must be added to the payload type URI to indicate
111-
that the signature is over the raw payload. This allows the signatures to remain
122+
`"backwards-compatible-json"` is added to the payload type URI to indicate that
123+
the signature is over the raw payload. This allows the signatures to remain
112124
valid while avoiding the verifier from having to use [Canonical JSON].
113125
114126
```json
115127
{
116128
"payload": "<Base64(CanonicalJson(BODY))>",
117129
"payloadType": "<URI>/backwards-compatible-json",
118130
"signatures" : [{
119-
,
120-
"sig" : "<Base64(Sign(CanonicalJson(BODY)))>"
121-
}, …]
131+
"keyid": "<KEYID>",
132+
"sig": "<Base64(Sign(CanonicalJson(BODY)))>"
133+
}]
122134
}
123135
```
124136

125137
Support for this backwards compatibility mode is optional.
126138

127139
To sign:
128140

129-
- BODY **must** be an object type (`{...}`).
141+
- BODY **MUST** be an object type (`{...}`).
130142
- Serialize BODY as [Canonical JSON]; call this SERIALIZED_BODY.
131143
- Sign SERIALIZED_BODY, base64-encode the result, and store it in `sig`.
144+
- Optionally, compute a KEYID and store it in `keyid`.
132145
- Base64-encode SERIALIZED_BODY and store it in `payload`.
133146
- Store `"<URI>/backwards-compatible-json"` in `payloadType`.
134147

@@ -142,16 +155,35 @@ To verify:
142155
decoding or the signature verification fails.
143156
- Parse SERIALIZED_BODY as a JSON object. Reject if the parsing fails or if
144157
the result is not a JSON object. In particular, the first byte of
145-
SERIALIZED_BODY must be `{`. Verifiers **must not** require SERIALIZED_BODY
158+
SERIALIZED_BODY **MUST** be `{`. Verifiers **MUST NOT** require SERIALIZED_BODY
146159
to be Canonical JSON.
147160

148161
Backwards compatible signatures are not recommended because they lack the
149162
authenticated payloadType indicator.
150163

151164
This scheme is safe from rollback attacks because the first byte of
152-
SERIALIZED_BODY must be 0x7b (`{`) in backwards compatibility mode and 0x02 in
165+
SERIALIZED_BODY is 0x7b (`{`) in backwards compatibility mode and 0x02 in
153166
regular mode.
154167

168+
### Multiple signatures
169+
170+
A file may have more than one signature, which is equivalent to separate files
171+
with individual signatures.
172+
173+
```json
174+
{
175+
"payload": "<Base64(SERIALIZED_BODY)>",
176+
"payloadType": "<PAYLOAD_TYPE>",
177+
"signatures": [{
178+
"keyid": "<KEYID_1>",
179+
"sig": "<SIG_1>"
180+
}, {
181+
"keyid": "<KEYID_2>",
182+
"sig": "<SIG_2>"
183+
}]
184+
}
185+
```
186+
155187
### Optional changes to wrapper
156188

157189
The standard wrapper is JSON with an explicit `payloadType`. Optionally,
@@ -286,9 +318,9 @@ over the [Canonical JSON] serialization of BODY.
286318
{
287319
"signed": <BODY>,
288320
"signatures": [{
289-
,
321+
"keyid": "<KEYID>",
290322
"sig": "<Hex(Sign(CanonicalJson(BODY)))>"
291-
}, ]
323+
}]
292324
}
293325
```
294326

@@ -307,11 +339,13 @@ To convert an existing signature to the new format:
307339
- `new.payload = base64encode(CanonicalJson(orig.signed))`
308340
- `new.payloadType = "<URI>/backwards-compatible-json"`
309341
- `new.signatures[*].sig = base64encode(hexdecode(orig.signatures[*].sig))`
342+
- `new.signatures[*].keyid = orig.signatures[*].keyid`
310343

311344
To convert a backwards compatible signature to the old format:
312345

313346
- `old.signed = jsonparse(base64decode(new.payload))`
314347
- `old.signatures[*].sig = hexencode(base64decode(new.signatures[*].sig))`
348+
- `old.signatures[*].keyid = new.signatures[*].keyid`
315349

316350
## Testing
317351

0 commit comments

Comments
 (0)