types.mx raw
1 package mls
2
3 // MLS cryptographic types (RFC 9420 §5.3, §6).
4 // Key type aliases, credentials, and HPKE ciphertext.
5
6 import "errors"
7
8 var (
9 errInvalidCredentialType = errors.New("mls: invalid credential type")
10 )
11
12 // Key type aliases — all are raw byte slices.
13 type (
14 hpkePublicKey []byte
15 hpkePrivateKey []byte
16 signaturePublicKey []byte
17 signaturePrivateKey []byte
18 )
19
20 // --- Credential ---
21
22 type credentialType uint16
23
24 const (
25 credentialTypeBasic credentialType = 0x0001
26 credentialTypeX509 credentialType = 0x0002
27 )
28
29 // Credential holds information about a group member's identity.
30 type Credential struct {
31 credentialType credentialType
32 identity []byte // for credentialTypeBasic
33 certificates [][]byte // for credentialTypeX509
34 }
35
36 // NewBasicCredential creates a basic credential with an application-specific identity.
37 func NewBasicCredential(identity []byte) *Credential {
38 return &Credential{
39 credentialType: credentialTypeBasic,
40 identity: identity,
41 }
42 }
43
44 func (cred *Credential) unmarshal(r *Reader) error {
45 *cred = Credential{}
46
47 v, ok := r.readUint16()
48 if !ok {
49 return errUnexpectedEOF
50 }
51 cred.credentialType = credentialType(v)
52
53 switch cred.credentialType {
54 case credentialTypeBasic:
55 cred.identity, ok = r.readOpaqueVec()
56 if !ok {
57 return errUnexpectedEOF
58 }
59 return nil
60 case credentialTypeX509:
61 return r.readVector(func(r *Reader) error {
62 cert, ok := r.readOpaqueVec()
63 if !ok {
64 return errUnexpectedEOF
65 }
66 cred.certificates = append(cred.certificates, cert)
67 return nil
68 })
69 default:
70 return errInvalidCredentialType
71 }
72 }
73
74 func (cred *Credential) marshal(w *Writer) {
75 w.addUint16(uint16(cred.credentialType))
76 switch cred.credentialType {
77 case credentialTypeBasic:
78 w.writeOpaqueVec(cred.identity)
79 case credentialTypeX509:
80 w.writeVector(len(cred.certificates), func(w *Writer, i int) {
81 w.writeOpaqueVec(cred.certificates[i])
82 })
83 default:
84 panic("unreachable")
85 }
86 }
87
88 // --- HPKE Ciphertext ---
89
90 type hpkeCiphertext struct {
91 kemOutput []byte
92 ciphertext []byte
93 }
94
95 func (hc *hpkeCiphertext) unmarshal(r *Reader) error {
96 *hc = hpkeCiphertext{}
97 var ok bool
98 hc.kemOutput, ok = r.readOpaqueVec()
99 if !ok {
100 return errUnexpectedEOF
101 }
102 hc.ciphertext, ok = r.readOpaqueVec()
103 if !ok {
104 return errUnexpectedEOF
105 }
106 return nil
107 }
108
109 func (hc *hpkeCiphertext) marshal(w *Writer) {
110 w.writeOpaqueVec(hc.kemOutput)
111 w.writeOpaqueVec(hc.ciphertext)
112 }
113