Countersigning COSE Envelopes in Transparency Services
Fraunhofer SIT
Rheinstrasse 75
Darmstadt
64295
Germany
henk.birkholz@sit.fraunhofer.de
Microsoft
UK
Maik.Riechert@microsoft.com
Microsoft
UK
antdl@microsoft.com
Microsoft
UK
fournet@microsoft.com
Security
TBD
Internet-Draft
A transparent and authentic Transparent Registry service in support of a supply chain's integrity, transparency, and trust requires all peers that contribute to the Registry operations to be trustworthy and authentic. In this document, a countersigning variant is specified that enables trust assertions on Merkle-tree based operations for global supply chain registries. A generic procedure for producing payloads to be signed and validated is defined and leverages solutions and principles from the Concise Signing and Encryption (COSE) space.
Introduction
This draft is retained as a -03 version. It's contents will be distributed between and soon.
This document defines a method for issuing and verifying countersignatures on COSE_Sign1 messages included in an authenticated data structure such as a Merkle Tree.
We adopt the terminology of the Supply Chain Integrity, Transparency, and Trust (SCITT) architecture document (An Architecture for Trustworthy and Transparent Digital Supply Chains, see ): Claim, Envelope, Transparency Service, Registry, Receipt, and Verifier.
-
[TODO] Do we need to explain or introduce them here? We may also define Tree (our shorthand for authenticated data structure), Root (a succinct commitment to the Tree, e.g., a hand) and use Issuer instead of TS.
From the Verifier's viewpoint, a Receipt is similar to a countersignature V2 on a single signed message: it is a universally-verifiable cryptographic proof of endorsement of the signed envelope by the countersigner.
Compared with countersignatures on single COSE envelopes,
- Receipts countersign the envelope in context, providing authentication both of the envelope and of its logical position in the authenticated data structure.
- Receipts are proof of commitment to the whole contents of the data structure, even if the Verifier knows only some of its contents.
- Receipts can be issued in bulk, using a single public-key signature for issuing a large number of Receipts.
Requirements Notation
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED",
"MAY", and "OPTIONAL" in this document are to be interpreted as
described in BCP 14 when, and only when, they
appear in all capitals, as shown here.
Common Parameters
Verifiers are configured by a collection of parameters
to identify a Transparency Service and verify its Receipts.
These parameters MUST be fixed for the lifetime of the Transparency Service
and securely communicated to all Verifiers.
At minimum, these parameters include:
- a Service identifier: An opaque identifier (e.g. UUID) that uniquely identifies the service and can be used to securely retrieve all other Service parameters.
-
The Tree algorithm used for issuing receipts, and its additional parameters, if any. This document creates a registry (see ) and describes an initial set of tree algorithms.
-
[TODO] The architecture also has fixed TS registration policies.
Generic Receipt Structure
A Receipt represents a countersignature issued by a Transparency Service.
The Receipt structure is a CBOR array with two items, in order:
-
protected: The protected header of the countersigner.
-
contents: The proof as a CBOR structure determined by the tree algorithm.
Receipt = [
protected: bstr .cbor {
* label => value
},
contents: any
]
label = tstr / int
value = any
Each tree algorithm MUST define its contents type and procedures for issuing and verifying a receipt.
COSE_Sign1 Countersigning
While the tree algorithms may differ in the way they aggregate multiple envelopes to compute a digest to be signed by the TS,
they all share the same representation of the individual envelopes to be countersigned (intuitively, their leaves).
This document uses the principles and structure definitions
of COSE_Sign1 countersigning V2 ().
Each envelope is authenticated using a Countersign_structure array, recalled below.
Countersign_structure = [
context: "CounterSignatureV2",
body_protected: empty_or_serialized_map,
sign_protected: empty_or_serialized_map,
external_aad: bstr,
payload: bstr,
other_fields: [
signature: bstr
]
]
The body_protected, payload, and signature fields are copied from the COSE_Sign1 message being countersigned.
The sign_protected field is provided by the TS, see below. This field
is included in the Receipt contents to enable the Verifier to re-construct Countersign_structure, as specified by the tree algorithm.
By convention, the TS always provides an empty external_aad: a zero-length bytestring.
Procedure for reconstruction of Countersign_structure:
- Let Target be the COSE_Sign1 message that corresponds to the countersignature. Different environments will have different mechanisms to achieve this. One obvious mechanism is to embed the Receipt in the unprotected header of Target. Another mechanism may be to store both artifacts separately and use a naming convention, database, or other method to link both together.
- Extract body_protected, payload, and signature from Target.
- Create a Countersign_structure using the extracted fields from Target, and sign_protected from the Receipt contents.
Countersigner Header Parameters
The following parameters MUST be included in the protected header of the countersigner (sign_protected in ):
- Service ID (label: TBD): The Service identifier, as defined in the Transparency Service parameters.
- Tree Algorithm (label: TBD): The Tree Algorithm used for issuing the receipt, as defined in the Transparency Service parameters.
- Issued At (label: TBD): The time at which the countersignature was issued as the number of seconds from 1970-01-01T00:00:00Z UTC, ignoring leap seconds.
Receipt Verification
Given a signed envelope and a Receipt for it,
the following steps must be followed to verify this Receipt.
- Decode the protected header of the Receipt and look-up the TS parameters using the Service ID header parameter.
- Verify that the Tree Algorithm parameter value in the receipt protected header matches the one in the TS parameters.
- Construct a Countersign_structure as described in , using the protected header of the Receipt as sign_protected.
- CBOR-encode Countersign_structure as To-Be-Included, using the CBOR encoding described in .
- Invoke the Tree Algorithm receipt verification procedure with the TS parameters and To-Be-Included as inputs.
The Verifier SHOULD apply additional checks before accepting the countersigned envelope as valid, based on its protected headers and payload.
CCF Tree Algorithm
The CCF tree algorithm specifies an algorithm based on a binary Merkle tree over the sequence of all ledger entries, as implemented in the CCF framework (see ).
Additional Parameters
The algorithm requires that the TS define
additional parameters:
- Signature Algorithm: The ECDSA signature algorithm used to sign the Merkle tree root (see ).
- Service Certificate: The self-signed X.509 certificate used as trust anchor to verify signatures generated by the transparency service using the Signature Algorithm.
All definitions in this section use the hash algorithm required by the signature algorithm set in the TS parameters (see Section ). We write HASH to refer to this algorithm, and HASH_SIZE for the fixed length of its output in bytes.
Cryptographic Components
Note: This section is adapted from , which provides additional discussion of Merkle trees.
Binary Merkle Trees
The input of the Merkle Tree Hash (MTH) function is a list of n bytestrings, written D_n = {d[0], d[1], ..., d[n-1]}. The output is a single HASH_SIZE bytestring, also called the tree root hash.
This function is defined as follows:
The hash of an empty list is the hash of an empty string:
The hash of a list with one entry (also known as a leaf hash) is:
For n > 1, let k be the largest power of two smaller than n (i.e., k < n <= 2k). The Merkle Tree Hash of an n-element list D_n is then defined recursively as:
where:
- || denotes concatenation
- : denotes concatenation of lists
- D[k1:k2] = D'_(k2-k1) denotes the list {d'[0] = d[k1], d'[1] = d[k1+1], ..., d'[k2-k1-1] = d[k2-1]} of length (k2 - k1).
Merkle Inclusion Proofs
A Merkle inclusion proof for a leaf in a Merkle Tree is the shortest list of intermediate hash values required to re-compute the tree root hash
from the digest of the leaf bytestring. Each node in the tree is either a leaf node or is computed from the two nodes immediately below it (i.e., towards the leaves). At each step up the tree (towards the root), a node from the inclusion proof is combined with the node computed so far. In other words, the inclusion proof consists of the list of missing nodes required to compute the nodes leading from a leaf to the root of the tree. If the root computed from the inclusion proof matches the true root, then the inclusion proof proves that the leaf exists in the tree.
Verifying an Inclusion Proof
When a client has received an inclusion proof and wishes to verify inclusion of a leaf_hash for a given root_hash, the following algorithm may be used to prove the hash was included in the root_hash:
Generating an Inclusion Proof
Given the MTH input D_n = {d[0], d[1], ..., d[n-1]} and an index i < n in this list,
run the MTH algorithm and record the position and value of every intermediate hash
concatenated and hashed first with the digest of the leaf, then with the resulting intermediate hash value. (Most implementations instead record all intermediate hash computations, so that they can produce all inclusion proofs for a given tree by table lookups.)
Encoding Signed Envelopes into Tree Leaves
This section describes the encoding of signed envelopes and auxiliary ledger entries
into the leaf bytestrings passed as input to the Merkle Tree function.
Each bytestring is computed from three inputs:
-
internal_hash: a string of HASH_SIZE bytes;
-
internal_data: a string of at most 1024 bytes; and
-
data_hash: either the HASH of the CBOR-encoded Countersign_structure of the signed envelope, using the CBOR encoding described in , or a bytestring of size HASH_SIZE filled with zeroes for auxiliary ledger entries.
as the concatenation of three hashes:
This ensures that leaf bytestrings are always distinct from the inputs of the intermediate computations in MTH, which always consist of two hashes, and also that leaf bytestrings for signed envelopes and for auxiliary ledger entries are always distinct.
The internal_hash and internal_data bytestrings are internal to the CCF implementation. Similarly, the auxiliary ledger entries are internal to CCF. They are opaque to receipt Verifiers, but they commit the TS to the whole ledger contents and may be used for additional, CCF-specific auditing.
Receipt Contents Structure
The Receipt contents structure is a CBOR array. The items of the array in order are:
-
signature: the ECDSA signature over the Merkle tree root as bstr. Note that the Merkle tree root hash is the prehashed input to ECDSA and is not hashed twice.
-
node_certificate: a DER-encoded X.509 certificate for the public key for signature verification.
This certificate MUST be a valid CCF node certificate
for the service; in particular, it MUST form a valid X.509 certificate chain with the service certificate.
-
inclusion_proof: the intermediate hashes to recompute the signed root of the Merkle tree from the leaf digest of the envelope.
- The array MUST have at most 64 items.
- The inclusion proof structure is an array of [left, hash] pairs where left indicates the ordering of digests for the intermediate hash compution. The hash MUST be a bytestring of length HASH_SIZE.
-
leaf_info: auxiliary inputs to recompute the leaf digest included in the Merkle tree: the internal hash and the internal data.
-
internal_hash MUST be a bytestring of length HASH_SIZE;
-
internal_data MUST be a bytestring of length less than 1024.
The inclusion of an additional, short-lived certificate endorsed by the TS enables flexibility in its distributed implementation, and may support additional CCF-specific auditing.
The CDDL fragment that represents the above text follows.
ReceiptContents = [
signature: bstr,
node_certificate: bstr,
inclusion_proof: [+ ProofElement],
leaf_info: LeafInfo
]
ProofElement = [
left: bool
hash: bstr
]
LeafInfo = [
internal_hash: bstr,
internal_data: bstr
]
Receipt Contents Verification
Given the To-Be-Included bytes (see ) and the TS parameters,
the following steps must be followed to verify the Receipt contents.
- Verify that the Receipt Content structure is well-formed, as described in .
-
Compute LeafBytes as the bytestring concatenation of the internal hash, the hash of internal data, and the hash of the To-Be-Included bytes.
-
Compute the leaf digest.
-
Compute the root hash from the leaf hash and the Merkle proof using the Merkle Tree Hash Algorithm found in the service's parameters (see ):
- Verify the certificate chain established by the node certificate embedded in the receipt and the fixed service certificate in the TS parameters (see ). TBD needs more details
- Verify that signature is a valid signature value of the root hash, using the public key of the node certificate and the Signature Algorithm of the TS parameters.
Receipt Generation
This document provides a reference algorithm for producing valid receipts,
but it omits any discussion of TS registration policy and any CCF-specific implementation details.
The algorithm takes as input a list of entries to be jointly countersigned, each entry consisting of internal_hash, internal_data, and an optional signed envelope.
(This optional item reflects that a CCF ledger records both signed envelopes and auxiliary entries.)
- For each signed envelope, create the countersigner protected header and compute the Countersign_structure as described in .
- For each item in the list, compute LeafBytes as the bytestring concatenation of the internal hash, the hash of internal data and, if the envelope is present, the hash of the CBOR-encoding of Countersign_structure, using the CBOR encoding described in , otherwise a HASH_SIZE bytestring of zeroes.
- Compute the tree root hash by applying MTH to the resulting list of leaf bytestrings,
keeping the results for all intermediate HASH values.
- Select a valid node_certificate and compute a signature of the root of the tree with the corresponding signing key.
-
For each signed envelope provided in the input,
- Collect an inclusion_proof by selecting intermediate hash values, as described above.
- Produce the receipt contents using this inclusion_proof, the fixed node_certificate and signature, and the bytestrings internal_hash and internal_data provided with the envelope.
- Produce the receipt using the countersigner protected header and this receipt's contents.
CBOR Encoding Restrictions
In order to always regenerate the same byte string for the "to be included" and "to be hashed" values, the core deterministic encoding rules defined in MUST be used for all their CBOR structures.
Privacy Considerations
TBD
Security Considerations
TBD
IANA Considerations
Additions to Existing Registries
New Entries to the COSE Header Parameters Registry
IANA is requested to register the new COSE Header parameters defined below in the "COSE Header Parameters" registry.
COSE_Sign1 Countersign receipt
Name: COSE_Sign1 Countersign receipt
Label: TBD (temporary: 394, see also )
Value Type: [+ Receipt]
Description: One or more COSE_Sign1 Countersign Receipts to be embedded in the unprotected header of the countersigned COSE_Sign1 message.
Issued At
Name: Issued At
Label: TBD
Value Type: uint
Description: The time at which the signature was issued as the number of seconds from 1970-01-01T00:00:00Z UTC, ignoring leap seconds.
New SCITT-Related Registries
IANA is asked to add a new registry "TBD" to the list that appears at https://www.iana.org/assignments/.
The rest of this section defines the subregistries that are to be created within the new "TBD" registry.
Tree Algorithms
IANA is asked to establish a registry of tree algorithm identifiers, named "Tree Algorithms", with the following registration procedures: TBD
The "Tree Algorithms" registry initially consists of:
Initial content of Tree Algorithms registry
Identifier |
Tree Algorithm |
Reference |
CCF |
CCF tree algorithm |
This document |
The designated expert(s) should ensure that the proposed algorithm has a public specification and is suitable for use as [TBD].
Signature Algorithms
IANA is asked to establish a registry of signature algorithm identifiers, named "Signature Algorithms", with the following registration procedures: TBD
The "Signature Algorithms" registry initially consists of:
Initial content of Signature Algorithms registry
Identifier |
Signature Algorithm |
Reference |
ES256 |
ECDSA w/ SHA-256 |
|
The designated expert(s) should ensure that the proposed algorithm has a public specification and is suitable for use as a cryptographic signature algorithm.
References
Normative References
Concise Binary Object Representation (CBOR)
The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small code size, fairly small message size, and extensibility without the need for version negotiation. These design goals make it different from earlier binary serializations such as ASN.1 and MessagePack.
This document obsoletes RFC 7049, providing editorial improvements, new details, and errata fixes while keeping full compatibility with the interchange format of RFC 7049. It does not create a new version of the format.
Certificate Transparency Version 2.0
This document describes version 2.0 of the Certificate Transparency (CT) protocol for publicly logging the existence of Transport Layer Security (TLS) server certificates as they are issued or observed, in a manner that allows anyone to audit certification authority (CA) activity and notice the issuance of suspect certificates as well as to audit the certificate logs themselves. The intent is that eventually clients would refuse to honor certificates that do not appear in a log, effectively forcing CAs to add all issued certificates to the logs.
This document obsoletes RFC 6962. It also specifies a new TLS extension that is used to send various CT log artifacts.
Logs are network services that implement the protocol operations for submissions and queries that are defined in this document.
US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)
Federal Information Processing Standard, FIPS
Edwards-Curve Digital Signature Algorithm (EdDSA)
This document describes elliptic curve signature scheme Edwards-curve Digital Signature Algorithm (EdDSA). The algorithm is instantiated with recommended parameters for the edwards25519 and edwards448 curves. An example implementation and test vectors are provided.
CBOR Object Signing and Encryption (COSE): Initial Algorithms
Concise Binary Object Representation (CBOR) is a data format designed for small code size and small message size. There is a need to be able to define basic security services for this data format. This document defines a set of algorithms that can be used with the CBOR Object Signing and Encryption (COSE) protocol (RFC 9052).
This document, along with RFC 9052, obsoletes RFC 8152.
Key words for use in RFCs to Indicate Requirement Levels
In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words
RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.
Informative References
CBOR Object Signing and Encryption (COSE): Countersignatures
August Cellars
Concise Binary Object Representation (CBOR) is a data format designed for small code size and small message size. CBOR Object Signing and Encryption (COSE) defines a set of security services for CBOR. This document defines a countersignature algorithm along with the needed header parameters and CBOR tags for COSE. This document updates RFC 9052.
An Architecture for Trustworthy and Transparent Digital Supply Chains
Fraunhofer SIT
Microsoft Research
Microsoft Research
ARM
Traceability of physical and digital artifacts in supply chains is a
long-standing, but increasingly serious security concern. The rise
in popularity of verifiable data structures as a mechanism to make
actors more accountable for breaching their compliance promises has
found some successful applications to specific use cases (such as the
supply chain for digital certificates), but lacks a generic and
scalable architecture that can address a wider range of use cases.
This memo defines a generic and scalable architecture to enable
transparency across any supply chain with minimum adoption barriers
for producers (who can register their Signed Statements on any
Transparency Service, with the guarantee that all consumers will be
able to verify them) and enough flexibility to allow different
implementations of Transparency Services with various auditing and
compliance requirements.
Concise Encoding of Signed Merkle Tree Proofs
Transmute
Fraunhofer SIT
Microsoft
Microsoft
Microsoft
This specification describes three CBOR data structures for primary
use in COSE envelopes. A format for Merkle Tree Root Signatures with
metadata, a format for Inclusions Paths, and a format for disclosure
of a single hadh tree leaf payload (Merkle Tree Proofs).
CCF - Merkle Tree
n.d.