Add signatures into /devices/list request

This commit is contained in:
Neil Alexander 2021-08-05 15:46:53 +01:00
parent 8fd501e2f6
commit 87f476e444
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
5 changed files with 98 additions and 0 deletions

View file

@ -37,6 +37,15 @@ func GetUserDevices(
return jsonerror.InternalServerError() return jsonerror.InternalServerError()
} }
sigReq := &keyapi.QuerySignaturesRequest{
TargetIDs: map[string][]gomatrixserverlib.KeyID{},
}
sigRes := &keyapi.QuerySignaturesResponse{}
for _, dev := range res.Devices {
sigReq.TargetIDs[userID] = append(sigReq.TargetIDs[userID], gomatrixserverlib.KeyID(dev.DeviceID))
}
keyAPI.QuerySignatures(req.Context(), sigReq, sigRes)
response := gomatrixserverlib.RespUserDevices{ response := gomatrixserverlib.RespUserDevices{
UserID: userID, UserID: userID,
StreamID: res.StreamID, StreamID: res.StreamID,
@ -56,6 +65,24 @@ func GetUserDevices(
DisplayName: dev.DisplayName, DisplayName: dev.DisplayName,
Keys: key, Keys: key,
} }
targetUser, ok := sigRes.Signatures[dev.UserID]
if !ok {
continue
}
targetKey, ok := targetUser[gomatrixserverlib.KeyID(dev.DeviceID)]
if !ok {
continue
}
for sourceUserID, forSourceUser := range targetKey {
for sourceKeyID, sourceKey := range forSourceUser {
if _, ok := device.Keys.Signatures[sourceUserID]; !ok {
device.Keys.Signatures[sourceUserID] = map[gomatrixserverlib.KeyID]gomatrixserverlib.Base64Bytes{}
}
device.Keys.Signatures[sourceUserID][sourceKeyID] = sourceKey
}
}
response.Devices = append(response.Devices, device) response.Devices = append(response.Devices, device)
} }

View file

@ -20,6 +20,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/matrix-org/dendrite/keyserver/types"
userapi "github.com/matrix-org/dendrite/userapi/api" userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
) )
@ -38,6 +39,7 @@ type KeyInternalAPI interface {
QueryKeyChanges(ctx context.Context, req *QueryKeyChangesRequest, res *QueryKeyChangesResponse) QueryKeyChanges(ctx context.Context, req *QueryKeyChangesRequest, res *QueryKeyChangesResponse)
QueryOneTimeKeys(ctx context.Context, req *QueryOneTimeKeysRequest, res *QueryOneTimeKeysResponse) QueryOneTimeKeys(ctx context.Context, req *QueryOneTimeKeysRequest, res *QueryOneTimeKeysResponse)
QueryDeviceMessages(ctx context.Context, req *QueryDeviceMessagesRequest, res *QueryDeviceMessagesResponse) QueryDeviceMessages(ctx context.Context, req *QueryDeviceMessagesRequest, res *QueryDeviceMessagesResponse)
QuerySignatures(ctx context.Context, req *QuerySignaturesRequest, res *QuerySignaturesResponse)
} }
// KeyError is returned if there was a problem performing/querying the server // KeyError is returned if there was a problem performing/querying the server
@ -242,6 +244,17 @@ type QueryDeviceMessagesResponse struct {
Error *KeyError Error *KeyError
} }
type QuerySignaturesRequest struct {
// A map of target user ID -> target key/device IDs to retrieve signatures for
TargetIDs map[string][]gomatrixserverlib.KeyID `json:"target_ids"`
}
type QuerySignaturesResponse struct {
// A map of target user ID -> target key/device ID -> origin user ID -> origin key/device ID -> signatures
Signatures map[string]map[gomatrixserverlib.KeyID]types.CrossSigningSigMap
Error *KeyError
}
type InputDeviceListUpdateRequest struct { type InputDeviceListUpdateRequest struct {
Event gomatrixserverlib.DeviceListUpdateEvent Event gomatrixserverlib.DeviceListUpdateEvent
} }

View file

@ -460,3 +460,32 @@ func (a *KeyInternalAPI) crossSigningKeysFromDatabase(
} }
} }
} }
func (a *KeyInternalAPI) QuerySignatures(ctx context.Context, req *api.QuerySignaturesRequest, res *api.QuerySignaturesResponse) {
for targetUserID, forTargetUser := range req.TargetIDs {
for _, targetKeyID := range forTargetUser {
keyMap, err := a.DB.CrossSigningSigsForTarget(ctx, targetUserID, targetKeyID)
if err != nil {
res.Error = &api.KeyError{
Err: fmt.Sprintf("a.DB.CrossSigningSigsForTarget: %s", err),
}
return
}
for sourceUserID, forSourceUser := range keyMap {
if _, ok := res.Signatures[targetUserID]; !ok {
res.Signatures[targetUserID] = map[gomatrixserverlib.KeyID]types.CrossSigningSigMap{}
}
if _, ok := res.Signatures[targetUserID][targetKeyID]; !ok {
res.Signatures[targetUserID][targetKeyID] = types.CrossSigningSigMap{}
}
if _, ok := res.Signatures[targetUserID][targetKeyID][sourceUserID]; !ok {
res.Signatures[targetUserID][targetKeyID][sourceUserID] = map[gomatrixserverlib.KeyID]gomatrixserverlib.Base64Bytes{}
}
for targetKeyID, targetSig := range forSourceUser {
res.Signatures[targetUserID][targetKeyID][sourceUserID][targetKeyID] = targetSig
}
}
}
}
}

View file

@ -36,6 +36,7 @@ const (
QueryKeyChangesPath = "/keyserver/queryKeyChanges" QueryKeyChangesPath = "/keyserver/queryKeyChanges"
QueryOneTimeKeysPath = "/keyserver/queryOneTimeKeys" QueryOneTimeKeysPath = "/keyserver/queryOneTimeKeys"
QueryDeviceMessagesPath = "/keyserver/queryDeviceMessages" QueryDeviceMessagesPath = "/keyserver/queryDeviceMessages"
QuerySignaturesPath = "/keyserver/querySignatures"
) )
// NewKeyServerClient creates a KeyInternalAPI implemented by talking to a HTTP POST API. // NewKeyServerClient creates a KeyInternalAPI implemented by talking to a HTTP POST API.
@ -211,3 +212,20 @@ func (h *httpKeyInternalAPI) PerformUploadDeviceSignatures(
} }
} }
} }
func (h *httpKeyInternalAPI) QuerySignatures(
ctx context.Context,
request *api.QuerySignaturesRequest,
response *api.QuerySignaturesResponse,
) {
span, ctx := opentracing.StartSpanFromContext(ctx, "QuerySignatures")
defer span.Finish()
apiURL := h.apiURL + QuerySignaturesPath
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
if err != nil {
response.Error = &api.KeyError{
Err: err.Error(),
}
}
}

View file

@ -124,4 +124,15 @@ func AddRoutes(internalAPIMux *mux.Router, s api.KeyInternalAPI) {
return util.JSONResponse{Code: http.StatusOK, JSON: &response} return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}), }),
) )
internalAPIMux.Handle(QuerySignaturesPath,
httputil.MakeInternalAPI("querySignatures", func(req *http.Request) util.JSONResponse {
request := api.QuerySignaturesRequest{}
response := api.QuerySignaturesResponse{}
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
return util.MessageResponse(http.StatusBadRequest, err.Error())
}
s.QuerySignatures(req.Context(), &request, &response)
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
} }