Code change:
This updates the language around how certificate chains are constructed: We allow certificates to be omitted if the client knows any recipients will already possess the omitted certificate. We allow certificate chains to be out-of-order and potentially contain unused certificates. This is nice because it means less data needs to be sent on the wire, and also provides a method for root certificates to be rotated gracefully (as clients can provide chains for both old and new roots).
NAME it might be useful to also add this language from RFC 8446. It would make the process exactly the same as TLS which makes implementation easier. >The sender's certificate MUST come in the first >CertificateEntry in the list. Each following certificate SHOULD >directly certify the one immediately preceding it. Because >certificate validation requires that trust anchors be distributed >independently, a certificate that specifies a trust anchor MAY be >omitted from the chain, provided that supported peers are known to >possess any omitted certificates.
I think that is fine and is consistent with RFC8446. Don't we already have a better mechanism for rotating certificates? As soon as a member has a new certificate chain, it can update its LeafNode in an UpdatePath. This semantics of X.509 certificate bundles are already a bit fuzzy. Such a change will make validation more complicated and more error prone, when this seems completely unnecessary.
The scenario that this would address is: say that a root CA is compromised and needs to be replaced. Distributing the new CA certificate likely requires a software release, which not everyone will install simultaneously. During the rollout, some users will know only the old compromised CA and some users will know only the new CA and not the compromised one. To preserve interop during the rollout, users need to include two intermediates in their certificate chain: an intermediate signed by the old root that signs their leaf, and an intermediate signed by the new root that signs their leaf. (In the exact scenario I'm thinking of, the intermediate private key is held by the user, so it would not be compromised with the root. Though there may be other arrangements where this flexibility helps.) In terms of implementation complexity: the X509 chain validation libraries I'm aware of already support path building because it's necessary for TLS, so I would expect those could be used
This is actually the reason why I think it makes sense to adopt the same mechanism. For example, if you use OpenSSL to validate the chain it does not take a chain as input. It takes a collection of certificates, a set of trusted root certs, and the leaf you want to validate. I believe not making this change has a higher complexity.
I'm sorry I missed this previously, but this requirement was a source of trouble in TLS and was removed in RFC 8446, which allows extra certificates in the middle. Was there a conscious decision to be more strict here.
I don't recall this ever being discussed. I think it was just added and nobody ever objected.
NAME can you elaborate a little bit? The way I read it the requirement is just that there is a valid signature chain, i.e. that one certificate signs the next and so on.
NAME - I deliberately reverted to the original TLS level of strictness here, in hopes that in starting over with a new ecosystem we could reset things to a cleaner state. Do you think there are legitimate reasons for violating the strict rule, or is it just a common misconfiguration in TLS servers? I would not really be inclined to accommodate the latter. NAME - I believe what NAME is envisioning are cases where there are multiple valid chains, say via old and new versions of an intermediate certificate. So you might do something like provide a "chain" of the form (leaf, oldintermediate, newintermediate), with the idea that the client could verify using whichever one makes it happy.
NAME take a look at the comment I left on the PR. I can see your point about starting over as being valid, but one thing that also caught my eye in the TLS RFC was language around allowing a root CA to be left out of the chain since those could potentially already exist in a local trust store.
I see. Thanks NAME for the clarification. Maybe we can phrase it in such a way that whatever the credential includes (added intermediary certificates or left-out root certificates) in the end the local client MUST be able to create a continuous certificate chain from the leaf to the root. Do we need to define how the client does that? Since we're already pushing everything else related to authentication into the AS, I'm inclined to say no.

Related discussion:
text: additional information.  The format of the encoded identity is defined by the application. <del> For an X.509 credential, each entry in the chain represents a single DER-encoded X.509 certificate.  The chain is ordered such that the first entry (chain[0]) is the end-entity certificate and each subsequent certificate in the chain MUST be the issuer of the previous certificate.  The public key encoded in the "subjectPublicKeyInfo" of the end-entity certificate MUST be identical to the "signature_key" in the LeafNode containing this credential. </del> <ins> For an X.509 credential, each entry in the "certificates" field represents a single DER-encoded X.509 certificate.  The chain is ordered such that the first entry (chain[0]) is the end-entity certificate.  The public key encoded in the "subjectPublicKeyInfo" of the end-entity certificate MUST be identical to the "signature_key" in the LeafNode containing this credential.  A chain MAY omit any non-leaf certificates that supported peers are known to already possess. </ins> 5.3.1.