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 []byte
11 leafNode leafNode
12 extensions []extension
13 signature []byte
14 }
15
16 func (pkg *KeyPackage) unmarshal(r *Reader) (err 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 e := pkg.leafNode.unmarshal(r); e != nil {
40 return e
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) CipherSuiteValue() (n uint16) {
57 return uint16(pkg.cipherSuite)
58 }
59
60 func (pkg *KeyPackage) marshalTBS(w *Writer) {
61 w.addUint16(uint16(pkg.version))
62 w.addUint16(uint16(pkg.cipherSuite))
63 w.writeOpaqueVec([]byte(pkg.initKey))
64 pkg.leafNode.marshal(w)
65 marshalExtensionVec(w, pkg.extensions)
66 }
67
68 func (pkg *KeyPackage) marshal(w *Writer) {
69 pkg.marshalTBS(w)
70 w.writeOpaqueVec(pkg.signature)
71 }
72
73 // UnmarshalKeyPackage reads a key package from an MLS message envelope.
74 func UnmarshalKeyPackage(raw []byte) (p *KeyPackage, err2 error) {
75 var msg mlsMessage
76 if err := unmarshalRaw(raw, &msg); err != nil {
77 return nil, err
78 }
79 if msg.wireFormat != wireFormatMLSKeyPackage {
80 return nil, errInvalidWireFormat
81 }
82 return msg.keyPackage, nil
83 }
84
85 // UnmarshalRawKeyPackage reads a key package from bare TLS bytes (no envelope).
86 // This is the format used by NIP-EE (kind 443 events).
87 func UnmarshalRawKeyPackage(raw []byte) (p *KeyPackage, err2 error) {
88 r := newReader(raw)
89 pkg := &KeyPackage{}
90 if err := pkg.unmarshal(&r); err != nil {
91 return nil, err
92 }
93 if !r.empty() {
94 return nil, errExcessBytes
95 }
96 return pkg, nil
97 }
98
99 // Bytes encodes the key package in an MLSMessage envelope.
100 func (pkg *KeyPackage) Bytes() (buf []byte) {
101 raw, err := marshalRaw(&mlsMessage{
102 version: protocolVersionMLS10,
103 wireFormat: wireFormatMLSKeyPackage,
104 keyPackage: pkg,
105 })
106 if err != nil {
107 panic("mls: failed to marshal key package")
108 }
109 return raw
110 }
111
112 // RawBytes encodes the key package as bare TLS bytes (no envelope).
113 func (pkg *KeyPackage) RawBytes() (buf []byte) {
114 var w Writer
115 pkg.marshal(&w)
116 raw, err := w.bytes()
117 if err != nil {
118 panic("mls: failed to marshal raw key package")
119 }
120 return raw
121 }
122
123 // keyPackageRefEqual reports whether two key package references are equal.
124 func keyPackageRefEqual(ref []byte, other []byte) (ok bool) {
125 return bytesEqual(ref, other)
126 }
127
128 // PrivateKeyPackage holds private key material.
129 type PrivateKeyPackage struct {
130 InitKey []byte
131 EncryptionKey []byte
132 SignatureKey []byte
133 }
134
135 // KeyPairPackage holds both public and private information.
136 type KeyPairPackage struct {
137 Public KeyPackage
138 Private PrivateKeyPackage
139 }
140
141 // Marshal serializes the KeyPairPackage for persistence.
142 // Format: opaque_vec(publicRawBytes) || opaque_vec(InitKey) || opaque_vec(EncryptionKey) || opaque_vec(SignatureKey)
143 func (kpp *KeyPairPackage) Marshal() (out []byte, err error) {
144 var w Writer
145 w.writeOpaqueVec(kpp.Public.RawBytes())
146 w.writeOpaqueVec(kpp.Private.InitKey)
147 w.writeOpaqueVec(kpp.Private.EncryptionKey)
148 w.writeOpaqueVec(kpp.Private.SignatureKey)
149 return w.bytes()
150 }
151
152 // UnmarshalKeyPairPackage restores a KeyPairPackage from bytes produced by Marshal.
153 func UnmarshalKeyPairPackage(raw []byte) (p *KeyPairPackage, err2 error) {
154 r := newReader(raw)
155
156 pubBytes, ok := r.readOpaqueVec()
157 if !ok {
158 return nil, errUnexpectedEOF
159 }
160 pub, err := UnmarshalRawKeyPackage(pubBytes)
161 if err != nil {
162 return nil, err
163 }
164
165 initKey, ok := r.readOpaqueVec()
166 if !ok {
167 return nil, errUnexpectedEOF
168 }
169 encKey, ok := r.readOpaqueVec()
170 if !ok {
171 return nil, errUnexpectedEOF
172 }
173 sigKey, ok := r.readOpaqueVec()
174 if !ok {
175 return nil, errUnexpectedEOF
176 }
177
178 return &KeyPairPackage{
179 Public: *pub,
180 Private: PrivateKeyPackage{
181 InitKey: initKey,
182 EncryptionKey: encKey,
183 SignatureKey: sigKey,
184 },
185 }, nil
186 }
187
188 // KeyPackageOptions configures key package generation.
189 type KeyPackageOptions struct {
190 CapabilityExtensions []extensionType
191 LeafExtensions []extension
192 KeyPackageExtensions []extension
193 }
194