Skip to content

(CBOM) Protocol properties: replace protocol-specific properties with a generic composition - #1213

Open
bhess wants to merge 1 commit into
CycloneDX:2.0-devfrom
bhess:feat/protocol-composition-bom
Open

bhess wants to merge 1 commit into
CycloneDX:2.0-devfrom
bhess:feat/protocol-composition-bom

Conversation

@bhess

@bhess bhess commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Replaces the protocol-specific structure in protocolProperties with one generic property, composition, which reuses the protocol registry's compositionSlot. Addresses #1162, as an alternative to the protocol-specific properties of #1184 and #1200.

Why

  • Protocol-specific properties don't scale. TLS and IKEv2 have their own structure, feat(2.0): add SSH algorithm lists to protocolProperties #1200 would add SSH, and the registry lists 14 protocol families. Each one would need a schema change.
  • The shape is the same every time: named entries with algorithms, grouped by role. Only the labels differ (tlsGroups, kex, encr).
  • The registry already defines these labels. Since CBOM: add protocol registry schema #1010, a protocol version is a list of slots, each with a role and the algorithms that can fill it. A CBOM states the same for its subject.

A new protocol becomes a registry entry, not a schema change. A consumer finds every key exchange in a BOM with one query, whatever the protocol.

What's changed

"protocolProperties": {
  "type": "ssh", "version": "2.0",
  "composition": [
    { "role": "key-exchange", "selection": "one-of", "selectedBy": "negotiation", "selectingParty": "client",
      "algorithmSet": [{ "name": "mlkem768x25519-sha256", "algorithms": ["ML-KEM-768", "x25519", "SHA-256"] }] },
    { "role": "signature", "selection": "one-of", "selectedBy": "negotiation", "selectingParty": "client",
      "algorithmSet": [{ "name": "ssh-ed25519", "algorithms": ["Ed25519"] }] }
  ]
}

How it works

  • type and version identify the registry entry. A slot matches the entry's slot with the same role, and with the same selecting party where the role occurs more than once.
  • name keeps the protocol's own identifier, (for example) the IANA name in TLS. algorithms follow the variant patterns, so they resolve in the registry and to the algorithm components of the BOM.

Open points

Backwards compatibility

Breaking for 2.0: removes cipherSuites and ikev2TransformTypes, adds composition.

Closes #1162

…d update existing ones

Signed-off-by: Basil Hess <bhe@zurich.ibm.com>
"title": "IKEv2 Authentication Method"
}
}
"$ref": "../../cryptography-defs.schema.json#/definitions/compositionSlot",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I support the generic direction(as discussed in meeting). One regression concerns me: the link from a slot to the algorithm asset in the BOM is lost.

Before this PR, cipherSuites[].algorithms and the ikeV2* algorithm properties were refLinkType references, so a slot pointed at a specific algorithm component. Here algorithms are name strings, and the description says they resolve "to the algorithm components of the BOM". In this PR's own test cases they do not:

  • valid-cryptography-full-2.0.json: AES-128-GCM-128-96, AES-256-GCM-128-96 and HMAC-SHA-256-128 have no component with that name (the components are AES-128-GCM, AES-256-GCM, HMAC-SHA-256).
  • valid-cryptography-certificate-2.0.json: AES-256-GCM-128-96 versus component AES-256-GCM.
  • The three new examples define no algorithm components at all.

I think it matters because the algorithm component carries the implementation facts (certification level, execution environment, implementation platform, security levels, the providing library). Two components can share a name, for example the same algorithm from a validated and a non-validated module, and a string cannot choose between them. A Misspelled name also dangles silently, where a refId can be checked.

The migrated examples keep relatedCryptographicAssets beside the composition, but that list is unlabelled, which is the "which algorithm does what" problem of #1162 again. The same applies to keys: the SSH example names the host key algorithm, but there is no key asset and no link to one.

Could a member carry an optional reference to the asset on the BOM side, or could the resolution rule be stated normatively ?

},
{
"role": "authentication",
"selection": "one-of",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The role authentication is not in the registry entry for ike version 2, which has encryption, prf, integrity and key-exchange. The same slot is in valid-cryptography-full-2.0.json. ssh and esp have no registry entry at all, so all their roles are unchecked.

role is a free string in compositionSlot, and the schema cannot check it against the registry. So "a consumer finds every key exchange with one query" only holds if producers spell roles identically. A filter on key-exchange for a post-quantum readiness check would silently miss kex or key-agreement.

Could the registry schema define the role vocabulary as a closed list (or a recommended one), and could the description say what a slot means when the registry entry has no slot with that role?

},
{
"role": "cert-chain-signature",
"selection": "any-of",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This slot does not resolve against the TLS 1.3 entry in #1211. There, cert-chain-signature holds only the sub-protocol reference { "protocol": "x509", "version": "3" }, with all-of and protocol-fixed. Here it holds TLS signature scheme bundles with any-of and configuration, and ECDSA-secp256r1-SHA-256 is not in the x509 entry (which has ECDSA-SHA-256).

Which is intended on the BOM side: the TLS scheme names from signature_algorithms_cert, or X.509 signature algorithm names? The two PRs should agree, otherwise a checker cannot match this slot.

"algorithmSet": [
{
"name": "256-bit random ECP group",
"algorithms": [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the open point about codepoints: I think IKEv2 needs them. The IANA "name" here is descriptive text ("256-bit random ECP group"), not an identifier. Implementations label the same thing differently (group 19, ecp256), and what is on the wire is the Transform ID. The removed ikeV2Ke.group integer was the only stable identifier.

For TLS the IANA name is already a unique identifier, so the codepoint matters less there. An optional identifier on a member would cover both.

@beatquantum

Copy link
Copy Markdown

The generic composition is a good direction. On the open point about codepoints, I would add that TLS needs them too, for groups outside the IANA registry.

During migration, groups circulate under draft and private-use codepoints, and the codepoints for the same hybrid have changed as drafts moved on. Several jurisdictions also prefer algorithms and hybrids that are not yet in the IANA registry, and strategic sectors such as defence may run profiles that never will be. For those groups the name is not a stable identifier. The codepoint is what a scanner observes on the wire, and it is what matches a CBOM to a captured handshake.

An optional identifier on each algorithmSet member, as suggested above for IKEv2, would cover IKEv2 Transform IDs, TLS codepoints including private-use ones, and SSH names in one field. It would also let a CBOM record what a service actually negotiates where the registry in #1211 has no entry yet, rather than leaving those groups out of the inventory.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cap: cryptography Capability: Cryptography (CBOM)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants