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  var (
   7  	errInvalidCredentialType error
   8  )
   9  
  10  // Key material is raw []byte: Moxie forbids named slice types, so the old
  11  // []byte/[]byte/[]byte/[]byte names
  12  // are the bare byte slice.
  13  
  14  // --- Credential ---
  15  
  16  type credentialType uint16
  17  
  18  const (
  19  	credentialTypeBasic credentialType = 0x0001
  20  	credentialTypeX509  credentialType = 0x0002
  21  )
  22  
  23  // Credential holds information about a group member's identity.
  24  type Credential struct {
  25  	credentialType credentialType
  26  	identity       []byte   // for credentialTypeBasic
  27  	certificates   [][]byte // for credentialTypeX509
  28  }
  29  
  30  // NewBasicCredential creates a basic credential with an application-specific identity.
  31  func NewBasicCredential(identity []byte) (c *Credential) {
  32  	return &Credential{
  33  		credentialType: credentialTypeBasic,
  34  		identity:       identity,
  35  	}
  36  }
  37  
  38  func (cred *Credential) unmarshal(r *Reader) (err error) {
  39  	*cred = Credential{}
  40  
  41  	v, ok := r.readUint16()
  42  	if !ok {
  43  		return errUnexpectedEOF
  44  	}
  45  	cred.credentialType = credentialType(v)
  46  
  47  	switch cred.credentialType {
  48  	case credentialTypeBasic:
  49  		cred.identity, ok = r.readOpaqueVec()
  50  		if !ok {
  51  			return errUnexpectedEOF
  52  		}
  53  		return nil
  54  	case credentialTypeX509:
  55  		return r.readVector(func(r *Reader) error {
  56  			cert, hasCert := r.readOpaqueVec()
  57  			if !hasCert {
  58  				return errUnexpectedEOF
  59  			}
  60  			cred.certificates = push(cred.certificates, cert)
  61  			return nil
  62  		})
  63  	default:
  64  		return errInvalidCredentialType
  65  	}
  66  }
  67  
  68  func (cred *Credential) marshal(w *Writer) {
  69  	w.addUint16(uint16(cred.credentialType))
  70  	switch cred.credentialType {
  71  	case credentialTypeBasic:
  72  		w.writeOpaqueVec(cred.identity)
  73  	case credentialTypeX509:
  74  		w.writeVector(len(cred.certificates), func(w *Writer, i int32) {
  75  			w.writeOpaqueVec(cred.certificates[i])
  76  		})
  77  	default:
  78  		panic("unreachable")
  79  	}
  80  }
  81  
  82  // --- HPKE Ciphertext ---
  83  
  84  type hpkeCiphertext struct {
  85  	kemOutput  []byte
  86  	ciphertext []byte
  87  }
  88  
  89  func (hc *hpkeCiphertext) unmarshal(r *Reader) (err error) {
  90  	*hc = hpkeCiphertext{}
  91  	var ok bool
  92  	hc.kemOutput, ok = r.readOpaqueVec()
  93  	if !ok {
  94  		return errUnexpectedEOF
  95  	}
  96  	hc.ciphertext, ok = r.readOpaqueVec()
  97  	if !ok {
  98  		return errUnexpectedEOF
  99  	}
 100  	return nil
 101  }
 102  
 103  func (hc *hpkeCiphertext) marshal(w *Writer) {
 104  	w.writeOpaqueVec(hc.kemOutput)
 105  	w.writeOpaqueVec(hc.ciphertext)
 106  }
 107