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