Skip to content

Commit b25be06

Browse files
committed
Fully specify all encodings.
* Specify that payload type is encoded as UTF-8 when passed to PAE. Previously this was ambiguous since PAYLOAD_TYPE was a unicode string while the `type` parameter of PAE() required a byte sequence. * Clarify that SERIALIZED_BODY is a byte sequence. * Spell out what Sign(), UTF8(), and Base64() are. Closes #3.
1 parent 828795f commit b25be06

File tree

1 file changed

+41
-24
lines changed

1 file changed

+41
-24
lines changed

specification.md

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,63 +15,81 @@ misinterpretation of the payload. The serialized payload is encoded as a string
1515
and verified by the recipient _before_ deserializing. A backwards compatible
1616
variant is available.
1717

18-
## Specification
18+
## Overview
1919

2020
$signing_spec does not rely on Canonical JSON, nor any other canonicalization
2121
scheme. Instead, the producer records the signed bytes exactly as signed and the
2222
consumer verifies those exact bytes before parsing. In addition, the signature
2323
now includes an authenticated `payloadType` field indicating how to interpret
2424
the payload.
2525

26+
## Specification
27+
28+
The signature format is a JSON message of the following form:
29+
2630
```json
2731
{
2832
"payload": "<Base64(SERIALIZED_BODY)>",
2933
"payloadType": "<PAYLOAD_TYPE>",
3034
"signatures": [{
3135
…,
32-
"sig": "<Base64(Sign(PAE([PAYLOAD_TYPE, SERIALIZED_BODY])))>"
36+
"sig": "<Base64(Sign(PAE([UTF8(PAYLOAD_TYPE), SERIALIZED_BODY])))>"
3337
}, ]
3438
}
3539
```
3640

37-
where PAE is the
38-
[PASETO Pre-Authentication Encoding](https://github.com/paragonie/paseto/blob/master/docs/01-Protocol-Versions/Common.md#authentication-padding):
41+
where:
3942

40-
```none
41-
PAE([type, body]) := le64(2) || le64(len(type)) || type || le64(len(body)) || body
42-
le64(n) := 64-bit little-endian encoding of `n`, where 0 <= n < 2^63
43-
```
43+
* SERIALIZED_BODY is the byte sequence to be signed.
4444

45-
The PAYLOAD_TYPE is a URI indicating how to interpret SERIALIZED_BODY. It
46-
encompasses the content type (JSON, Canonical-JSON, CBOR, etc.), the purpose,
47-
and the schema version of the payload. This obviates the need for the `_type`
48-
field within in-toto/TUF payloads. This URI does not need to be resolved to a
49-
remote resource, nor does such a resource need to be fetched. Examples:
45+
* PAYLOAD_TYPE is a URI indicating how to interpret SERIALIZED_BODY. It
46+
encompasses the content type (JSON, Canonical-JSON, CBOR, etc.), the
47+
purpose, and the schema version of the payload. This obviates the need for
48+
the `_type` field within in-toto/TUF payloads. This URI does not need to be
49+
resolved to a remote resource, nor does such a resource need to be fetched.
50+
Examples:
5051

51-
- https://in-toto.io/Link/v0.9
52-
- https://in-toto.io/Layout/v0.9
53-
- https://theupdateframework.com/Root/v1.0.5
54-
- etc...
52+
- https://in-toto.io/Link/v0.9
53+
- https://in-toto.io/Layout/v0.9
54+
- https://theupdateframework.com/Root/v1.0.5
55+
- etc...
5556

56-
The switch from Hex to Base64 for `sig` is to save space and to be consistent
57-
with `payload`.
57+
* PAE() is the
58+
[PASETO Pre-Authentication Encoding](https://github.com/paragonie/paseto/blob/master/docs/01-Protocol-Versions/Common.md#authentication-padding),
59+
where parameters `type` and `body` are byte sequences:
60+
61+
```none
62+
PAE([type, body]) := le64(2) || le64(len(type)) || type || le64(len(body)) || body
63+
le64(n) := 64-bit little-endian encoding of `n`, where 0 <= n < 2^63
64+
```
65+
66+
* Sign() is an arbitrary digital signature format. Details must be agreed upon
67+
out-of-band by the signer and verifier. This specification places no
68+
restriction on the signature algorithm or format.
69+
70+
* UTF8() is [UTF-8 encoding](https://tools.ietf.org/html/rfc3629),
71+
transforming a unicode string to a byte sequence.
72+
73+
* Base64() is [Base64 encoding](https://tools.ietf.org/html/rfc4648),
74+
transforming a byte sequence to a unicode string. Either standard or
75+
URL-safe encoding is allowed.
5876
5977
### Steps
6078
6179
To sign:
6280
6381
- Serialize BODY according to PAYLOAD_TYPE. Call the result SERIALIZED_BODY.
64-
- Sign PAE([PAYLOAD_TYPE, SERIALIZED_BODY]), base64-encode the result, and
65-
store it in `sig`.
82+
- Sign PAE([UTF8(PAYLOAD_TYPE), SERIALIZED_BODY]), base64-encode the result,
83+
and store it in `sig`.
6684
- Base64-encode SERIALIZED_BODY and store it in `payload`.
6785
- Store PAYLOAD_TYPE in `payloadType`.
6886
6987
To verify:
7088
7189
- Base64-decode `payload`; call this SERIALIZED_BODY. Reject if the decoding
7290
fails.
73-
- Base64-decode `sig` and verify PAE([PAYLOAD_TYPE, SERIALIZED_BODY]). Reject
74-
if either the decoding or the signature verification fails.
91+
- Base64-decode `sig` and verify PAE([UTF8(PAYLOAD_TYPE), SERIALIZED_BODY]).
92+
Reject if either the decoding or the signature verification fails.
7593
- Parse SERIALIZED_BODY according to PAYLOAD_TYPE. Reject if the parsing
7694
fails.
7795
@@ -336,4 +354,3 @@ Signed wrapper:
336354
- [Canonical JSON](http://wiki.laptop.org/go/Canonical_JSON)
337355
- [JWS](https://tools.ietf.org/html/rfc7515)
338356
- [PASETO](https://github.com/paragonie/paseto/blob/master/docs/01-Protocol-Versions/Version2.md#sig)
339-

0 commit comments

Comments
 (0)