Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fully specify all fields within signatures #11

Merged
merged 7 commits into from
Dec 14, 2020
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 39 additions & 8 deletions specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@ The signature format is a JSON message of the following form:
"payload": "<Base64(SERIALIZED_BODY)>",
"payloadType": "<PAYLOAD_TYPE>",
"signatures": [{
,
"keyid": "<KEYID>",
"sig": "<Base64(Sign(PAE([UTF8(PAYLOAD_TYPE), SERIALIZED_BODY])))>"
}, …]
}]
}
```

where:
Empty fields may be omitted. [Multiple signatures](#multiple-signatures) are
allowed.

Parameters:

* SERIALIZED_BODY is the byte sequence to be signed.

Expand All @@ -54,6 +57,11 @@ where:
- https://theupdateframework.com/Root/v1.0.5
- etc...

* KEYID is an optional, unauthenticated hint indicating what key was used to
joshuagl marked this conversation as resolved.
Show resolved Hide resolved
sign the message. It **must not** be used for security decisions.
MarkLodato marked this conversation as resolved.
Show resolved Hide resolved

Functions:

* PAE() is the
[PASETO Pre-Authentication Encoding](https://github.com/paragonie/paseto/blob/master/docs/01-Protocol-Versions/Common.md#authentication-padding),
where parameters `type` and `body` are byte sequences:
Expand Down Expand Up @@ -81,6 +89,7 @@ To sign:
- Serialize BODY according to PAYLOAD_TYPE. Call the result SERIALIZED_BODY.
- Sign PAE([UTF8(PAYLOAD_TYPE), SERIALIZED_BODY]), base64-encode the result,
and store it in `sig`.
- Optionally, compute a KEYID and store it in `keyid`.
- Base64-encode SERIALIZED_BODY and store it in `payload`.
- Store PAYLOAD_TYPE in `payloadType`.

Expand Down Expand Up @@ -108,9 +117,9 @@ valid while avoiding the verifier from having to use [Canonical JSON].
"payload": "<Base64(CanonicalJson(BODY))>",
"payloadType": "<URI>/backwards-compatible-json",
"signatures" : [{
,
"sig" : "<Base64(Sign(CanonicalJson(BODY)))>"
}, …]
"keyid": "<KEYID>",
"sig": "<Base64(Sign(CanonicalJson(BODY)))>"
}]
}
```

Expand All @@ -121,6 +130,7 @@ To sign:
- BODY **must** be an object type (`{...}`).
- Serialize BODY as [Canonical JSON]; call this SERIALIZED_BODY.
- Sign SERIALIZED_BODY, base64-encode the result, and store it in `sig`.
- Optionally, compute a KEYID and store it in `keyid`.
MarkLodato marked this conversation as resolved.
Show resolved Hide resolved
- Base64-encode SERIALIZED_BODY and store it in `payload`.
- Store `"<URI>/backwards-compatible-json"` in `payloadType`.

Expand All @@ -144,6 +154,25 @@ This scheme is safe from rollback attacks because the first byte of
SERIALIZED_BODY must be 0x7b (`{`) in backwards compatibility mode and 0x02 in
regular mode.

### Multiple signatures

A file may have more than one signature, which is equivalent to separate files
with individual signatures.

```json
{
"payload": "<Base64(SERIALIZED_BODY)>",
"payloadType": "<PAYLOAD_TYPE>",
"signatures": [{
"keyid": "<KEYID_1>",
"sig": "<SIG_1>"
}, {
"keyid": "<KEYID_2>",
"sig": "<SIG_2>"
}]
}
```

### Optional changes to wrapper

The standard wrapper is JSON with an explicit `payloadType`. Optionally,
Expand Down Expand Up @@ -278,9 +307,9 @@ used by TUF and in-toto has a BODY that is a regular JSON object and a signature
{
"signed": <BODY>,
"signatures": [{
,
"keyid": "<KEYID>",
"sig": "<Hex(Sign(CanonicalJson(BODY)))>"
}, …]
}]
}
```

Expand All @@ -299,11 +328,13 @@ To convert an existing signature to the new format:
- `new.payload = base64encode(CanonicalJson(orig.signed))`
- `new.payloadType = "<URI>/backwards-compatible-json"`
- `new.signatures[*].sig = base64encode(hexdecode(orig.signatures[*].sig))`
- `new.signatures[*].keyid = orig.signatures[*].keyid`

To convert a backwards compatible signature to the old format:

- `old.signed = jsonparse(base64decode(new.payload))`
- `old.signatures[*].sig = hexencode(base64decode(new.signatures[*].sig))`
- `old.signatures[*].keyid = new.signatures[*].keyid`

## Testing

Expand Down