mautrix-go/crypto/cross_sign_pubkey.go
Tulir Asokan 315d2ab17d
Some checks are pending
Go / Lint (latest) (push) Waiting to run
Go / Build (old, libolm) (push) Waiting to run
Go / Build (latest, libolm) (push) Waiting to run
Go / Build (old, goolm) (push) Waiting to run
Go / Build (latest, goolm) (push) Waiting to run
all: fix staticcheck issues
2025-12-08 00:07:25 +02:00

104 lines
2.8 KiB
Go

// Copyright (c) 2024 Tulir Asokan
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package crypto
import (
"context"
"fmt"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/id"
)
type CrossSigningPublicKeysCache struct {
MasterKey id.Ed25519
SelfSigningKey id.Ed25519
UserSigningKey id.Ed25519
}
func (mach *OlmMachine) GetOwnVerificationStatus(ctx context.Context) (hasKeys, isVerified bool, err error) {
pubkeys := mach.GetOwnCrossSigningPublicKeys(ctx)
if pubkeys != nil {
hasKeys = true
isVerified, err = mach.CryptoStore.IsKeySignedBy(
ctx, mach.Client.UserID, mach.GetAccount().SigningKey(), mach.Client.UserID, pubkeys.SelfSigningKey,
)
if err != nil {
err = fmt.Errorf("failed to check if current device is signed by own self-signing key: %w", err)
}
}
return
}
func (mach *OlmMachine) GetOwnCrossSigningPublicKeys(ctx context.Context) *CrossSigningPublicKeysCache {
if mach.crossSigningPubkeys != nil {
return mach.crossSigningPubkeys
}
if mach.CrossSigningKeys != nil {
mach.crossSigningPubkeys = mach.CrossSigningKeys.PublicKeys()
return mach.crossSigningPubkeys
}
if mach.crossSigningPubkeysFetched {
return nil
}
cspk, err := mach.GetCrossSigningPublicKeys(ctx, mach.Client.UserID)
if err != nil {
mach.Log.Error().Err(err).Msg("Failed to get own cross-signing public keys")
return nil
}
mach.crossSigningPubkeys = cspk
mach.crossSigningPubkeysFetched = true
return mach.crossSigningPubkeys
}
func (mach *OlmMachine) GetCrossSigningPublicKeys(ctx context.Context, userID id.UserID) (*CrossSigningPublicKeysCache, error) {
dbKeys, err := mach.CryptoStore.GetCrossSigningKeys(ctx, userID)
if err != nil {
return nil, fmt.Errorf("failed to get keys from database: %w", err)
}
if len(dbKeys) > 0 {
masterKey, ok := dbKeys[id.XSUsageMaster]
if ok {
selfSigning := dbKeys[id.XSUsageSelfSigning]
userSigning := dbKeys[id.XSUsageUserSigning]
return &CrossSigningPublicKeysCache{
MasterKey: masterKey.Key,
SelfSigningKey: selfSigning.Key,
UserSigningKey: userSigning.Key,
}, nil
}
}
keys, err := mach.Client.QueryKeys(ctx, &mautrix.ReqQueryKeys{
DeviceKeys: mautrix.DeviceKeysRequest{
userID: mautrix.DeviceIDList{},
},
})
if err != nil {
return nil, fmt.Errorf("failed to query keys: %w", err)
}
var cspk CrossSigningPublicKeysCache
masterKeys, ok := keys.MasterKeys[userID]
if !ok {
return nil, nil
}
cspk.MasterKey = masterKeys.FirstKey()
selfSigningKeys, ok := keys.SelfSigningKeys[userID]
if !ok {
return nil, nil
}
cspk.SelfSigningKey = selfSigningKeys.FirstKey()
userSigningKeys, ok := keys.UserSigningKeys[userID]
if ok {
cspk.UserSigningKey = userSigningKeys.FirstKey()
}
return &cspk, nil
}