key_package_crypto.mx raw
1 package mls
2
3 // MLS key package crypto operations (RFC 9420 ยง10).
4
5 var (
6 errKeyPackageVersionMismatch error
7 errKeyPackageSuiteMismatch error
8 errKeyPackageBadSource error
9 errKeyPackageBadSignature error
10 errKeyPackageKeysMatch error
11 )
12
13 func (pkg *KeyPackage) sign(signerPriv []byte) (err error) {
14 var w Writer
15 pkg.marshalTBS(&w)
16 rawTBS, err := w.bytes()
17 if err != nil {
18 return err
19 }
20 sig, err := pkg.cipherSuite.signWithLabel(signerPriv, []byte("KeyPackageTBS"), rawTBS)
21 if err != nil {
22 return err
23 }
24 pkg.signature = sig
25 return nil
26 }
27
28 func (pkg *KeyPackage) verifySignature() (ok bool) {
29 var w Writer
30 pkg.marshalTBS(&w)
31 rawTBS, err := w.bytes()
32 if err != nil {
33 return false
34 }
35 return pkg.cipherSuite.verifyWithLabel(pkg.leafNode.signatureKey, []byte("KeyPackageTBS"), rawTBS, pkg.signature)
36 }
37
38 func (pkg *KeyPackage) verify(ctx *groupContext) (err error) {
39 if pkg.version != ctx.version {
40 return errKeyPackageVersionMismatch
41 }
42 if pkg.cipherSuite != ctx.cipherSuite {
43 return errKeyPackageSuiteMismatch
44 }
45 if pkg.leafNode.leafNodeSource != leafNodeSourceKeyPackage {
46 return errKeyPackageBadSource
47 }
48 if !pkg.verifySignature() {
49 return errKeyPackageBadSignature
50 }
51 if bytesEqual(pkg.leafNode.encryptionKey, pkg.initKey) {
52 return errKeyPackageKeysMatch
53 }
54 return nil
55 }
56
57 func (pkg *KeyPackage) GenerateRef() (v []byte, err2 error) {
58 var w Writer
59 pkg.marshal(&w)
60 raw, err := w.bytes()
61 if err != nil {
62 return nil, err
63 }
64 h, err := pkg.cipherSuite.refHash([]byte("MLS 1.0 KeyPackage Reference"), raw)
65 if err != nil {
66 return nil, err
67 }
68 return h, nil
69 }
70
71 // GenerateKeyPairPackage creates a new key pair package for suite 0x0003.
72 // nowUnix is the current time as Unix seconds (caller provides from DOM/SW context).
73 func GenerateKeyPairPackage(cs CipherSuite, credential *Credential, nowUnix int64) (p *KeyPairPackage, err error) {
74 return GenerateKeyPairPackageWithOptions(cs, credential, nil, nowUnix)
75 }
76
77 // GenerateKeyPairPackageWithOptions creates a key pair package with options.
78 func GenerateKeyPairPackageWithOptions(cs CipherSuite, credential *Credential, opts *KeyPackageOptions, nowUnix int64) (p *KeyPairPackage, err2 error) {
79 initPub, initPriv, err := cs.generateEncryptionKeyPair()
80 if err != nil {
81 return nil, err
82 }
83 encPub, encPriv, err := cs.generateEncryptionKeyPair()
84 if err != nil {
85 return nil, err
86 }
87 sigPub, sigPriv, err := cs.generateSignatureKeyPair()
88 if err != nil {
89 return nil, err
90 }
91
92 var capExts []extensionType
93 var leafExts []extension
94 var kpExts []extension
95 if opts != nil {
96 capExts = opts.CapabilityExtensions
97 leafExts = opts.LeafExtensions
98 kpExts = opts.KeyPackageExtensions
99 }
100 if capExts == nil {
101 capExts = []extensionType{extensionTypeRatchetTree}
102 }
103
104 // Lifetime: now - 1h to now + 84 days
105 notBefore := nowUnix - 3600
106 notAfter := nowUnix + 84*24*3600
107
108 keyPkg := KeyPackage{
109 version: protocolVersionMLS10,
110 cipherSuite: cs,
111 initKey: initPub,
112 leafNode: leafNode{
113 encryptionKey: encPub,
114 signatureKey: sigPub,
115 leafNodeSource: leafNodeSourceKeyPackage,
116 credential: *credential,
117 capabilities: capabilities{
118 versions: []protocolVersion{protocolVersionMLS10},
119 cipherSuites: []CipherSuite{cs},
120 extensions: capExts,
121 proposals: []proposalType{proposalTypeAdd, proposalTypeUpdate, proposalTypeRemove},
122 credentials: []credentialType{credentialTypeBasic},
123 },
124 lifetime: &lifetime{notBefore: uint64(notBefore), notAfter: uint64(notAfter)},
125 extensions: leafExts,
126 },
127 extensions: kpExts,
128 }
129
130 if e := keyPkg.leafNode.sign(cs, nil, 0, sigPriv); e != nil {
131 return nil, e
132 }
133 if e := keyPkg.sign(sigPriv); e != nil {
134 return nil, e
135 }
136
137 return &KeyPairPackage{
138 Public: keyPkg,
139 Private: PrivateKeyPackage{
140 InitKey: initPriv,
141 EncryptionKey: encPriv,
142 SignatureKey: sigPriv,
143 },
144 }, nil
145 }
146