dendrite/federationapi/routing/e2ee.go
2019-10-25 17:47:20 +05:30

138 lines
4.2 KiB
Go

// 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
}