Legible FS

This commit is contained in:
SUMUKHA-PK 2019-10-28 16:10:05 +05:30
parent d3a099f22b
commit 55d7d93c48
8 changed files with 501 additions and 410 deletions

View file

@ -0,0 +1,55 @@
// 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 routing
import (
"net/http"
"github.com/matrix-org/dendrite/encryptoapi/storage"
"github.com/matrix-org/dendrite/encryptoapi/types"
"github.com/matrix-org/util"
)
// ChangesInKeys returns the changes in the keys after last sync
// each user maintains a chain of the changes when provided by FED
func ChangesInKeys(
req *http.Request,
encryptionDB *storage.Database,
) util.JSONResponse {
// assuming federation has added keys to the DB,
// extracting from the DB here
// get from FED/Req
var readID int
var userID string
keyChanges, err := encryptionDB.GetKeyChanges(req.Context(), readID, userID)
if err != nil {
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: struct{}{},
}
}
changesRes := types.ChangesResponse{}
changesRes.Changed = keyChanges.Changed
changesRes.Left = keyChanges.Left
// delete the extracted keys from the DB
return util.JSONResponse{
Code: http.StatusOK,
JSON: changesRes,
}
}

View file

@ -0,0 +1,77 @@
// 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 routing
import (
"net/http"
"time"
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/encryptoapi/storage"
"github.com/matrix-org/dendrite/encryptoapi/types"
"github.com/matrix-org/util"
)
// ClaimOneTimeKeys enables user to claim one time keys for sessions.
func ClaimOneTimeKeys(
req *http.Request,
encryptionDB *storage.Database,
) util.JSONResponse {
var claimRq types.ClaimRequest
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
domain --------+ fed (keys)
domain +--tout-- timer
*/
// todo: Add federation processing at specific userID.
if false /*federation judgement*/ {
tout := claimRq.Timeout
stimuCh := make(chan int)
go func() {
time.Sleep(time.Duration(tout) * 1000 * 1000)
close(stimuCh)
}()
select {
case <-stimuCh:
claimRes.Failures = make(map[string]interface{})
// todo: key in this map is restricted to username at the end, yet a mocked one.
claimRes.Failures["@alice:localhost"] = "ran out of offered time"
case <-make(chan interface{}):
// todo : here goes federation chan , still a mocked one
}
// probably some other better error to tell it timed out in FED
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: struct{}{},
}
}
return util.JSONResponse{
Code: http.StatusOK,
JSON: claimRes,
}
}

View file

@ -1,4 +1,4 @@
// Copyright 2018 Vector Creations Ltd
// 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.
@ -15,21 +15,8 @@
package routing
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
"github.com/Shopify/sarama"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/common/basecomponent"
"github.com/matrix-org/dendrite/encryptoapi/storage"
"github.com/matrix-org/dendrite/encryptoapi/types"
"github.com/matrix-org/util"
"github.com/pkg/errors"
)
const (
@ -59,406 +46,13 @@ type KeyNotifier struct {
var keyProducer = &KeyNotifier{}
// UploadPKeys enables the user to upload his device
// and one time keys with limit at 50 set as default
func UploadPKeys(
req *http.Request,
encryptionDB *storage.Database,
userID, deviceID string,
) util.JSONResponse {
var keybody types.UploadEncrypt
if reqErr := httputil.UnmarshalJSONRequest(req, &keybody); reqErr != nil {
return *reqErr
}
keySpecific := turnSpecific(keybody)
// persist keys into encryptionDB
err := persistKeys(
req.Context(),
encryptionDB,
&keySpecific,
userID, deviceID)
// numMap is algorithm-num map
// this gets the number of unclaimed OTkeys
numMap, ok := (queryOneTimeKeys(
req.Context(),
TYPESUM,
userID,
deviceID,
encryptionDB)).(map[string]int)
if !ok {
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: struct{}{},
}
}
if err != nil {
return util.JSONResponse{
Code: http.StatusBadGateway,
JSON: types.UploadResponse{
Count: numMap,
},
}
}
return util.JSONResponse{
Code: http.StatusOK,
JSON: types.UploadResponse{
Count: numMap,
},
}
}
// QueryPKeys returns the public identity keys
// and supported algorithms of "intended user"
// This just forwards the request to the Federation,
// and waits/checks for timeouts and failures. Response
// of the FedSenderAPI is bundled with the failures and returned.
func QueryPKeys(
req *http.Request,
encryptionDB *storage.Database,
deviceID string,
deviceDB *devices.Database,
) util.JSONResponse {
var err error
var queryRq types.QueryRequest
if reqErr := httputil.UnmarshalJSONRequest(req, &queryRq); reqErr != nil {
return *reqErr
}
queryRp := types.QueryResponse{}
// sendDKToFed := queryRq.DeviceKeys
var obtainedFromFed types.QueryResponse
obtainedKeysFromFed := obtainedFromFed.DeviceKeys
queryRp.DeviceKeys = obtainedKeysFromFed
queryRp.Failure = make(map[string]interface{})
// FED must return the keys from the other user
/*
federation consideration: when user id is in federation, a
query is needed to ask fed for keys.
domain --------+ fed (keys)
domain +--tout-- timer
*/
// todo: Add federation processing at specific userID.
if false /*federation judgement*/ {
tout := queryRq.Timeout
if tout == 0 {
tout = int64(10 * time.Second)
}
stimuCh := make(chan int)
go func() {
time.Sleep(time.Duration(tout) * 1000 * 1000)
close(stimuCh)
}()
select {
case <-stimuCh:
queryRp.Failure = make(map[string]interface{})
// todo: key in this map is restricted to username at the end, yet a mocked one.
queryRp.Failure["@alice:localhost"] = "ran out of offered time"
case <-make(chan interface{}):
// todo : here goes federation chan , still a mocked one
}
// probably some other better error to tell it timed out in FED
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: struct{}{},
}
}
//
//
//
//
// Forward the request to the federation server and get the required info
return util.JSONResponse{
Code: http.StatusOK,
JSON: queryRp,
}
}
// ClaimOneTimeKeys enables user to claim one time keys for sessions.
func ClaimOneTimeKeys(
req *http.Request,
encryptionDB *storage.Database,
) util.JSONResponse {
var claimRq types.ClaimRequest
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
domain --------+ fed (keys)
domain +--tout-- timer
*/
// todo: Add federation processing at specific userID.
if false /*federation judgement*/ {
tout := claimRq.Timeout
stimuCh := make(chan int)
go func() {
time.Sleep(time.Duration(tout) * 1000 * 1000)
close(stimuCh)
}()
select {
case <-stimuCh:
claimRes.Failures = make(map[string]interface{})
// todo: key in this map is restricted to username at the end, yet a mocked one.
claimRes.Failures["@alice:localhost"] = "ran out of offered time"
case <-make(chan interface{}):
// todo : here goes federation chan , still a mocked one
}
// probably some other better error to tell it timed out in FED
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: struct{}{},
}
}
return util.JSONResponse{
Code: http.StatusOK,
JSON: claimRes,
}
}
// ChangesInKeys returns the changes in the keys after last sync
// each user maintains a chain of the changes when provided by FED
func ChangesInKeys(
req *http.Request,
encryptionDB *storage.Database,
) util.JSONResponse {
// assuming federation has added keys to the DB,
// extracting from the DB here
// get from FED/Req
var readID int
var userID string
keyChanges, err := encryptionDB.GetKeyChanges(req.Context(), readID, userID)
if err != nil {
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: struct{}{},
}
}
changesRes := types.ChangesResponse{}
changesRes.Changed = keyChanges.Changed
changesRes.Left = keyChanges.Left
// delete the extracted keys from the DB
return util.JSONResponse{
Code: http.StatusOK,
JSON: changesRes,
}
}
// todo: check through interface for duplicate and what type of request should it be
// whether device or one time or both of them
func checkUpload(req *types.UploadEncryptSpecific, typ int) bool {
if typ == BODYDEVICEKEY {
devicekey := req.DeviceKeys
if devicekey.UserID == "" {
return false
}
}
if typ == BODYONETIMEKEY {
if req.OneTimeKey.KeyString == nil || req.OneTimeKey.KeyObject == nil {
return false
}
}
return true
}
// queryOneTimeKeys todo: complete this field through claim type
func queryOneTimeKeys(
ctx context.Context,
typ int,
userID, deviceID string,
encryptionDB *storage.Database,
) interface{} {
if typ == TYPESUM {
res, _ := encryptionDB.SelectOneTimeKeyCount(ctx, deviceID, userID)
return res
}
return nil
}
// ClearUnused when web client sign out, a clean should be processed, cause all keys would never been used from then on.
// todo: complete this function and invoke through sign out extension or some scenarios else those matter
func ClearUnused() {}
// persist both device keys and one time keys
func persistKeys(
ctx context.Context,
database *storage.Database,
body *types.UploadEncryptSpecific,
userID,
deviceID string,
) (err error) {
// in order to persist keys , a check,
// filtering the duplicates should be processed.
// true stands for counterparts are in request
// situation 1: only device keys
// situation 2: both device keys and one time keys
// situation 3: only one time keys
if checkUpload(body, BODYDEVICEKEY) {
deviceKeys := body.DeviceKeys
al := deviceKeys.Algorithm
err = persistAl(ctx, *database, userID, deviceID, al)
if err != nil {
return
}
if checkUpload(body, BODYONETIMEKEY) {
if err = persistBothKeys(ctx, body, userID, deviceID, database, deviceKeys); err != nil {
return
}
} else {
if err = persistDeviceKeys(ctx, userID, deviceID, database, deviceKeys); err != nil {
return
}
}
// notifier to sync server
upnotify(userID)
} else {
if checkUpload(body, BODYONETIMEKEY) {
if err = persistOneTimeKeys(ctx, body, userID, deviceID, database); err != nil {
return
}
} else {
return errors.New("failed to persist keys")
}
}
return err
}
// make keys instantiated to specific struct from keybody interface{}
func turnSpecific(
cont types.UploadEncrypt,
) (spec types.UploadEncryptSpecific) {
// both device keys are coordinate
spec.DeviceKeys = cont.DeviceKeys
spec.OneTimeKey.KeyString = make(map[string]string)
spec.OneTimeKey.KeyObject = make(map[string]types.KeyObject)
mapStringInterface := cont.OneTimeKey
for key, val := range mapStringInterface {
value, ok := val.(string)
if ok {
spec.OneTimeKey.KeyString[key] = value
} else {
valueObject := types.KeyObject{}
target, _ := json.Marshal(val)
err := json.Unmarshal(target, &valueObject)
if err != nil {
continue
}
spec.OneTimeKey.KeyObject[key] = valueObject
}
}
return
}
func persistAl(
ctx context.Context,
encryptDB storage.Database,
uid, device string,
al []string,
) (err error) {
err = encryptDB.InsertAl(ctx, uid, device, al)
return
}
func upnotify(userID string) {
m := sarama.ProducerMessage{
Topic: "keyUpdate",
Key: sarama.StringEncoder("key"),
Value: sarama.StringEncoder(userID),
}
keyProducer.ch.Input() <- &m
}
// InitNotifier initialize kafka notifier
func InitNotifier(base *basecomponent.BaseDendrite) {
keyProducer.base = base
pro, _ := sarama.NewAsyncProducer(base.Cfg.Kafka.Addresses, nil)
keyProducer.ch = pro
}
func persistBothKeys(
ctx context.Context,
body *types.UploadEncryptSpecific,
userID, deviceID string,
database *storage.Database,
deviceKeys types.DeviceKeys,
) (err error) {
// insert one time keys
err = persistOneTimeKeys(ctx, body, userID, deviceID, database)
if err != nil {
return
}
// insert device keys
err = persistDeviceKeys(ctx, userID, deviceID, database, deviceKeys)
if err != nil {
return
}
return
}
func persistDeviceKeys(
ctx context.Context,
userID, deviceID string,
database *storage.Database,
deviceKeys types.DeviceKeys,
) (err error) {
keys := deviceKeys.Keys
sigs := deviceKeys.Signature
for alDevice, key := range keys {
al := (strings.Split(alDevice, ":"))[0]
keyTyp := DEVICEKEYSTR
keyInfo := key
keyID := ""
sig := sigs[userID][fmt.Sprintf("%s:%s", "ed25519", deviceID)]
err = database.InsertKey(ctx, deviceID, userID, keyID, keyTyp, keyInfo, al, sig)
}
return
}
func persistOneTimeKeys(
ctx context.Context,
body *types.UploadEncryptSpecific,
userID, deviceID string,
database *storage.Database,
) (err error) {
onetimeKeys := body.OneTimeKey
for alKeyID, val := range onetimeKeys.KeyString {
al := (strings.Split(alKeyID, ":"))[0]
keyID := (strings.Split(alKeyID, ":"))[1]
keyInfo := val
oneTimeKeyStringTyp := ONETIMEKEYSTR
sig := ""
err = database.InsertKey(ctx, deviceID, userID, keyID, oneTimeKeyStringTyp, keyInfo, al, sig)
if err != nil {
return
}
}
for alKeyID, val := range onetimeKeys.KeyObject {
al := (strings.Split(alKeyID, ":"))[0]
keyID := (strings.Split(alKeyID, ":"))[1]
keyInfo := val.Key
oneTimeKeyObjectTyp := ONETIMEKEYSTR
sig := val.Signature[userID][fmt.Sprintf("%s:%s", "ed25519", deviceID)]
err = database.InsertKey(ctx, deviceID, userID, keyID, oneTimeKeyObjectTyp, keyInfo, al, sig)
if err != nil {
return
}
}
return
}

View file

@ -0,0 +1,96 @@
// 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 routing
import (
"net/http"
"time"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/encryptoapi/storage"
"github.com/matrix-org/dendrite/encryptoapi/types"
"github.com/matrix-org/util"
)
// QueryPKeys returns the public identity keys
// and supported algorithms of "intended user"
// This just forwards the request to the Federation,
// and waits/checks for timeouts and failures. Response
// of the FedSenderAPI is bundled with the failures and returned.
func QueryPKeys(
req *http.Request,
encryptionDB *storage.Database,
deviceID string,
deviceDB *devices.Database,
) util.JSONResponse {
var err error
var queryRq types.QueryRequest
if reqErr := httputil.UnmarshalJSONRequest(req, &queryRq); reqErr != nil {
return *reqErr
}
queryRp := types.QueryResponse{}
// sendDKToFed := queryRq.DeviceKeys
var obtainedFromFed types.QueryResponse
obtainedKeysFromFed := obtainedFromFed.DeviceKeys
queryRp.DeviceKeys = obtainedKeysFromFed
queryRp.Failure = make(map[string]interface{})
// FED must return the keys from the other user
/*
federation consideration: when user id is in federation, a
query is needed to ask fed for keys.
domain --------+ fed (keys)
domain +--tout-- timer
*/
// todo: Add federation processing at specific userID.
if false /*federation judgement*/ {
tout := queryRq.Timeout
if tout == 0 {
tout = int64(10 * time.Second)
}
stimuCh := make(chan int)
go func() {
time.Sleep(time.Duration(tout) * 1000 * 1000)
close(stimuCh)
}()
select {
case <-stimuCh:
queryRp.Failure = make(map[string]interface{})
// todo: key in this map is restricted to username at the end, yet a mocked one.
queryRp.Failure["@alice:localhost"] = "ran out of offered time"
case <-make(chan interface{}):
// todo : here goes federation chan , still a mocked one
}
// probably some other better error to tell it timed out in FED
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: struct{}{},
}
}
//
//
//
//
// Forward the request to the federation server and get the required info
return util.JSONResponse{
Code: http.StatusOK,
JSON: queryRp,
}
}

View file

@ -0,0 +1,269 @@
// 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 routing
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
"github.com/Shopify/sarama"
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/encryptoapi/storage"
"github.com/matrix-org/dendrite/encryptoapi/types"
"github.com/matrix-org/util"
"github.com/pkg/errors"
)
// UploadPKeys enables the user to upload his device
// and one time keys with limit at 50 set as default
func UploadPKeys(
req *http.Request,
encryptionDB *storage.Database,
userID, deviceID string,
) util.JSONResponse {
var keybody types.UploadEncrypt
if reqErr := httputil.UnmarshalJSONRequest(req, &keybody); reqErr != nil {
return *reqErr
}
keySpecific := turnSpecific(keybody)
// persist keys into encryptionDB
err := persistKeys(
req.Context(),
encryptionDB,
&keySpecific,
userID, deviceID)
// numMap is algorithm-num map
// this gets the number of unclaimed OTkeys
numMap, ok := (queryOneTimeKeys(
req.Context(),
TYPESUM,
userID,
deviceID,
encryptionDB)).(map[string]int)
if !ok {
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: struct{}{},
}
}
if err != nil {
return util.JSONResponse{
Code: http.StatusBadGateway,
JSON: types.UploadResponse{
Count: numMap,
},
}
}
return util.JSONResponse{
Code: http.StatusOK,
JSON: types.UploadResponse{
Count: numMap,
},
}
}
// make keys instantiated to specific struct from keybody interface{}
func turnSpecific(
cont types.UploadEncrypt,
) (spec types.UploadEncryptSpecific) {
// both device keys are coordinate
spec.DeviceKeys = cont.DeviceKeys
spec.OneTimeKey.KeyString = make(map[string]string)
spec.OneTimeKey.KeyObject = make(map[string]types.KeyObject)
mapStringInterface := cont.OneTimeKey
for key, val := range mapStringInterface {
value, ok := val.(string)
if ok {
spec.OneTimeKey.KeyString[key] = value
} else {
valueObject := types.KeyObject{}
target, _ := json.Marshal(val)
err := json.Unmarshal(target, &valueObject)
if err != nil {
continue
}
spec.OneTimeKey.KeyObject[key] = valueObject
}
}
return
}
// persist both device keys and one time keys
func persistKeys(
ctx context.Context,
database *storage.Database,
body *types.UploadEncryptSpecific,
userID,
deviceID string,
) (err error) {
// in order to persist keys , a check,
// filtering the duplicates should be processed.
// true stands for counterparts are in request
// situation 1: only device keys
// situation 2: both device keys and one time keys
// situation 3: only one time keys
if checkUpload(body, BODYDEVICEKEY) {
deviceKeys := body.DeviceKeys
al := deviceKeys.Algorithm
err = persistAlgo(ctx, *database, userID, deviceID, al)
if err != nil {
return
}
if checkUpload(body, BODYONETIMEKEY) {
if err = persistBothKeys(ctx, body, userID, deviceID, database, deviceKeys); err != nil {
return
}
} else {
if err = persistDeviceKeys(ctx, userID, deviceID, database, deviceKeys); err != nil {
return
}
}
// notifier to sync server
upnotify(userID)
} else {
if checkUpload(body, BODYONETIMEKEY) {
if err = persistOneTimeKeys(ctx, body, userID, deviceID, database); err != nil {
return
}
} else {
return errors.New("failed to persist keys")
}
}
return err
}
// todo: check through interface for duplicate and what type of request should it be
// whether device or one time or both of them
func checkUpload(req *types.UploadEncryptSpecific, typ int) bool {
if typ == BODYDEVICEKEY {
devicekey := req.DeviceKeys
if devicekey.UserID == "" {
return false
}
}
if typ == BODYONETIMEKEY {
if req.OneTimeKey.KeyString == nil || req.OneTimeKey.KeyObject == nil {
return false
}
}
return true
}
func persistAlgo(
ctx context.Context,
encryptDB storage.Database,
uid, device string,
al []string,
) (err error) {
err = encryptDB.InsertAl(ctx, uid, device, al)
return
}
// queryOneTimeKeys todo: complete this field through claim type
func queryOneTimeKeys(
ctx context.Context,
typ int,
userID, deviceID string,
encryptionDB *storage.Database,
) interface{} {
if typ == TYPESUM {
res, _ := encryptionDB.SelectOneTimeKeyCount(ctx, deviceID, userID)
return res
}
return nil
}
func upnotify(userID string) {
m := sarama.ProducerMessage{
Topic: "keyUpdate",
Key: sarama.StringEncoder("key"),
Value: sarama.StringEncoder(userID),
}
keyProducer.ch.Input() <- &m
}
func persistBothKeys(
ctx context.Context,
body *types.UploadEncryptSpecific,
userID, deviceID string,
database *storage.Database,
deviceKeys types.DeviceKeys,
) (err error) {
// insert one time keys
err = persistOneTimeKeys(ctx, body, userID, deviceID, database)
if err != nil {
return
}
// insert device keys
err = persistDeviceKeys(ctx, userID, deviceID, database, deviceKeys)
if err != nil {
return
}
return
}
func persistDeviceKeys(
ctx context.Context,
userID, deviceID string,
database *storage.Database,
deviceKeys types.DeviceKeys,
) (err error) {
keys := deviceKeys.Keys
sigs := deviceKeys.Signature
for alDevice, key := range keys {
al := (strings.Split(alDevice, ":"))[0]
keyTyp := DEVICEKEYSTR
keyInfo := key
keyID := ""
sig := sigs[userID][fmt.Sprintf("%s:%s", "ed25519", deviceID)]
err = database.InsertKey(ctx, deviceID, userID, keyID, keyTyp, keyInfo, al, sig)
}
return
}
func persistOneTimeKeys(
ctx context.Context,
body *types.UploadEncryptSpecific,
userID, deviceID string,
database *storage.Database,
) (err error) {
onetimeKeys := body.OneTimeKey
for alKeyID, val := range onetimeKeys.KeyString {
al := (strings.Split(alKeyID, ":"))[0]
keyID := (strings.Split(alKeyID, ":"))[1]
keyInfo := val
oneTimeKeyStringTyp := ONETIMEKEYSTR
sig := ""
err = database.InsertKey(ctx, deviceID, userID, keyID, oneTimeKeyStringTyp, keyInfo, al, sig)
if err != nil {
return
}
}
for alKeyID, val := range onetimeKeys.KeyObject {
al := (strings.Split(alKeyID, ":"))[0]
keyID := (strings.Split(alKeyID, ":"))[1]
keyInfo := val.Key
oneTimeKeyObjectTyp := ONETIMEKEYSTR
sig := val.Signature[userID][fmt.Sprintf("%s:%s", "ed25519", deviceID)]
err = database.InsertKey(ctx, deviceID, userID, keyID, oneTimeKeyObjectTyp, keyInfo, al, sig)
if err != nil {
return
}
}
return
}

View file

@ -1,4 +1,4 @@
// Copyright 2018 Vector Creations Ltd
// 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.

View file

@ -1,4 +1,4 @@
// Copyright 2018 Vector Creations Ltd
// 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.

View file

@ -1,4 +1,4 @@
// Copyright 2018 Vector Creations Ltd
// 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.