Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Signed-off-by: Sumner Evans <sumner@beeper.com>
  • Loading branch information
sumnerevans committed Jan 12, 2024
1 parent 1ec64bb commit 1e9ae4a
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 20 deletions.
11 changes: 6 additions & 5 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"go.mau.fi/util/retryafter"
"maunium.net/go/maulogger/v2/maulogadapt"

"maunium.net/go/mautrix/crypto/backup"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
"maunium.net/go/mautrix/pushrules"
Expand Down Expand Up @@ -1944,7 +1945,7 @@ func (cli *Client) GetKeyChanges(ctx context.Context, from, to string) (resp *Re
// GetKeyBackup retrieves the keys from the backup.
//
// See: https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3room_keyskeys
func (cli *Client) GetKeyBackup(ctx context.Context, version string) (resp *RespRoomKeys, err error) {
func (cli *Client) GetKeyBackup(ctx context.Context, version string) (resp *RespRoomKeys[backup.EncryptedMegolmSessionData], err error) {

Check failure on line 1948 in client.go

View workflow job for this annotation

GitHub Actions / lint

undefined: backup.EncryptedMegolmSessionData

Check failure on line 1948 in client.go

View workflow job for this annotation

GitHub Actions / build (1.20)

undefined: backup.EncryptedMegolmSessionData

Check failure on line 1948 in client.go

View workflow job for this annotation

GitHub Actions / build (1.21)

undefined: backup.EncryptedMegolmSessionData

Check failure on line 1948 in client.go

View workflow job for this annotation

GitHub Actions / lint

undefined: backup.EncryptedMegolmSessionData

Check failure on line 1948 in client.go

View workflow job for this annotation

GitHub Actions / build (1.20)

undefined: backup.EncryptedMegolmSessionData

Check failure on line 1948 in client.go

View workflow job for this annotation

GitHub Actions / build (1.21)

undefined: backup.EncryptedMegolmSessionData
urlPath := cli.BuildURLWithQuery(ClientURLPath{"v3", "room_keys", "keys"}, map[string]string{
"version": version,
})
Expand Down Expand Up @@ -1977,7 +1978,7 @@ func (cli *Client) DeleteKeyBackup(ctx context.Context, version string) (resp *R
// GetKeyBackupForRoom retrieves the keys from the backup for the given room.
//
// See: https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3room_keyskeysroomid
func (cli *Client) GetKeyBackupForRoom(ctx context.Context, version string, roomID id.RoomID) (resp *RespRoomKeyBackup, err error) {
func (cli *Client) GetKeyBackupForRoom(ctx context.Context, version string, roomID id.RoomID) (resp *RespRoomKeyBackup[backup.EncryptedMegolmSessionData], err error) {

Check failure on line 1981 in client.go

View workflow job for this annotation

GitHub Actions / lint

undefined: backup.EncryptedMegolmSessionData

Check failure on line 1981 in client.go

View workflow job for this annotation

GitHub Actions / build (1.20)

undefined: backup.EncryptedMegolmSessionData

Check failure on line 1981 in client.go

View workflow job for this annotation

GitHub Actions / build (1.21)

undefined: backup.EncryptedMegolmSessionData

Check failure on line 1981 in client.go

View workflow job for this annotation

GitHub Actions / lint

undefined: backup.EncryptedMegolmSessionData

Check failure on line 1981 in client.go

View workflow job for this annotation

GitHub Actions / build (1.20)

undefined: backup.EncryptedMegolmSessionData

Check failure on line 1981 in client.go

View workflow job for this annotation

GitHub Actions / build (1.21)

undefined: backup.EncryptedMegolmSessionData
urlPath := cli.BuildURLWithQuery(ClientURLPath{"v3", "room_keys", "keys", roomID.String()}, map[string]string{
"version": version,
})
Expand Down Expand Up @@ -2011,7 +2012,7 @@ func (cli *Client) DeleteKeysFromBackupForRoom(ctx context.Context, version stri
// GetKeyBackupForRoomAndSession retrieves a key from the backup.
//
// See: https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3room_keyskeysroomidsessionid
func (cli *Client) GetKeyBackupForRoomAndSession(ctx context.Context, version string, roomID id.RoomID, sessionID id.SessionID) (resp *RespKeyBackupData, err error) {
func (cli *Client) GetKeyBackupForRoomAndSession(ctx context.Context, version string, roomID id.RoomID, sessionID id.SessionID) (resp *RespKeyBackupData[backup.EncryptedMegolmSessionData], err error) {

Check failure on line 2015 in client.go

View workflow job for this annotation

GitHub Actions / lint

undefined: backup.EncryptedMegolmSessionData

Check failure on line 2015 in client.go

View workflow job for this annotation

GitHub Actions / build (1.20)

undefined: backup.EncryptedMegolmSessionData

Check failure on line 2015 in client.go

View workflow job for this annotation

GitHub Actions / build (1.21)

undefined: backup.EncryptedMegolmSessionData

Check failure on line 2015 in client.go

View workflow job for this annotation

GitHub Actions / lint

undefined: backup.EncryptedMegolmSessionData

Check failure on line 2015 in client.go

View workflow job for this annotation

GitHub Actions / build (1.20)

undefined: backup.EncryptedMegolmSessionData

Check failure on line 2015 in client.go

View workflow job for this annotation

GitHub Actions / build (1.21)

undefined: backup.EncryptedMegolmSessionData
urlPath := cli.BuildURLWithQuery(ClientURLPath{"v3", "room_keys", "keys", roomID.String(), sessionID.String()}, map[string]string{
"version": version,
})
Expand Down Expand Up @@ -2044,7 +2045,7 @@ func (cli *Client) DeleteKeysInBackupForRoomAndSession(ctx context.Context, vers
// GetKeyBackupLatestVersion returns information about the latest backup version.
//
// See: https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3room_keysversion
func (cli *Client) GetKeyBackupLatestVersion(ctx context.Context) (resp *RespRoomKeysVersion, err error) {
func (cli *Client) GetKeyBackupLatestVersion(ctx context.Context) (resp *RespRoomKeysVersion[backup.MegolmAuthData], err error) {
urlPath := cli.BuildClientURL("v3", "room_keys", "version")
_, err = cli.MakeRequest(ctx, http.MethodGet, urlPath, nil, &resp)
return
Expand All @@ -2062,7 +2063,7 @@ func (cli *Client) CreateKeyBackupVersion(ctx context.Context, req *ReqRoomKeysV
// GetKeyBackupVersion returns information about an existing key backup.
//
// See: https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3room_keysversionversion
func (cli *Client) GetKeyBackupVersion(ctx context.Context, version string) (resp *RespRoomKeysVersion, err error) {
func (cli *Client) GetKeyBackupVersion(ctx context.Context, version string) (resp *RespRoomKeysVersion[backup.MegolmAuthData], err error) {
urlPath := cli.BuildClientURL("v3", "room_keys", "version", version)
_, err = cli.MakeRequest(ctx, http.MethodGet, urlPath, nil, &resp)
return
Expand Down
22 changes: 18 additions & 4 deletions crypto/backup/ed25519aessha2.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package backup

import (
"crypto/ed25519"

"maunium.net/go/mautrix/crypto/signatures"
"maunium.net/go/mautrix/id"
)

// MegolmAuthData is the auth_data when the key backup is created with
// the [id.KeyBackupAlgorithmCurve25519AESSHA2] algorithm as defined in
// the [id.KeyBackupAlgorithmMegolmBackupV1] algorithm as defined in
// [Section 11.12.3.2.2 of the Spec].
//
// [Section 11.12.3.2.2 of the Spec]: https://spec.matrix.org/v1.9/client-server-api/#backup-algorithm-mmegolm_backupv1curve25519-aes-sha2
Expand All @@ -15,11 +17,23 @@ type MegolmAuthData struct {
Signatures signatures.Signatures `json:"signatures"`
}

// MegolmSessionData is the session_data when the key backup is created
// with the [id.KeyBackupAlgorithmCurve25519AESSHA2] algorithm as defined in
// [Section 11.12.3.2.2 of the Spec].
// EncryptedSessionData is the encrypted session_data field of a key backup as
// defined in [Section 11.12.3.2.2 of the Spec].
//
// The type parameter B represents the format of the session data contained in
// the encrypted payload.
//
// [Section 11.12.3.2.2 of the Spec]: https://spec.matrix.org/v1.9/client-server-api/#backup-algorithm-mmegolm_backupv1curve25519-aes-sha2
type EncryptedSessionData[T any] struct {
Ciphertext []byte `json:"ciphertext"`
Ephemeral []byte `json:"ephemeral"`
Mac []byte `json:"mac"`
}

func (e *EncryptedSessionData[T]) Encrypt(recoveryKey ed25519.PrivateKey) (*T, error) {
return nil, nil
}

type MegolmSessionData struct {
Algorithm id.Algorithm `json:"algorithm"`
ForwardingCurve25519KeyChain []string `json:"forwarding_curve25519_key_chain"`
Expand Down
50 changes: 50 additions & 0 deletions crypto/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

"github.com/rs/zerolog"

"maunium.net/go/mautrix/crypto/olm"
"maunium.net/go/mautrix/crypto/ssss"
"maunium.net/go/mautrix/id"

Expand Down Expand Up @@ -688,3 +689,52 @@ func (mach *OlmMachine) ExpiredKeyDeleteLoop(ctx context.Context) {
}
}
}

func (mach *OlmMachine) DownloadAndStoreLatestKeyBackup(ctx context.Context) error {
log := mach.machOrContextLog(ctx).With().
Str("action", "download and store latest key backup").
Logger()
versionInfo, err := mach.Client.GetKeyBackupLatestVersion(ctx)
if err != nil {
return err
}

if versionInfo.Algorithm != id.KeyBackupAlgorithmMegolmBackupV1 {
return fmt.Errorf("unsupported key backup algorithm: %s", versionInfo.Algorithm)
}

log = log.With().
Int("count", versionInfo.Count).
Str("etag", versionInfo.ETag).
Str("key_backup_version", versionInfo.Version).
Logger()

if versionInfo.Count == 0 {
log.Debug().Msg("No keys found in key backup")
return nil
}

keys, err := mach.Client.GetKeyBackup(ctx, versionInfo.Version)
if err != nil {
return err
}

for roomID, backup := range keys.Rooms {
fmt.Printf("Sessions for %s\n", roomID)
for sessionID, keyBackupData := range backup.Sessions {
// TODO
fmt.Printf("\t%s: %v\n", sessionID, keyBackupData)

olm.NewInboundGroupSession([]byte(keyBackupData.SessionData.SessionKey))

err := mach.CryptoStore.PutGroupSession(ctx, roomID, keyBackupData.SessionData.SenderKey, sessionID, &InboundGroupSession{
Internal: olm.InboundGroupSession,
})
if err != nil {
return nil
}
}
}

return nil
}
22 changes: 11 additions & 11 deletions responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -596,27 +596,27 @@ type RespRoomKeysVersionCreate struct {
Version string `json:"version"`
}

type RespRoomKeysVersion struct {
type RespRoomKeysVersion[A any] struct {
Algorithm id.KeyBackupAlgorithm `json:"algorithm"`
AuthData json.RawMessage `json:"auth_data"`
AuthData A `json:"auth_data"`
Count int `json:"count"`
ETag string `json:"etag"`
Version string `json:"version"`
}

type RespRoomKeys struct {
Rooms map[id.RoomID]RespRoomKeyBackup `json:"rooms"`
type RespRoomKeys[S any] struct {
Rooms map[id.RoomID]RespRoomKeyBackup[S] `json:"rooms"`
}

type RespRoomKeyBackup struct {
Sessions map[id.SessionID]RespKeyBackupData `json:"sessions"`
type RespRoomKeyBackup[S any] struct {
Sessions map[id.SessionID]RespKeyBackupData[S] `json:"sessions"`
}

type RespKeyBackupData struct {
FirstMessageIndex int `json:"first_message_index"`
ForwardedCount int `json:"forwarded_count"`
IsVerified bool `json:"is_verified"`
SessionData json.RawMessage `json:"session_data"`
type RespKeyBackupData[S any] struct {
FirstMessageIndex int `json:"first_message_index"`
ForwardedCount int `json:"forwarded_count"`
IsVerified bool `json:"is_verified"`
SessionData S `json:"session_data"`
}

type RespRoomKeysUpdate struct {
Expand Down

0 comments on commit 1e9ae4a

Please sign in to comment.