From d3a099f22bebddf52882c01b9b94feef3475fd2e Mon Sep 17 00:00:00 2001 From: SUMUKHA-PK Date: Mon, 28 Oct 2019 15:48:35 +0530 Subject: [PATCH] Progress in /query, /claim FED,CS --- encryptoapi/routing/keys.go | 56 +++++----------------------- encryptoapi/types/claim.go | 6 +-- federationapi/routing/e2ee.go | 70 ++++++++++++++++++++++++++++++++++- federationapi/types/claim.go | 31 ++++++++++++++++ 4 files changed, 112 insertions(+), 51 deletions(-) create mode 100644 federationapi/types/claim.go diff --git a/encryptoapi/routing/keys.go b/encryptoapi/routing/keys.go index 6f65a3d8e..9aced0d6e 100644 --- a/encryptoapi/routing/keys.go +++ b/encryptoapi/routing/keys.go @@ -183,13 +183,17 @@ func ClaimOneTimeKeys( encryptionDB *storage.Database, ) util.JSONResponse { var claimRq types.ClaimRequest - claimRp := types.ClaimResponse{} - claimRp.Failures = make(map[string]interface{}) - claimRp.ClaimBody = make(map[string]map[string]map[string]interface{}) + claimRes := types.ClaimResponse{} + claimRes.Failures = make(map[string]interface{}) + claimRes.OneTimeKeys = make(map[string]map[string]map[string]interface{}) if reqErr := httputil.UnmarshalJSONRequest(req, &claimRq); reqErr != nil { return *reqErr } + var obtainedFromFed types.QueryResponse + obtainedKeysFromFed := obtainedFromFed.DeviceKeys + claimRes.OneTimeKeys = obtainedKeysFromFed + // not sure what FED should return here /* federation consideration: when user id is in federation, a query is needed to ask fed for keys @@ -206,9 +210,9 @@ func ClaimOneTimeKeys( }() select { case <-stimuCh: - claimRp.Failures = make(map[string]interface{}) + claimRes.Failures = make(map[string]interface{}) // todo: key in this map is restricted to username at the end, yet a mocked one. - claimRp.Failures["@alice:localhost"] = "ran out of offered time" + claimRes.Failures["@alice:localhost"] = "ran out of offered time" case <-make(chan interface{}): // todo : here goes federation chan , still a mocked one } @@ -219,40 +223,9 @@ func ClaimOneTimeKeys( } } - content := claimRq.ClaimDetail - for uid, detail := range content { - for deviceID, alg := range detail { - var algTyp int - if strings.Contains(alg, "signed") { - algTyp = ONETIMEKEYOBJECT - } else { - algTyp = ONETIMEKEYSTRING - } - key, err := pickOne(req.Context(), *encryptionDB, uid, deviceID, alg) - if err != nil { - claimRp.Failures[uid] = fmt.Sprintf("%s: %s", "failed to get keys for device", deviceID) - } - claimRp.ClaimBody[uid] = make(map[string]map[string]interface{}) - keyPreMap := claimRp.ClaimBody[uid] - keymap := keyPreMap[deviceID] - if keymap == nil { - keymap = make(map[string]interface{}) - } - switch algTyp { - case ONETIMEKEYSTRING: - keymap[fmt.Sprintf("%s:%s", alg, key.KeyID)] = key.Key - case ONETIMEKEYOBJECT: - sig := make(map[string]map[string]string) - sig[uid] = make(map[string]string) - sig[uid][fmt.Sprintf("%s:%s", "ed25519", deviceID)] = key.Signature - keymap[fmt.Sprintf("%s:%s", alg, key.KeyID)] = types.KeyObject{Key: key.Key, Signature: sig} - } - claimRp.ClaimBody[uid][deviceID] = keymap - } - } return util.JSONResponse{ Code: http.StatusOK, - JSON: claimRp, + JSON: claimRes, } } @@ -403,15 +376,6 @@ func persistAl( return } -func pickOne( - ctx context.Context, - encryptDB storage.Database, - uid, device, al string, -) (key types.KeyHolder, err error) { - key, err = encryptDB.SelectOneTimeKeySingle(ctx, uid, device, al) - return -} - func upnotify(userID string) { m := sarama.ProducerMessage{ Topic: "keyUpdate", diff --git a/encryptoapi/types/claim.go b/encryptoapi/types/claim.go index 858696f1e..b2ac69578 100644 --- a/encryptoapi/types/claim.go +++ b/encryptoapi/types/claim.go @@ -17,11 +17,11 @@ package types // ClaimRequest structure type ClaimRequest struct { Timeout int64 `json:"timeout"` - ClaimDetail map[string]map[string]string `json:"one_time_keys"` + OneTimeKeys map[string]map[string]string `json:"one_time_keys"` } // ClaimResponse structure type ClaimResponse struct { - Failures map[string]interface{} `json:"failures"` - ClaimBody map[string]map[string]map[string]interface{} `json:"one_time_keys"` + Failures map[string]interface{} `json:"failures"` + OneTimeKeys map[string]map[string]map[string]interface{} `json:"one_time_keys"` } diff --git a/federationapi/routing/e2ee.go b/federationapi/routing/e2ee.go index 6649251a3..59c1eab57 100644 --- a/federationapi/routing/e2ee.go +++ b/federationapi/routing/e2ee.go @@ -1,4 +1,4 @@ -// Copyright Sumukha PK 2019 +// Copyright 2019 Sumukha PK // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import ( "context" "fmt" "net/http" + "strings" "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" @@ -29,16 +30,72 @@ import ( "github.com/matrix-org/util" ) +const ( + // ONETIMEKEYSTRING key string + ONETIMEKEYSTRING = iota + // ONETIMEKEYOBJECT key object + ONETIMEKEYOBJECT +) + +// ONETIMEKEYSTR stands for storage string property +const ONETIMEKEYSTR = "one_time_key" + +// DEVICEKEYSTR stands for storage string property +const DEVICEKEYSTR = "device_key" + // ClaimKeys provides the e2ee keys of the user func ClaimKeys( httpReq *http.Request, request *gomatrixserverlib.FederationRequest, encryptionDB *storage.Database, ) util.JSONResponse { + var claimReq types.ClaimRequest + claimRes := types.ClaimResponse{} + claimRes.OneTimeKeys = make(map[string]map[string]map[string]interface{}) + if reqErr := httputil.UnmarshalJSONRequest(httpReq, &claimReq); reqErr != nil { + return *reqErr + } + + content := claimReq.OneTimeKeys + for uid, detail := range content { + for deviceID, alg := range detail { + var algTyp int + if strings.Contains(alg, "signed") { + algTyp = ONETIMEKEYOBJECT + } else { + algTyp = ONETIMEKEYSTRING + } + key, err := pickOne(httpReq.Context(), *encryptionDB, uid, deviceID, alg) + if err != nil { + // send a better response in order to capture failures on the other part + return util.JSONResponse{ + Code: http.StatusInternalServerError, + JSON: struct{}{}, + } + // claimRes.Failures[uid] = fmt.Sprintf("%s: %s", "failed to get keys for device", deviceID) + } + claimRes.OneTimeKeys[uid] = make(map[string]map[string]interface{}) + keyPreMap := claimRes.OneTimeKeys[uid] + keymap := keyPreMap[deviceID] + if keymap == nil { + keymap = make(map[string]interface{}) + } + switch algTyp { + case ONETIMEKEYSTRING: + keymap[fmt.Sprintf("%s:%s", alg, key.KeyID)] = key.Key + case ONETIMEKEYOBJECT: + sig := make(map[string]map[string]string) + sig[uid] = make(map[string]string) + sig[uid][fmt.Sprintf("%s:%s", "ed25519", deviceID)] = key.Signature + keymap[fmt.Sprintf("%s:%s", alg, key.KeyID)] = types.KeyObject{Key: key.Key, Signatures: sig} + } + claimRes.OneTimeKeys[uid][deviceID] = keymap + } + } return util.JSONResponse{ Code: http.StatusOK, - JSON: struct{}{}, + JSON: claimRes, } } @@ -143,3 +200,12 @@ func takeAlgo( al, err = encryptDB.SelectAlgo(ctx, uid, device) return } + +func pickOne( + ctx context.Context, + encryptDB storage.Database, + uid, device, al string, +) (key types.KeyHolder, err error) { + key, err = encryptDB.SelectOneTimeKeySingle(ctx, uid, device, al) + return +} diff --git a/federationapi/types/claim.go b/federationapi/types/claim.go new file mode 100644 index 000000000..ab145a5fa --- /dev/null +++ b/federationapi/types/claim.go @@ -0,0 +1,31 @@ +// Copyright 2019 Sumukha PK +// +// 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 types + +// ClaimRequest structure +type ClaimRequest struct { + OneTimeKeys map[string]map[string]string `json:"one_time_keys"` +} + +// ClaimResponse structure +type ClaimResponse struct { + OneTimeKeys map[string]map[string]map[string]interface{} +} + +// KeyObject structure +type KeyObject struct { + Key string `json:"key"` + Signatures map[string]string `json:"signatures"` +}