Draft: draft-ietf-mls-protocol

Commentary: This PR moves the signature key from to , to ensure that an MLS client always has a signature public key with which to verify messages , even if it does not support a member 's credential type . This is an alternative approach to , and IMO a bit cleaner . We no longer need the notion of a  , since BasicCredential does n't stand alone . And since  only appears in LeafNode , common fields can be hoisted up into LeafNode . The Credential struct really only exists as a conceptual boundary , to make the exposition clearer ; otherwise you could just shove the into LeafNode . Note that this does not obviate the need for . This PR only ensures that the signatures can be processed ; that PR helps ensure that the signatures are meaningful . 
 - As I noted in the intro comment , I think you can view these two PRs as addressing different levels of interop -- the mechanics of verifying signatures vs. the ability to actually meaningfully interpret a credential . Always having the key in the same place could also allow some minor simplification to implementation logic It 's also interesting to consider what this would imply for future credential types . On the one hand , they would n't need to recite the public key , just provide a binding to it , like a hash or a signature where the public key was filled in from outside . On the other hand , it would open up the door to credential types that are n't actually bound to the public key , which creates replay risk . In any case , as the above might hint , I do n't have strong feelings about this . I mainly wanted to present an alternative to that was more palatable to me . Given the replay risk noted above , though , I think I 'm trending toward closing both this PR and , and just keeping the current structure with the improved compatibilty bounds provided by . 
 Latest commit responds to some offline comments from Having and makes it a little confusing what is about . So changed to and propagated that change throughout . The definition of fits better in the ciphersuites section ( next to ) than it does in the credentials section Having done that , I 'm more positive on this change . The change is a good clarification , and having the signature public key separate from the credential provides a stonger decoupling of the credential from the MLS crypto . The only thing the credential layer needs to know now is how to bind to the signature key . 
 We relocated multiple pieces recently which causes the general structure of the document to feel a bit disordered , we need to do a minimal editorial restructure before releasing the next draft . Changing the depth of some sections might be enough ... 
 I am gon na close this in favor of the newer issue where we started a bit more discussion : 
 Can you elaborate on why we need this if we also mandate that all clients have to support the credential types of all other clients ? I would think that if a client supports a credential type , it knows how to extract the signature public key from that credential .
Paragraph (version B):
Like HPKE public keys, signature public keys are represented as
opaque values in a format defined by the cipher suite's signature
scheme.
Paragraph (version B):
For ciphersuites using Ed25519 or Ed448 signature schemes, the public
key is in the format specified in RFC8032.  For ciphersuites using
ECDSA with the NIST curves (P-256, P-384, or P-521), the public key
is the output of the uncompressed Elliptic-Curve-Point-to-Octet-
String conversion according to SECG.
Paragraph (version A):
Note that a Credential can provide multiple identifiers for the
client.  If an application wishes to decided whether a credential
represents the correct identifier for a participant in a given
context, it is up to the application to decide what the correct value
is and compare it to the credential.  For example, a certificate in
an X509Credential may attest to several domain names or email
addresses in its subjectAltName extension.  An application may decide
to present all of these to a user, or if it knows a "desired" domain
name or email address, it can check that the desired identifier is
among those attested.  Using the terminology from RFC6125, a
Credential provides "presented identifiers", and it is up to the
application to supply a "reference identifier" for the authenticated
client, if any.
Paragraph (version B):
Each member of a group presents a credential that associates an
identity with the member's key material.  This information is
verified according to the Authentication Service in use for a group.
Paragraph (version B):
A Credential can provide multiple identifiers for the client.  It is
up to the application to decide which identifier or identifiers to
use at the application level.  For example, a certificate in an
X509Credential may attest to several domain names or email addresses
in its subjectAltName extension.  An application may decide to
present all of these to a user, or if it knows a "desired" domain
name or email address, it can check that the desired identifier is
among those attested.  Using the terminology from RFC6125, a
Credential provides "presented identifiers", and it is up to the
application to supply a "reference identifier" for the authenticated
client, if any.
Paragraph (version A):
Credentials MAY also include information that allows a relying party
to verify the identity / signing key binding.
Paragraph (version A):
Additionally, Credentials SHOULD specify the signature scheme
corresponding to each contained public key.
Paragraph (version A):
A BasicCredential is a raw, unauthenticated assertion of an identity/
key binding.  The format of the key in the "public_key" field is
defined by the relevant ciphersuite: the group ciphersuite for a
credential in a leaf node of a ratchet tree or the KeyPackage
ciphersuite for a credential in a KeyPackage object.  For
ciphersuites using Ed25519 or Ed448 signature schemes, the public key
is in the format specified in RFC8032.  For ciphersuites using ECDSA
with the NIST curves (P-256, P-384, or P-521), the public key is the
output of the uncompressed Elliptic-Curve-Point-to-Octet-String
conversion according to SECG.
Paragraph (version A):
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 algorithm for the "public_key" in the end-
entity certificate MUST match the relevant ciphersuite.
Paragraph (version B):
Credentials MAY also include information that allows a relying party
to verify the identity / signing key binding, such as a signature
from a trusted authority.
Paragraph (version B):
A BasicCredential is a bare assertion of an identity, without any
additional information.  The format of the encoded identity is
defined by the application.
Paragraph (version B):
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.
Paragraph (version A):
The "public_key" field contains an HPKE public key whose private key
is held only by the members at the leaves among its descendants.  The
"parent_hash" field contains a hash of this node's parent node, as
described in parent-hash.  The "unmerged_leaves" field lists the
leaves under this parent node that are unmerged, according to their
indices among all the leaves in the tree.
Paragraph (version B):
The "encryption_key" field contains an HPKE public key whose private
key is held only by the members at the leaves among its descendants.
The "parent_hash" field contains a hash of this node's parent node,
as described in parent-hash.  The "unmerged_leaves" field lists the
leaves under this parent node that are unmerged, according to their
indices among all the leaves in the tree.
Paragraph (version A):
The "public_key" field conains an HPKE public key whose private key
is held only by the member occupying this leaf (or in the case of a
LeafNode in a KeyPackage object, the issuer of the KeyPackage).  The
"credential" contains authentication information for this member, as
described in credentials.
Paragraph (version B):
The "encryption_key" field conains an HPKE public key whose private
key is held only by the member occupying this leaf (or in the case of
a LeafNode in a KeyPackage object, the issuer of the KeyPackage).
The "credential" contains authentication information for this member,
as described in credentials.
Paragraph (version A):
The field "public_key" contains the HPKE public key of P.  If P is
the root, then the "parent_hash" field is set to a zero-length octet
string.  Otherwise, "parent_hash" is the Parent Hash of the next node
after P on the filtered direct path of U.  This way, P's Parent Hash
fixes the new HPKE public key of each node V on the path from P to
the root.  Note that the path from P to the root may contain some
blank nodes that are not fixed by P's Parent Hash.  However, for each
node that has an HPKE key, this key is fixed by P's Parent Hash.
Paragraph (version B):
The field "encryption_key" contains the HPKE public key of P.  If P
is the root, then the "parent_hash" field is set to a zero-length
octet string.  Otherwise, "parent_hash" is the Parent Hash of the
next node after P on the filtered direct path of U.  This way, P's
Parent Hash fixes the new HPKE public key of each node V on the path
from P to the root.  Note that the path from P to the root may
contain some blank nodes that are not fixed by P's Parent Hash.
However, for each node that has an HPKE key, this key is fixed by P's
Parent Hash.
Paragraph (version A):
The value for "init_key" MUST be a public key for the asymmetric
encryption scheme defined by "cipher_suite", and it MUST be unique
among the set of KeyPackages created by this client.  Likewise, the
"leaf_node" field MUST be valid for the ciphersuite, including both
the "public_key" and "credential" fields.  The whole structure is
signed using the client's signature key.  A KeyPackage object with an
invalid signature field MUST be considered malformed.
Paragraph (version B):
The value for "init_key" MUST be a public key for the asymmetric
encryption scheme defined by "cipher_suite", and it MUST be unique
among the set of KeyPackages created by this client.  Likewise, the
"leaf_node" field MUST be valid for the ciphersuite, including both
the "encryption_key" and "signature_key" fields.  The whole structure
is signed using the client's signature key.  A KeyPackage object with
an invalid signature field MUST be considered malformed.
Paragraph (version A):
Verify that the value of "leaf_node.public_key" is different from
the value of the "init_key" field.
Paragraph (version B):
Verify that the value of "leaf_node.encryption_key" is different
from the value of the "init_key" field.
Paragraph (version A):
Verify that the "public_key" value in the LeafNode is different
from the corresponding field in the LeafNode being replaced.
Paragraph (version B):
Verify that the "encryption_key" value in the LeafNode is
different from the corresponding field in the LeafNode being
replaced.
Paragraph (version A):
if the LeafNode in the KeyPackage shares the same "public_key" with
another LeafNode in the group.
Paragraph (version B):
if the LeafNode in the KeyPackage shares the same "encryption_key"
with another LeafNode in the group.
Paragraph (version A):
Verify that the "public_key" value in the LeafNode is different
from the committer's current leaf node.
Paragraph (version B):
Verify that the "encryption_key" value in the LeafNode is
different from the committer's current leaf node.