mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-16 11:23:11 -06:00
/upload checked for completeness/correctness
This commit is contained in:
parent
d7664a1c96
commit
a89da890b9
|
|
@ -28,7 +28,6 @@ import (
|
||||||
"github.com/matrix-org/dendrite/common/basecomponent"
|
"github.com/matrix-org/dendrite/common/basecomponent"
|
||||||
"github.com/matrix-org/dendrite/encryptoapi/storage"
|
"github.com/matrix-org/dendrite/encryptoapi/storage"
|
||||||
"github.com/matrix-org/dendrite/encryptoapi/types"
|
"github.com/matrix-org/dendrite/encryptoapi/types"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
@ -79,6 +78,7 @@ func UploadPKeys(
|
||||||
&keySpecific,
|
&keySpecific,
|
||||||
userID, deviceID)
|
userID, deviceID)
|
||||||
// numMap is algorithm-num map
|
// numMap is algorithm-num map
|
||||||
|
// this gets the number of unclaimed OTkeys
|
||||||
numMap, ok := (queryOneTimeKeys(
|
numMap, ok := (queryOneTimeKeys(
|
||||||
req.Context(),
|
req.Context(),
|
||||||
TYPESUM,
|
TYPESUM,
|
||||||
|
|
@ -116,13 +116,12 @@ func QueryPKeys(
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
var err error
|
var err error
|
||||||
var queryRq types.QueryRequest
|
var queryRq types.QueryRequest
|
||||||
queryRp := types.QueryResponse{}
|
|
||||||
queryRp.Failure = make(map[string]interface{})
|
|
||||||
queryRp.DeviceKeys = make(map[string]map[string]types.DeviceKeysQuery)
|
|
||||||
if reqErr := httputil.UnmarshalJSONRequest(req, &queryRq); reqErr != nil {
|
if reqErr := httputil.UnmarshalJSONRequest(req, &queryRq); reqErr != nil {
|
||||||
return *reqErr
|
return *reqErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendDKToFed := queryRq.DeviceKeys
|
||||||
|
queryRp.Failure = make(map[string]interface{})
|
||||||
// FED must return the keys from the other user
|
// FED must return the keys from the other user
|
||||||
/*
|
/*
|
||||||
federation consideration: when user id is in federation, a
|
federation consideration: when user id is in federation, a
|
||||||
|
|
@ -156,44 +155,12 @@ func QueryPKeys(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// query one's device key from user corresponding to uid
|
//
|
||||||
for uid, arr := range queryRq.DeviceKeys {
|
//
|
||||||
queryRp.DeviceKeys[uid] = make(map[string]types.DeviceKeysQuery)
|
//
|
||||||
deviceKeysQueryMap := queryRp.DeviceKeys[uid]
|
//
|
||||||
// backward compatible to old interface
|
// Forward the request to the federation server and get the required info
|
||||||
midArr := []string{}
|
|
||||||
// figure out device list from devices described as device which is actually deviceID
|
|
||||||
for device := range arr.(map[string]interface{}) {
|
|
||||||
midArr = append(midArr, device)
|
|
||||||
}
|
|
||||||
// all device keys
|
|
||||||
dkeys, _ := encryptionDB.QueryInRange(req.Context(), uid, midArr)
|
|
||||||
// build response for them
|
|
||||||
|
|
||||||
for _, key := range dkeys {
|
|
||||||
|
|
||||||
deviceKeysQueryMap = presetDeviceKeysQueryMap(deviceKeysQueryMap, uid, key)
|
|
||||||
// load for accomplishment
|
|
||||||
single := deviceKeysQueryMap[key.DeviceID]
|
|
||||||
resKey := fmt.Sprintf("%s:%s", key.KeyAlgorithm, key.DeviceID)
|
|
||||||
resBody := key.Key
|
|
||||||
single.Keys[resKey] = resBody
|
|
||||||
single.DeviceID = key.DeviceID
|
|
||||||
single.UserID = key.UserID
|
|
||||||
single.Signature[uid][fmt.Sprintf("%s:%s", "ed25519", key.DeviceID)] = key.Signature
|
|
||||||
single.Algorithm, err = takeAL(req.Context(), *encryptionDB, key.UserID, key.DeviceID)
|
|
||||||
localpart, _, _ := gomatrixserverlib.SplitID('@', uid)
|
|
||||||
device, _ := deviceDB.GetDeviceByID(req.Context(), localpart, deviceID)
|
|
||||||
single.Unsigned.Info = device.DisplayName
|
|
||||||
deviceKeysQueryMap[key.DeviceID] = single
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return util.JSONResponse{
|
|
||||||
Code: http.StatusInternalServerError,
|
|
||||||
JSON: queryRp,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
JSON: queryRp,
|
JSON: queryRp,
|
||||||
|
|
@ -426,15 +393,6 @@ func persistAl(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func takeAL(
|
|
||||||
ctx context.Context,
|
|
||||||
encryptDB storage.Database,
|
|
||||||
uid, device string,
|
|
||||||
) (al []string, err error) {
|
|
||||||
al, err = encryptDB.SelectAl(ctx, uid, device)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func pickOne(
|
func pickOne(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
encryptDB storage.Database,
|
encryptDB storage.Database,
|
||||||
|
|
@ -460,35 +418,6 @@ func InitNotifier(base *basecomponent.BaseDendrite) {
|
||||||
keyProducer.ch = pro
|
keyProducer.ch = pro
|
||||||
}
|
}
|
||||||
|
|
||||||
func presetDeviceKeysQueryMap(
|
|
||||||
deviceKeysQueryMap map[string]types.DeviceKeysQuery,
|
|
||||||
uid string,
|
|
||||||
key types.KeyHolder,
|
|
||||||
) map[string]types.DeviceKeysQuery {
|
|
||||||
// preset for complicated nested map struct
|
|
||||||
if _, ok := deviceKeysQueryMap[key.DeviceID]; !ok {
|
|
||||||
// make consistency
|
|
||||||
deviceKeysQueryMap[key.DeviceID] = types.DeviceKeysQuery{}
|
|
||||||
}
|
|
||||||
if deviceKeysQueryMap[key.DeviceID].Signature == nil {
|
|
||||||
mid := make(map[string]map[string]string)
|
|
||||||
midmap := deviceKeysQueryMap[key.DeviceID]
|
|
||||||
midmap.Signature = mid
|
|
||||||
deviceKeysQueryMap[key.DeviceID] = midmap
|
|
||||||
}
|
|
||||||
if deviceKeysQueryMap[key.DeviceID].Keys == nil {
|
|
||||||
mid := make(map[string]string)
|
|
||||||
midmap := deviceKeysQueryMap[key.DeviceID]
|
|
||||||
midmap.Keys = mid
|
|
||||||
deviceKeysQueryMap[key.DeviceID] = midmap
|
|
||||||
}
|
|
||||||
if _, ok := deviceKeysQueryMap[key.DeviceID].Signature[uid]; !ok {
|
|
||||||
// make consistency
|
|
||||||
deviceKeysQueryMap[key.DeviceID].Signature[uid] = make(map[string]string)
|
|
||||||
}
|
|
||||||
return deviceKeysQueryMap
|
|
||||||
}
|
|
||||||
|
|
||||||
func persistBothKeys(
|
func persistBothKeys(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
body *types.UploadEncryptSpecific,
|
body *types.UploadEncryptSpecific,
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ func (d *Database) InsertKey(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// SelectOneTimeKeyCount for key upload response usage a map from key algorithm to sum to counterpart
|
// SelectOneTimeKeyCount provides the number of un-claimed OTKeys
|
||||||
func (d *Database) SelectOneTimeKeyCount(
|
func (d *Database) SelectOneTimeKeyCount(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
deviceID, userID string,
|
deviceID, userID string,
|
||||||
|
|
|
||||||
137
federationapi/routing/e2ee.go
Normal file
137
federationapi/routing/e2ee.go
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
// Copyright Sumukha PK 2019
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package routing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||||
|
"github.com/matrix-org/dendrite/encryptoapi/storage"
|
||||||
|
"github.com/matrix-org/dendrite/federationapi/types"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
"github.com/matrix-org/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ClaimKeys provides the e2ee keys of the user
|
||||||
|
func ClaimKeys(
|
||||||
|
httpReq *http.Request,
|
||||||
|
request *gomatrixserverlib.FederationRequest,
|
||||||
|
encryptionDB *storage.Database,
|
||||||
|
) util.JSONResponse {
|
||||||
|
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusOK,
|
||||||
|
JSON: struct{}{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryKeys provides the public identity keys and supported algorithms.
|
||||||
|
func QueryKeys(
|
||||||
|
httpReq *http.Request,
|
||||||
|
request *gomatrixserverlib.FederationRequest,
|
||||||
|
encryptionDB *storage.Database,
|
||||||
|
) util.JSONResponse {
|
||||||
|
var err error
|
||||||
|
var queryRq types.QueryRequest
|
||||||
|
if reqErr := httputil.UnmarshalJSONRequest(httpReq, &queryRq); reqErr != nil {
|
||||||
|
return *reqErr
|
||||||
|
}
|
||||||
|
queryRp := types.QueryResponse{}
|
||||||
|
|
||||||
|
queryRp.DeviceKeys = make(map[string]map[string]types.DeviceKeys)
|
||||||
|
// query one's device key from user corresponding to uid
|
||||||
|
for uid, arr := range queryRq.DeviceKeys {
|
||||||
|
queryRp.DeviceKeys[uid] = make(map[string]types.DeviceKeys)
|
||||||
|
deviceKeysQueryMap := queryRp.DeviceKeys[uid]
|
||||||
|
// backward compatible to old interface
|
||||||
|
midArr := []string{}
|
||||||
|
// figure out device list from devices described as device which is actually deviceID
|
||||||
|
for device := range arr.(map[string]interface{}) {
|
||||||
|
midArr = append(midArr, device)
|
||||||
|
}
|
||||||
|
// all device keys
|
||||||
|
dkeys, _ := encryptionDB.QueryInRange(httpReq.Context(), uid, midArr)
|
||||||
|
// build response for them
|
||||||
|
|
||||||
|
for _, key := range dkeys {
|
||||||
|
|
||||||
|
deviceKeysQueryMap = presetDeviceKeysQueryMap(deviceKeysQueryMap, uid, key)
|
||||||
|
// load for accomplishment
|
||||||
|
single := deviceKeysQueryMap[key.DeviceID]
|
||||||
|
resKey := fmt.Sprintf("%s:%s", key.KeyAlgorithm, key.DeviceID)
|
||||||
|
resBody := key.Key
|
||||||
|
single.Keys[resKey] = resBody
|
||||||
|
single.DeviceID = key.DeviceID
|
||||||
|
single.UserID = key.UserID
|
||||||
|
single.Signature[uid][fmt.Sprintf("%s:%s", "ed25519", key.DeviceID)] = key.Signature
|
||||||
|
single.Algorithm, err = takeAL(httpReq.Context(), *encryptionDB, key.UserID, key.DeviceID)
|
||||||
|
localpart, _, _ := gomatrixserverlib.SplitID('@', uid)
|
||||||
|
device, _ := deviceDB.GetDeviceByID(req.Context(), localpart, deviceID)
|
||||||
|
single.Unsigned.Info = device.DisplayName
|
||||||
|
deviceKeysQueryMap[key.DeviceID] = single
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
JSON: struct{}{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusOK,
|
||||||
|
JSON: struct{}{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func presetDeviceKeysQueryMap(
|
||||||
|
deviceKeysQueryMap map[string]types.DeviceKeys,
|
||||||
|
uid string,
|
||||||
|
key types.KeyHolder,
|
||||||
|
) map[string]types.DeviceKeys {
|
||||||
|
// preset for complicated nested map struct
|
||||||
|
if _, ok := deviceKeysQueryMap[key.DeviceID]; !ok {
|
||||||
|
// make consistency
|
||||||
|
deviceKeysQueryMap[key.DeviceID] = types.DeviceKeysQuery{}
|
||||||
|
}
|
||||||
|
if deviceKeysQueryMap[key.DeviceID].Signature == nil {
|
||||||
|
mid := make(map[string]map[string]string)
|
||||||
|
midmap := deviceKeysQueryMap[key.DeviceID]
|
||||||
|
midmap.Signature = mid
|
||||||
|
deviceKeysQueryMap[key.DeviceID] = midmap
|
||||||
|
}
|
||||||
|
if deviceKeysQueryMap[key.DeviceID].Keys == nil {
|
||||||
|
mid := make(map[string]string)
|
||||||
|
midmap := deviceKeysQueryMap[key.DeviceID]
|
||||||
|
midmap.Keys = mid
|
||||||
|
deviceKeysQueryMap[key.DeviceID] = midmap
|
||||||
|
}
|
||||||
|
if _, ok := deviceKeysQueryMap[key.DeviceID].Signature[uid]; !ok {
|
||||||
|
// make consistency
|
||||||
|
deviceKeysQueryMap[key.DeviceID].Signature[uid] = make(map[string]string)
|
||||||
|
}
|
||||||
|
return deviceKeysQueryMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func takeAL(
|
||||||
|
ctx context.Context,
|
||||||
|
encryptDB storage.Database,
|
||||||
|
uid, device string,
|
||||||
|
) (al []string, err error) {
|
||||||
|
al, err = encryptDB.SelectAl(ctx, uid, device)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
@ -271,4 +271,27 @@ func Setup(
|
||||||
return Backfill(httpReq, request, query, vars["roomID"], cfg)
|
return Backfill(httpReq, request, query, vars["roomID"], cfg)
|
||||||
},
|
},
|
||||||
)).Methods(http.MethodGet)
|
)).Methods(http.MethodGet)
|
||||||
|
|
||||||
|
v1fedmux.Handle("/keys/claim", common.MakeFedAPI(
|
||||||
|
"federation_claim_e2ee_keys", cfg.Matrix.ServerName, keys,
|
||||||
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
|
||||||
|
// vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
|
||||||
|
// if err != nil {
|
||||||
|
// return util.ErrorResponse(err)
|
||||||
|
// }
|
||||||
|
return ClaimKeys(httpReq, request)
|
||||||
|
},
|
||||||
|
)).Methods(http.MethodPost)
|
||||||
|
|
||||||
|
v1fedmux.Handle("/keys/query", common.MakeFedAPI(
|
||||||
|
"federation_query_e2ee_keys", cfg.Matrix.ServerName, keys,
|
||||||
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
|
||||||
|
// vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
|
||||||
|
// if err != nil {
|
||||||
|
// return util.ErrorResponse(err)
|
||||||
|
// }
|
||||||
|
return QueryKeys(httpReq, request)
|
||||||
|
},
|
||||||
|
)).Methods(http.MethodPost)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,3 +41,39 @@ func NewTransaction() Transaction {
|
||||||
|
|
||||||
return Transaction{OriginServerTS: ts}
|
return Transaction{OriginServerTS: ts}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryRequest is the request for /query
|
||||||
|
type QueryRequest struct {
|
||||||
|
DeviceKeys map[string][]string `json:"device_keys"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsignedDeviceInfo is the struct for UDI
|
||||||
|
type UnsignedDeviceInfo struct {
|
||||||
|
DeviceDisplayName string `json:"device_display_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceKeys has the data of the keys of the device
|
||||||
|
type DeviceKeys struct {
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
DeviceID string `json:"edvice_id"`
|
||||||
|
Algorithms []string `json:"algorithms"`
|
||||||
|
Keys map[string]string `json:"keys"`
|
||||||
|
Signatures map[string]map[string]string `json:"signatures"`
|
||||||
|
Unsigned UnsignedDeviceInfo `json:"unsigned"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryResponse is the response for /query
|
||||||
|
type QueryResponse struct {
|
||||||
|
DeviceKeys map[string]DeviceKeys `json:"device_keys"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyHolder structure
|
||||||
|
type KeyHolder struct {
|
||||||
|
UserID,
|
||||||
|
DeviceID,
|
||||||
|
Signature,
|
||||||
|
KeyAlgorithm,
|
||||||
|
KeyID,
|
||||||
|
Key,
|
||||||
|
KeyType string
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue