Skip to content

Commit 976a7d9

Browse files
Merge pull request #61 from adityasaky/signature-extensions
Add support for signature extensions
2 parents fba27e4 + d25e627 commit 976a7d9

File tree

4 files changed

+114
-11
lines changed

4 files changed

+114
-11
lines changed

envelope.md

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
May 10, 2024
44

5-
Version 1.0.1
5+
Version 1.1.0
66

77
This document describes the recommended data structure for storing DSSE
88
signatures, which we call the "JSON Envelope". For the protocol/algorithm, see
@@ -52,14 +52,63 @@ envelopes with individual signatures.
5252
}
5353
```
5454

55+
### Signature Extensions [experimental]
56+
57+
58+
NOTE: The design for signature extensions is currently experimental and may
59+
change.
60+
61+
In addition to `keyid` and `sig`, a signature object may include an `extension`
62+
field to store ecosystem specific information pertaining to the signature.
63+
Extensions do not modify the signing workflow established in the
64+
[DSSE protocol](protocol.md) except for actually encoding the extension
65+
alongside the signature in the envelope. However, signers and verifiers may
66+
exchange information about the extensions used out-of-band.
67+
68+
```json
69+
{
70+
"payload": "<Base64(SERIALIZED_BODY)>",
71+
"payloadType": "<PAYLOAD_TYPE>",
72+
"signatures": [{
73+
"keyid": "<KEYID>",
74+
"sig": "<Base64(SIGNATURE)>",
75+
"extension": {
76+
"kind": "<EXTENSION_KIND>",
77+
"ext": {...}
78+
}
79+
}]
80+
}
81+
```
82+
83+
`extension.kind` is a string and the `EXTENSION_KIND` value must unambiguously
84+
identify the ecosystem or kind of the extension. This in turn identifies the
85+
fields in the opaque object `ext`. Some well-known extensions MAY be
86+
[registered and listed](extensions.md) with their `ext` definition alongside the
87+
DSSE specification.
88+
89+
Additionally, extensions MUST NOT contain any information such that the
90+
signature verification fails in its presence and passes in its absence.
91+
Essentially, if a required extension in some context is missing or if a consumer
92+
does not recognize the extension, verification MUST fail closed.
93+
94+
Finally, the opaque `ext` MUST NOT contain a DSSE envelope to avoid recursive
95+
verification of extensions and signatures. Similarly, the `ext` MUST NOT provide
96+
the signature bytes itself, but MUST only contain information required to verify
97+
the signature recorded in `sig` field.
98+
5599
### Parsing rules
56100

57101
* The following fields are REQUIRED and MUST be set, even if empty: `payload`,
58102
`payloadType`, `signature`, `signature.sig`.
59-
* The following fields are OPTIONAL and MAY be unset: `signature.keyid`.
60-
An unset field MUST be treated the same as set-but-empty.
103+
* The following fields are OPTIONAL and MAY be unset: `signature.keyid`,
104+
`signature.extension`. An unset field MUST be treated the same as
105+
set-but-empty.
106+
* The schema for `signature.extension.ext` for some declared
107+
`signature.extension.kind` MUST be communicated separately by producers to
108+
consumers.
61109
* Producers, or future versions of the spec, MAY add additional fields.
62-
Consumers MUST ignore unrecognized fields.
110+
Consumers MUST ignore unrecognized fields. Similarly, consumers MUST ignore
111+
extensions of an unrecognized kind.
63112

64113
## Other data structures
65114

envelope.proto

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ syntax = "proto3";
22

33
package io.intoto;
44

5+
import "google/protobuf/struct.proto";
6+
57
// An authenticated message of arbitrary type.
68
message Envelope {
79
// Message to be signed. (In JSON, this is encoded as base64.)
@@ -32,4 +34,19 @@ message Signature {
3234
// *Unauthenticated* hint identifying which public key was used.
3335
// OPTIONAL.
3436
string keyid = 2;
37+
38+
// *Unauthenticated* field that can record additional information pertaining
39+
// to the signature.
40+
// OPTIONAL.
41+
Extension extension = 3;
42+
}
43+
44+
message Extension {
45+
// Unambiguously identifies how to interpret extension fields.
46+
// REQUIRED.
47+
string kind = 1;
48+
49+
// Extension fields.
50+
// REQUIRED.
51+
google.protobuf.Struct ext = 2;
3552
}

extensions.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# DSSE Extensions
2+
3+
May 10, 2024
4+
5+
Version 1.1.0
6+
7+
This document lists the well known DSSE
8+
[signature extensions](/envelope.md#signature-extensions). To add a signature
9+
extension, propose a change with a unique media type for the signing ecosystem
10+
and include a link to the format of the `ext` field.
11+
12+
| Name (with link) | Kind | Notes |
13+
|------------------|------|-------|
14+
| [Sigstore] | `application/vnd.dev.sigstore.verificationmaterial;version=<VERSION>` | The X.509 certificate chain must not include the root or trusted intermediate certificates |
15+
16+
17+
[Sigstore]: https://github.com/sigstore/protobuf-specs/blob/main/protos/sigstore_bundle.proto

protocol.md

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
May 10, 2024
44

5-
Version 1.0.1
5+
Version 1.1.0
66

77
This document describes the protocol/algorithm for creating and verifying DSSE
88
signatures, independent of how they are transmitted or stored. For the
@@ -23,6 +23,7 @@ Name | Type | Required | Authenticated
2323
SERIALIZED_BODY | bytes | Yes | Yes
2424
PAYLOAD_TYPE | string | Yes | Yes
2525
KEYID | string | No | No
26+
EXTENSION | object | No | No
2627

2728
* SERIALIZED_BODY: Arbitrary byte sequence to be signed.
2829

@@ -52,6 +53,20 @@ KEYID | string | No | No
5253
decisions; it may only be used to narrow the selection of possible keys to
5354
try.
5455

56+
* EXTENSION: Optional, unauthenticated object used to store signature-specific
57+
information. Extensions are identified by a `kind` field that unambiguously
58+
describes the fields for the extension. The details for each extension and
59+
its fields must be agreed upon out-of-band by the signer and verifier,
60+
though some well-known extensions may be [listed](extensions.md) and defined
61+
in the DSSE specification. Note that as the extension is unauthenticated,
62+
it MUST NOT allow the verifier to independently verify the signature. For
63+
example, the extension MUST NOT be trusted to directly provide the leaf
64+
public key to verify a signature. Similarly, an extension field that
65+
contains an X.509 certificate chain MUST NOT be trusted to provide the root
66+
certificate, but it MAY provide only intermediate certificates.
67+
* NOTE: The design for signature extensions is currently experimental
68+
and is subject to change.
69+
5570
Functions:
5671

5772
* PAE() is the "Pre-Authentication Encoding", where parameters `type` and
@@ -77,23 +92,28 @@ Functions:
7792
Out of band:
7893
7994
- Agree on a PAYLOAD_TYPE and cryptographic details, optionally including
80-
KEYID.
95+
KEYID and EXTENSION.
8196
8297
To sign:
8398
8499
- Serialize the message according to PAYLOAD_TYPE. Call the result
85100
SERIALIZED_BODY.
86101
- Sign PAE(UTF8(PAYLOAD_TYPE), SERIALIZED_BODY). Call the result SIGNATURE.
87102
- Optionally, compute a KEYID.
88-
- Encode and transmit SERIALIZED_BODY, PAYLOAD_TYPE, SIGNATURE, and KEYID,
89-
preferably using the recommended [JSON envelope](envelope.md).
103+
- Optionally, include signature specific information as an EXTENSION.
104+
- Encode and transmit SERIALIZED_BODY, PAYLOAD_TYPE, SIGNATURE, KEYID, and
105+
EXTENSION, preferably using the recommended [JSON envelope](envelope.md).
90106
91107
To verify:
92108
93-
- Receive and decode SERIALIZED_BODY, PAYLOAD_TYPE, SIGNATURE, and KEYID, such
94-
as from the recommended [JSON envelope](envelope.md). Reject if decoding
95-
fails.
109+
- Receive and decode SERIALIZED_BODY, PAYLOAD_TYPE, SIGNATURE, KEYID, and
110+
EXTENSION such as from the recommended [JSON envelope](envelope.md). Reject
111+
if decoding fails.
96112
- Optionally, filter acceptable public keys by KEYID.
113+
- If EXTENSION is set, use its fields to obtain information that MAY be
114+
required for verification. Reject any significant fields that the verifier
115+
must establish separately, such as the public key for a signature or a root
116+
certificate for an X.509 certificate chain.
97117
- Verify SIGNATURE against PAE(UTF8(PAYLOAD_TYPE), SERIALIZED_BODY). Reject if
98118
the verification fails.
99119
- Reject if PAYLOAD_TYPE is not a supported type.

0 commit comments

Comments
 (0)