key_package.mx raw
1 package mls
2
3 // MLS key packages (RFC 9420 ยง10).
4
5 // KeyPackage provides public information: supported version/cipher suite,
6 // public keys, and credentials.
7 type KeyPackage struct {
8 version protocolVersion
9 cipherSuite CipherSuite
10 initKey hpkePublicKey
11 leafNode leafNode
12 extensions []extension
13 signature []byte
14 }
15
16 func (pkg *KeyPackage) unmarshal(r *Reader) error {
17 *pkg = KeyPackage{}
18
19 v, ok := r.readUint16()
20 if !ok {
21 return errUnexpectedEOF
22 }
23 pkg.version = protocolVersion(v)
24 if pkg.version != protocolVersionMLS10 {
25 return errInvalidVersion
26 }
27
28 v, ok = r.readUint16()
29 if !ok {
30 return errUnexpectedEOF
31 }
32 pkg.cipherSuite = CipherSuite(v)
33
34 pkg.initKey, ok = r.readOpaqueVec()
35 if !ok {
36 return errUnexpectedEOF
37 }
38
39 if err := pkg.leafNode.unmarshal(r); err != nil {
40 return err
41 }
42
43 exts, err := unmarshalExtensionVec(r)
44 if err != nil {
45 return err
46 }
47 pkg.extensions = exts
48
49 pkg.signature, ok = r.readOpaqueVec()
50 if !ok {
51 return errUnexpectedEOF
52 }
53 return nil
54 }
55
56 func (pkg *KeyPackage) marshalTBS(w *Writer) {
57 w.addUint16(uint16(pkg.version))
58 w.addUint16(uint16(pkg.cipherSuite))
59 w.writeOpaqueVec([]byte(pkg.initKey))
60 pkg.leafNode.marshal(w)
61 marshalExtensionVec(w, pkg.extensions)
62 }
63
64 func (pkg *KeyPackage) marshal(w *Writer) {
65 pkg.marshalTBS(w)
66 w.writeOpaqueVec(pkg.signature)
67 }
68
69 // UnmarshalKeyPackage reads a key package from an MLS message envelope.
70 func UnmarshalKeyPackage(raw []byte) (*KeyPackage, error) {
71 var msg mlsMessage
72 if err := unmarshalRaw(raw, &msg); err != nil {
73 return nil, err
74 }
75 if msg.wireFormat != wireFormatMLSKeyPackage {
76 return nil, errInvalidWireFormat
77 }
78 return msg.keyPackage, nil
79 }
80
81 // UnmarshalRawKeyPackage reads a key package from bare TLS bytes (no envelope).
82 // This is the format used by NIP-EE (kind 443 events).
83 func UnmarshalRawKeyPackage(raw []byte) (*KeyPackage, error) {
84 r := newReader(raw)
85 pkg := &KeyPackage{}
86 if err := pkg.unmarshal(&r); err != nil {
87 return nil, err
88 }
89 if !r.empty() {
90 return nil, errExcessBytes
91 }
92 return pkg, nil
93 }
94
95 // Bytes encodes the key package in an MLSMessage envelope.
96 func (pkg *KeyPackage) Bytes() []byte {
97 raw, err := marshalRaw(&mlsMessage{
98 version: protocolVersionMLS10,
99 wireFormat: wireFormatMLSKeyPackage,
100 keyPackage: pkg,
101 })
102 if err != nil {
103 panic("mls: failed to marshal key package")
104 }
105 return raw
106 }
107
108 // RawBytes encodes the key package as bare TLS bytes (no envelope).
109 func (pkg *KeyPackage) RawBytes() []byte {
110 var w Writer
111 pkg.marshal(&w)
112 raw, err := w.bytes()
113 if err != nil {
114 panic("mls: failed to marshal raw key package")
115 }
116 return raw
117 }
118
119 // KeyPackageRef is a hash uniquely identifying a key package.
120 type KeyPackageRef []byte
121
122 func (ref KeyPackageRef) equal(other KeyPackageRef) bool {
123 return bytesEqual([]byte(ref), []byte(other))
124 }
125
126 // PrivateKeyPackage holds private key material.
127 type PrivateKeyPackage struct {
128 InitKey []byte
129 EncryptionKey []byte
130 SignatureKey []byte
131 }
132
133 // KeyPairPackage holds both public and private information.
134 type KeyPairPackage struct {
135 Public KeyPackage
136 Private PrivateKeyPackage
137 }
138
139 // Marshal serializes the KeyPairPackage for persistence.
140 // Format: opaque_vec(publicRawBytes) || opaque_vec(InitKey) || opaque_vec(EncryptionKey) || opaque_vec(SignatureKey)
141 func (kpp *KeyPairPackage) Marshal() ([]byte, error) {
142 var w Writer
143 w.writeOpaqueVec(kpp.Public.RawBytes())
144 w.writeOpaqueVec(kpp.Private.InitKey)
145 w.writeOpaqueVec(kpp.Private.EncryptionKey)
146 w.writeOpaqueVec(kpp.Private.SignatureKey)
147 return w.bytes()
148 }
149
150 // UnmarshalKeyPairPackage restores a KeyPairPackage from bytes produced by Marshal.
151 func UnmarshalKeyPairPackage(raw []byte) (*KeyPairPackage, error) {
152 r := newReader(raw)
153
154 pubBytes, ok := r.readOpaqueVec()
155 if !ok {
156 return nil, errUnexpectedEOF
157 }
158 pub, err := UnmarshalRawKeyPackage(pubBytes)
159 if err != nil {
160 return nil, err
161 }
162
163 initKey, ok := r.readOpaqueVec()
164 if !ok {
165 return nil, errUnexpectedEOF
166 }
167 encKey, ok := r.readOpaqueVec()
168 if !ok {
169 return nil, errUnexpectedEOF
170 }
171 sigKey, ok := r.readOpaqueVec()
172 if !ok {
173 return nil, errUnexpectedEOF
174 }
175
176 return &KeyPairPackage{
177 Public: *pub,
178 Private: PrivateKeyPackage{
179 InitKey: initKey,
180 EncryptionKey: encKey,
181 SignatureKey: sigKey,
182 },
183 }, nil
184 }
185
186 // KeyPackageOptions configures key package generation.
187 type KeyPackageOptions struct {
188 CapabilityExtensions []extensionType
189 LeafExtensions []extension
190 KeyPackageExtensions []extension
191 }
192