From 7576f52bdca5c027bcd3368c5a3a3eb8af0fba8a Mon Sep 17 00:00:00 2001 From: Robin Date: Fri, 9 Jan 2026 17:24:31 +0100 Subject: [PATCH] Use base64 encoded hashes for room alias and participant ID (minimize identifying metadata sent to SFU) (#144) * Encode room alias as unpadded base64 As recommended by the latest version of MSC4195. * Set participant ID to SHA-256 of user ID, device ID, and member ID To match the latest version of MSC4195. --- main.go | 12 ++++++++++-- main_test.go | 9 ++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/main.go b/main.go index 1314c2e..c6993a7 100644 --- a/main.go +++ b/main.go @@ -10,6 +10,7 @@ import ( "context" "crypto/sha256" "crypto/tls" + "encoding/base64" "encoding/json" "errors" "fmt" @@ -85,6 +86,8 @@ type ValidatableSFURequest interface { Validate() error } +var unpaddedBase64 = base64.StdEncoding.WithPadding(base64.NoPadding) + func (e *MatrixErrorResponse) Error() string { return e.Err } @@ -276,8 +279,13 @@ func (h *Handler) processSFURequest(r *http.Request, req *SFURequest) (*SFURespo map[bool]string{true: "full access", false: "restricted access"}[isFullAccessUser], ) - lkIdentity := req.Member.ID - lkRoomAlias := fmt.Sprintf("%x", sha256.Sum256([]byte(req.RoomID + "|" + req.SlotID))) + lkIdentityRaw := userInfo.Sub + "|" + req.Member.ClaimedDeviceID + "|" + req.Member.ID + lkIdentityHash := sha256.Sum256([]byte(lkIdentityRaw)) + lkIdentity := unpaddedBase64.EncodeToString(lkIdentityHash[:]) + + lkRoomAliasHash := sha256.Sum256([]byte(req.RoomID + "|" + req.SlotID)) + lkRoomAlias := unpaddedBase64.EncodeToString(lkRoomAliasHash[:]) + token, err := getJoinToken(h.key, h.secret, lkRoomAlias, lkIdentity) if err != nil { log.Printf("Error getting LiveKit token: %v", err) diff --git a/main_test.go b/main_test.go index 78bf6f5..6ad05d6 100644 --- a/main_test.go +++ b/main_test.go @@ -201,12 +201,15 @@ func TestHandlePost(t *testing.T) { t.Fatalf("failed to parse claims from JWT: %v", err) } - if claims["sub"] != "member_test_id" { + want_sub_hash := sha256.Sum256([]byte("@user:"+ matrixServerName + "|testDevice|member_test_id")) + want_sub := unpaddedBase64.EncodeToString(want_sub_hash[:]) + if claims["sub"] != want_sub { t.Errorf("unexpected sub: got %v want %v", claims["sub"], "member_test_id") } // should have permission for the room - want_room := fmt.Sprintf("%x", sha256.Sum256([]byte("!testRoom:example.com" + "|" + "m.call#ROOM"))) + want_room_hash := sha256.Sum256([]byte("!testRoom:example.com" + "|" + "m.call#ROOM")) + want_room := unpaddedBase64.EncodeToString(want_room_hash[:]) if claims["video"].(map[string]interface{})["room"] != want_room { t.Errorf("unexpected room: got %v want %v", claims["video"].(map[string]interface{})["room"], want_room) } @@ -1072,4 +1075,4 @@ func TestProcessLegacySFURequest(t *testing.T) { } -} \ No newline at end of file +}