From e53af12682ce9e9c8619fb0f54cde0ff32af9b06 Mon Sep 17 00:00:00 2001 From: Nikos Filippakis Date: Wed, 5 Aug 2020 12:11:52 +0200 Subject: [PATCH] Add cryptotest methods for testing key forwarding Signed-off-by: Nikos Filippakis --- clients/bot_client.go | 47 +++++++++++++++++++ services/cryptotest/cryptotest.go | 78 +++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/clients/bot_client.go b/clients/bot_client.go index b315282..c56a38a 100644 --- a/clients/bot_client.go +++ b/clients/bot_client.go @@ -9,6 +9,7 @@ import ( "github.com/matrix-org/go-neb/database" "github.com/matrix-org/go-neb/matrix" log "github.com/sirupsen/logrus" + "golang.org/x/net/context" "maunium.net/go/mautrix" "maunium.net/go/mautrix/crypto" "maunium.net/go/mautrix/event" @@ -236,3 +237,49 @@ func (botClient *BotClient) StartSASVerification(userID id.UserID, deviceID id.D } return botClient.olmMachine.NewSimpleSASVerificationWith(device, botClient) } + +// SendRoomKeyRequest sends a room key request to another device. +func (botClient *BotClient) SendRoomKeyRequest(userID id.UserID, deviceID id.DeviceID, roomID id.RoomID, + senderKey id.SenderKey, sessionID id.SessionID, timeout time.Duration) (chan bool, error) { + + ctx, _ := context.WithTimeout(context.Background(), timeout) + return botClient.olmMachine.RequestRoomKey(ctx, userID, deviceID, roomID, senderKey, sessionID) +} + +// ForwardRoomKeyToDevice sends a room key to another device. +func (botClient *BotClient) ForwardRoomKeyToDevice(userID id.UserID, deviceID id.DeviceID, roomID id.RoomID, senderKey id.SenderKey, + sessionID id.SessionID) error { + + device, err := botClient.olmMachine.GetOrFetchDevice(userID, deviceID) + if err != nil { + return err + } + + igs, err := botClient.olmMachine.CryptoStore.GetGroupSession(roomID, senderKey, sessionID) + if err != nil { + return err + } else if igs == nil { + return errors.New("Group session not found") + } + + exportedKey, err := igs.Internal.Export(igs.Internal.FirstKnownIndex()) + if err != nil { + return err + } + + forwardedRoomKey := event.Content{ + Parsed: &event.ForwardedRoomKeyEventContent{ + RoomKeyEventContent: event.RoomKeyEventContent{ + Algorithm: id.AlgorithmMegolmV1, + RoomID: igs.RoomID, + SessionID: igs.ID(), + SessionKey: exportedKey, + }, + SenderKey: senderKey, + ForwardingKeyChain: igs.ForwardingChains, + SenderClaimedKey: igs.SigningKey, + }, + } + + return botClient.olmMachine.SendEncryptedToDevice(device, forwardedRoomKey) +} diff --git a/services/cryptotest/cryptotest.go b/services/cryptotest/cryptotest.go index 44a3c03..f94ec67 100644 --- a/services/cryptotest/cryptotest.go +++ b/services/cryptotest/cryptotest.go @@ -5,6 +5,7 @@ import ( "fmt" "math/rand" "strconv" + "time" "github.com/matrix-org/go-neb/clients" "github.com/matrix-org/go-neb/types" @@ -49,6 +50,8 @@ func (s *Service) handleEventMessage(source mautrix.EventSource, evt *mevt.Event // Commands supported: // !crypto_response random_string // Responds with a notice of "some message". +// TODO details here +// TODO each cmd when called incorrectly (wrong # of args) should also show a msg func (s *Service) Commands(cli types.MatrixClient) []types.Command { botClient := cli.(*clients.BotClient) return []types.Command{ @@ -161,6 +164,81 @@ func (s *Service) Commands(cli types.MatrixClient) []types.Command { return nil, nil }, }, + { + Path: []string{"request_my_room_key"}, + Command: func(roomID id.RoomID, userID id.UserID, arguments []string) (interface{}, error) { + if s.inRoom(roomID) && len(arguments) == 3 { + deviceID := id.DeviceID(arguments[0]) + senderKey := id.SenderKey(arguments[1]) + sessionID := id.SessionID(arguments[2]) + receivedChan, err := botClient.SendRoomKeyRequest(userID, deviceID, roomID, senderKey, sessionID, time.Minute) + if err != nil { + log.WithFields(log.Fields{ + "user_id": userID, + "device_id": deviceID, + "sender_key": senderKey, + "session_id": sessionID, + }).WithError(err).Error("Error requesting room key") + return mevt.MessageEventContent{ + MsgType: mevt.MsgText, + Body: fmt.Sprintf("Error requesting room key for session %v: %v", sessionID, err), + }, nil + } + go func() { + var result string + received := <-receivedChan + if received { + result = "Key received successfully!" + } else { + result = "Key was not received in the time limit" + } + content := mevt.MessageEventContent{ + MsgType: mevt.MsgText, + Body: fmt.Sprintf("Room key request for session %v result: %v", sessionID, result), + } + if _, err := botClient.SendMessageEvent(roomID, mevt.EventMessage, content); err != nil { + log.WithFields(log.Fields{ + "room_id": roomID, + "content": content, + }).WithError(err).Error("Failed to send room key request result to room") + } + }() + return mevt.MessageEventContent{ + MsgType: mevt.MsgText, + Body: fmt.Sprintf("Sent room key request for session %v to device %v", sessionID, deviceID), + }, nil + } + return nil, nil + }, + }, + { + Path: []string{"forward_me_room_key"}, + Command: func(roomID id.RoomID, userID id.UserID, arguments []string) (interface{}, error) { + if s.inRoom(roomID) && len(arguments) == 3 { + deviceID := id.DeviceID(arguments[0]) + senderKey := id.SenderKey(arguments[1]) + sessionID := id.SessionID(arguments[2]) + err := botClient.ForwardRoomKeyToDevice(userID, deviceID, roomID, senderKey, sessionID) + if err != nil { + log.WithFields(log.Fields{ + "user_id": userID, + "device_id": deviceID, + "sender_key": senderKey, + "session_id": sessionID, + }).WithError(err).Error("Error forwarding room key") + return mevt.MessageEventContent{ + MsgType: mevt.MsgText, + Body: fmt.Sprintf("Error forwarding room key for session %v: %v", sessionID, err), + }, nil + } + return mevt.MessageEventContent{ + MsgType: mevt.MsgText, + Body: fmt.Sprintf("Forwarded room key for session %v to device %v", sessionID, deviceID), + }, nil + } + return nil, nil + }, + }, } }