Skip to content

Commit

Permalink
Trust key backups if the public key matches
Browse files Browse the repository at this point in the history
  • Loading branch information
bradtgmurray committed Feb 12, 2025
1 parent aaad511 commit f764058
Showing 1 changed file with 13 additions and 2 deletions.
15 changes: 13 additions & 2 deletions crypto/keybackup.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package crypto

import (
"context"
"encoding/base64"
"fmt"
"time"

Expand All @@ -21,7 +22,7 @@ func (mach *OlmMachine) DownloadAndStoreLatestKeyBackup(ctx context.Context, meg

ctx = log.WithContext(ctx)

versionInfo, err := mach.GetAndVerifyLatestKeyBackupVersion(ctx)
versionInfo, err := mach.GetAndVerifyLatestKeyBackupVersion(ctx, megolmBackupKey)
if err != nil {
return "", err
} else if versionInfo == nil {
Expand All @@ -32,7 +33,7 @@ func (mach *OlmMachine) DownloadAndStoreLatestKeyBackup(ctx context.Context, meg
return versionInfo.Version, err
}

func (mach *OlmMachine) GetAndVerifyLatestKeyBackupVersion(ctx context.Context) (*mautrix.RespRoomKeysVersion[backup.MegolmAuthData], error) {
func (mach *OlmMachine) GetAndVerifyLatestKeyBackupVersion(ctx context.Context, megolmBackupKey *backup.MegolmBackupKey) (*mautrix.RespRoomKeysVersion[backup.MegolmAuthData], error) {
versionInfo, err := mach.Client.GetKeyBackupLatestVersion(ctx)
if err != nil {
return nil, err
Expand All @@ -48,6 +49,16 @@ func (mach *OlmMachine) GetAndVerifyLatestKeyBackupVersion(ctx context.Context)
Stringer("key_backup_version", versionInfo.Version).
Logger()

// https://spec.matrix.org/v1.10/client-server-api/#server-side-key-backups
// "Clients must only store keys in backups after they have ensured that the auth_data is trusted. This can be done either...
// ...by deriving the public key from a private key that it obtained from a trusted source. Trusted sources for the private
// key include the user entering the key, retrieving the key stored in secret storage, or obtaining the key via secret sharing
// from a verified device belonging to the same user."
if versionInfo.AuthData.PublicKey == id.Ed25519(base64.RawStdEncoding.EncodeToString(megolmBackupKey.PublicKey().Bytes())) {
return versionInfo, nil
}

// "...or checking that it is signed by the user’s master cross-signing key or by a verified device belonging to the same user"
userSignatures, ok := versionInfo.AuthData.Signatures[mach.Client.UserID]
if !ok {
return nil, fmt.Errorf("no signature from user %s found in key backup", mach.Client.UserID)
Expand Down

0 comments on commit f764058

Please sign in to comment.