77package crypto
88
99import (
10+ "bytes"
1011 "encoding/json"
12+ "fmt"
1113
1214 "github.com/tidwall/sjson"
1315
1416 "maunium.net/go/mautrix"
1517 "maunium.net/go/mautrix/crypto/canonicaljson"
18+ "maunium.net/go/mautrix/crypto/goolm/account"
1619 "maunium.net/go/mautrix/crypto/olm"
1720 "maunium.net/go/mautrix/crypto/signatures"
1821 "maunium.net/go/mautrix/id"
1922)
2023
2124type OlmAccount struct {
22- Internal olm.Account
25+ InternalLibolm olm.Account
26+ InternalGoolm olm.Account
2327 signingKey id.SigningKey
2428 identityKey id.IdentityKey
2529 Shared bool
2630 KeyBackupVersion id.KeyBackupVersion
2731}
2832
2933func NewOlmAccount () * OlmAccount {
30- account , err := olm .NewAccount ()
34+ libolmAccount , err := olm .NewAccount ()
35+ if err != nil {
36+ panic (err )
37+ }
38+ pickled , err := libolmAccount .Pickle ([]byte ("key" ))
39+ if err != nil {
40+ panic (err )
41+ }
42+ goolmAccount , err := account .AccountFromPickled (pickled , []byte ("key" ))
3143 if err != nil {
3244 panic (err )
3345 }
3446 return & OlmAccount {
35- Internal : account ,
47+ InternalLibolm : libolmAccount ,
48+ InternalGoolm : goolmAccount ,
3649 }
3750}
3851
3952func (account * OlmAccount ) Keys () (id.SigningKey , id.IdentityKey ) {
4053 if len (account .signingKey ) == 0 || len (account .identityKey ) == 0 {
4154 var err error
42- account .signingKey , account .identityKey , err = account .Internal .IdentityKeys ()
55+ account .signingKey , account .identityKey , err = account .InternalLibolm .IdentityKeys ()
56+ if err != nil {
57+ panic (err )
58+ }
59+ goolmSigningKey , goolmIdentityKey , err := account .InternalGoolm .IdentityKeys ()
4360 if err != nil {
4461 panic (err )
4562 }
63+ if account .signingKey != goolmSigningKey {
64+ panic ("account signing keys not equal" )
65+ }
66+ if account .identityKey != goolmIdentityKey {
67+ panic ("account identity keys not equal" )
68+ }
4669 }
4770 return account .signingKey , account .identityKey
4871}
4972
5073func (account * OlmAccount ) SigningKey () id.SigningKey {
5174 if len (account .signingKey ) == 0 {
5275 var err error
53- account .signingKey , account .identityKey , err = account .Internal .IdentityKeys ()
76+ account .signingKey , account .identityKey , err = account .InternalLibolm .IdentityKeys ()
77+ if err != nil {
78+ panic (err )
79+ }
80+ goolmSigningKey , goolmIdentityKey , err := account .InternalGoolm .IdentityKeys ()
5481 if err != nil {
5582 panic (err )
5683 }
84+ if account .signingKey != goolmSigningKey {
85+ panic ("account signing keys not equal" )
86+ }
87+ if account .identityKey != goolmIdentityKey {
88+ panic ("account identity keys not equal" )
89+ }
5790 }
5891 return account .signingKey
5992}
6093
6194func (account * OlmAccount ) IdentityKey () id.IdentityKey {
6295 if len (account .identityKey ) == 0 {
6396 var err error
64- account .signingKey , account .identityKey , err = account .Internal .IdentityKeys ()
97+ account .signingKey , account .identityKey , err = account .InternalLibolm .IdentityKeys ()
98+ if err != nil {
99+ panic (err )
100+ }
101+ goolmSigningKey , goolmIdentityKey , err := account .InternalGoolm .IdentityKeys ()
65102 if err != nil {
66103 panic (err )
67104 }
105+ if account .signingKey != goolmSigningKey {
106+ panic ("account signing keys not equal" )
107+ }
108+ if account .identityKey != goolmIdentityKey {
109+ panic ("account identity keys not equal" )
110+ }
68111 }
69112 return account .identityKey
70113}
@@ -78,7 +121,15 @@ func (account *OlmAccount) SignJSON(obj any) (string, error) {
78121 }
79122 objJSON , _ = sjson .DeleteBytes (objJSON , "unsigned" )
80123 objJSON , _ = sjson .DeleteBytes (objJSON , "signatures" )
81- signed , err := account .Internal .Sign (canonicaljson .CanonicalJSONAssumeValid (objJSON ))
124+ signed , err := account .InternalLibolm .Sign (canonicaljson .CanonicalJSONAssumeValid (objJSON ))
125+ goolmSigned , goolmErr := account .InternalGoolm .Sign (canonicaljson .CanonicalJSONAssumeValid (objJSON ))
126+ if err != nil {
127+ if goolmErr == nil {
128+ panic ("libolm errored, but goolm did not on account.SignJSON" )
129+ }
130+ } else if ! bytes .Equal (signed , goolmSigned ) {
131+ panic ("libolm and goolm signed are not equal in account.SignJSON" )
132+ }
82133 return string (signed ), err
83134}
84135
@@ -102,19 +153,36 @@ func (account *OlmAccount) getInitialKeys(userID id.UserID, deviceID id.DeviceID
102153 return deviceKeys
103154}
104155
105- func (account * OlmAccount ) getOneTimeKeys (userID id.UserID , deviceID id.DeviceID , currentOTKCount int ) map [id.KeyID ]mautrix.OneTimeKey {
106- newCount := int (account . Internal .MaxNumberOfOneTimeKeys ()/ 2 ) - currentOTKCount
156+ func (a * OlmAccount ) getOneTimeKeys (userID id.UserID , deviceID id.DeviceID , currentOTKCount int ) map [id.KeyID ]mautrix.OneTimeKey {
157+ newCount := int (a . InternalLibolm .MaxNumberOfOneTimeKeys ()/ 2 ) - currentOTKCount
107158 if newCount > 0 {
108- account .Internal .GenOneTimeKeys (uint (newCount ))
159+ a .InternalLibolm .GenOneTimeKeys (uint (newCount ))
160+
161+ pickled , err := a .InternalLibolm .Pickle ([]byte ("key" ))
162+ if err != nil {
163+ panic (err )
164+ }
165+ a .InternalGoolm , err = account .AccountFromPickled (pickled , []byte ("key" ))
166+ if err != nil {
167+ panic (err )
168+ }
109169 }
110170 oneTimeKeys := make (map [id.KeyID ]mautrix.OneTimeKey )
111- internalKeys , err := account .Internal .OneTimeKeys ()
171+ internalKeys , err := a .InternalLibolm .OneTimeKeys ()
172+ if err != nil {
173+ panic (err )
174+ }
175+ goolmInternalKeys , err := a .InternalGoolm .OneTimeKeys ()
112176 if err != nil {
113177 panic (err )
114178 }
115179 for keyID , key := range internalKeys {
180+ if goolmInternalKeys [keyID ] != key {
181+ panic (fmt .Sprintf ("key %s not found in getOneTimeKeys" , keyID ))
182+ }
183+
116184 key := mautrix.OneTimeKey {Key : key }
117- signature , _ := account .SignJSON (key )
185+ signature , _ := a .SignJSON (key )
118186 key .Signatures = signatures .NewSingleSignature (userID , id .KeyAlgorithmEd25519 , deviceID .String (), signature )
119187 key .IsSigned = true
120188 oneTimeKeys [id .NewKeyID (id .KeyAlgorithmSignedCurve25519 , keyID )] = key
0 commit comments