find lint revision in encryption api server codes

This commit is contained in:
terrill 2018-07-05 15:10:51 +08:00
parent 2e20f7bcab
commit d97c71992c
11 changed files with 324 additions and 398 deletions

View file

@ -32,9 +32,9 @@ import (
"github.com/matrix-org/dendrite/roomserver" "github.com/matrix-org/dendrite/roomserver"
"github.com/matrix-org/dendrite/syncapi" "github.com/matrix-org/dendrite/syncapi"
"github.com/matrix-org/dendrite/encryptoapi"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/matrix-org/dendrite/encryptoapi"
) )
var ( var (
@ -57,7 +57,7 @@ func main() {
alias, input, query := roomserver.SetupRoomServerComponent(base) alias, input, query := roomserver.SetupRoomServerComponent(base)
encryptoapi.SetupEcryptoapi(base, accountDB, deviceDB) encryptoapi.SetupEcryptoapi(base, deviceDB)
clientapi.SetupClientAPIComponent( clientapi.SetupClientAPIComponent(
base, deviceDB, accountDB, base, deviceDB, accountDB,

View file

@ -15,10 +15,9 @@
package encryptoapi package encryptoapi
import ( import (
"github.com/matrix-org/dendrite/common/basecomponent"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/encryptoapi/routing"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/dendrite/common/basecomponent"
"github.com/matrix-org/dendrite/encryptoapi/routing"
"github.com/matrix-org/dendrite/encryptoapi/storage" "github.com/matrix-org/dendrite/encryptoapi/storage"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -27,9 +26,10 @@ import (
// , CMD should involve this invoke into main function // , CMD should involve this invoke into main function
// , a setup need an assemble of i.e configs as base and // , a setup need an assemble of i.e configs as base and
// accountDB and deviceDB // accountDB and deviceDB
// SetupEcryptoapi set up to servers
func SetupEcryptoapi( func SetupEcryptoapi(
base *basecomponent.BaseDendrite, base *basecomponent.BaseDendrite,
accountsDB *accounts.Database,
deviceDB *devices.Database, deviceDB *devices.Database,
) { ) {
encryptionDB, err := storage.NewDatabase(string(base.Cfg.Database.EncryptAPI)) encryptionDB, err := storage.NewDatabase(string(base.Cfg.Database.EncryptAPI))
@ -38,9 +38,7 @@ func SetupEcryptoapi(
} }
routing.Setup( routing.Setup(
base.APIMux, base.APIMux,
*base.Cfg,
encryptionDB, encryptionDB,
accountsDB,
deviceDB, deviceDB,
) )
routing.InitNotifier(base) routing.InitNotifier(base)

View file

@ -15,33 +15,43 @@
package routing package routing
import ( import (
"github.com/matrix-org/util"
"github.com/matrix-org/dendrite/encryptoapi/storage"
"net/http"
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/encryptoapi/types"
"context" "context"
"github.com/pkg/errors"
"strings"
"fmt"
"encoding/json" "encoding/json"
"time" "fmt"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/dendrite/common/basecomponent"
"github.com/Shopify/sarama" "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/gomatrixserverlib"
"github.com/matrix-org/util"
"github.com/pkg/errors"
"net/http"
"strings"
"time"
) )
const ( const (
// TYPESUM sum type
TYPESUM = iota TYPESUM = iota
TYPECLAIM // BODYDEVICEKEY device key body
TYPEVAL
BODYDEVICEKEY BODYDEVICEKEY
// BODYONETIMEKEY one time key
BODYONETIMEKEY BODYONETIMEKEY
// ONETIMEKEYSTRING key string
ONETIMEKEYSTRING ONETIMEKEYSTRING
// ONETIMEKEYOBJECT key object
ONETIMEKEYOBJECT ONETIMEKEYOBJECT
) )
// ONETIMEKEYSTR stands for storage string property
const ONETIMEKEYSTR = "one_time_key"
// DEVICEKEYSTR stands for storage string property
const DEVICEKEYSTR = "device_key"
// KeyNotifier kafka notifier
type KeyNotifier struct { type KeyNotifier struct {
base *basecomponent.BaseDendrite base *basecomponent.BaseDendrite
ch sarama.AsyncProducer ch sarama.AsyncProducer
@ -49,32 +59,30 @@ type KeyNotifier struct {
var keyProducer = &KeyNotifier{} var keyProducer = &KeyNotifier{}
// this function is for user upload his device key, and one-time-key // UploadPKeys this function is for user upload his device key, and one-time-key to a limit at 50 set as default
// to a limit at 50 set as default
func UploadPKeys( func UploadPKeys(
req *http.Request, req *http.Request,
encryptionDB *storage.Database, encryptionDB *storage.Database,
userID, deviceID string, userID, deviceID string,
) util.JSONResponse { ) util.JSONResponse {
var keybody types.UploadEncrypt var keybody types.UploadEncrypt
if reqErr := httputil.UnmarshalJSONRequest(req, &keybody); if reqErr := httputil.UnmarshalJSONRequest(req, &keybody); reqErr != nil {
reqErr != nil {
return *reqErr return *reqErr
} }
keySpecific := turnSpecific(keybody) keySpecific := turnSpecific(keybody)
// persist keys into encryptionDB // persist keys into encryptionDB
err := persistKeys( err := persistKeys(
encryptionDB,
req.Context(), req.Context(),
encryptionDB,
&keySpecific, &keySpecific,
userID, deviceID) userID, deviceID)
// numMap is algorithm-num map // numMap is algorithm-num map
numMap := (QueryOneTimeKeys( numMap := (QueryOneTimeKeys(
req.Context(),
TYPESUM, TYPESUM,
userID, userID,
deviceID, deviceID,
encryptionDB, encryptionDB)).(map[string]int)
req.Context())).(map[string]int)
if err != nil { if err != nil {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusBadGateway, Code: http.StatusBadGateway,
@ -91,19 +99,19 @@ func UploadPKeys(
} }
} }
// this function is for user query other's device key // QueryPKeys this function is for user query other's device key
func QueryPKeys( func QueryPKeys(
req *http.Request, req *http.Request,
encryptionDB *storage.Database, encryptionDB *storage.Database,
userID, deviceID string, deviceID string,
deviceDB *devices.Database, deviceDB *devices.Database,
) util.JSONResponse { ) util.JSONResponse {
var err error
var queryRq types.QueryRequest var queryRq types.QueryRequest
queryRp := types.QueryResponse{} queryRp := types.QueryResponse{}
queryRp.Failure = make(map[string]interface{}) queryRp.Failure = make(map[string]interface{})
queryRp.DeviceKeys = make(map[string]map[string]types.DeviceKeysQuery) queryRp.DeviceKeys = make(map[string]map[string]types.DeviceKeysQuery)
if reqErr := httputil.UnmarshalJSONRequest(req, &queryRq); if reqErr := httputil.UnmarshalJSONRequest(req, &queryRq); reqErr != nil {
reqErr != nil {
return *reqErr return *reqErr
} }
@ -129,6 +137,8 @@ func QueryPKeys(
queryRp.Failure = make(map[string]interface{}) queryRp.Failure = make(map[string]interface{})
// todo: key in this map is restricted to username at the end, yet a mocked one. // 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" queryRp.Failure["@alice:localhost"] = "ran out of offered time"
case <-make(chan interface{}):
// todo : here goes federation chan , still a mocked one
} }
} }
@ -139,50 +149,35 @@ func QueryPKeys(
// backward compatible to old interface // backward compatible to old interface
midArr := []string{} midArr := []string{}
// figure out device list from devices described as device which is actually deviceID // figure out device list from devices described as device which is actually deviceID
for device, _ := range arr.(map[string]interface{}) { for device := range arr.(map[string]interface{}) {
midArr = append(midArr, device) midArr = append(midArr, device)
} }
// all device keys // all device keys
dkeys, _ := encryptionDB.QueryInRange(req.Context(), uid, midArr) dkeys, _ := encryptionDB.QueryInRange(req.Context(), uid, midArr)
// build response for them // build response for them
for _, key := range dkeys {
// preset for complicated nested map struct
if _, ok := deviceKeysQueryMap[key.Device_id]; !ok {
// make consistency
deviceKeysQueryMap[key.Device_id] = types.DeviceKeysQuery{}
}
if deviceKeysQueryMap[key.Device_id].Signature == nil {
mid := make(map[string]map[string]string)
midmap := deviceKeysQueryMap[key.Device_id]
midmap.Signature = mid
deviceKeysQueryMap[key.Device_id] = midmap
}
if deviceKeysQueryMap[key.Device_id].Keys == nil {
mid := make(map[string]string)
midmap := deviceKeysQueryMap[key.Device_id]
midmap.Keys = mid
deviceKeysQueryMap[key.Device_id] = midmap
}
if _, ok := deviceKeysQueryMap[key.Device_id].Signature[uid]; !ok {
// make consistency
deviceKeysQueryMap[key.Device_id].Signature[uid] = make(map[string]string)
}
// load for accomplishment
single := deviceKeysQueryMap[key.Device_id]
resKey := fmt.Sprintf("@%s:%s", key.Key_algorithm, key.Device_id) 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 resBody := key.Key
if _, ok := single.Keys[resKey]; !ok {
}
single.Keys[resKey] = resBody single.Keys[resKey] = resBody
single.DeviceId = key.Device_id single.DeviceID = key.DeviceID
single.UserId = key.User_id single.UserID = key.UserID
single.Signature[uid][fmt.Sprintf("@%s:%s", "ed25519", key.Device_id)] = key.Signature single.Signature[uid][fmt.Sprintf("@%s:%s", "ed25519", key.DeviceID)] = key.Signature
single.Algorithm, _ = takeAL(*encryptionDB, req.Context(), key.User_id, key.Device_id) single.Algorithm, err = takeAL(req.Context(), *encryptionDB, key.UserID, key.DeviceID)
localpart, _, _ := gomatrixserverlib.SplitID('@', uid) localpart, _, _ := gomatrixserverlib.SplitID('@', uid)
device, _ := deviceDB.GetDeviceByID(req.Context(), localpart, deviceID) device, _ := deviceDB.GetDeviceByID(req.Context(), localpart, deviceID)
single.Unsigned.Info = device.DisplayName single.Unsigned.Info = device.DisplayName
deviceKeysQueryMap[key.Device_id] = single deviceKeysQueryMap[key.DeviceID] = single
}
}
if err != nil {
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: queryRp,
} }
} }
return util.JSONResponse{ return util.JSONResponse{
@ -191,12 +186,10 @@ func QueryPKeys(
} }
} }
// claim for one time key that may be used in session exchange in olm encryption // ClaimOneTimeKeys claim for one time key that may be used in session exchange in olm encryption
func ClaimOneTimeKeys( func ClaimOneTimeKeys(
req *http.Request, req *http.Request,
encryptionDB *storage.Database, encryptionDB *storage.Database,
userID, deviceID string,
deviceDB *devices.Database,
) util.JSONResponse { ) util.JSONResponse {
var claimRq types.ClaimRequest var claimRq types.ClaimRequest
claimRp := types.ClaimResponse{} claimRp := types.ClaimResponse{}
@ -224,6 +217,8 @@ func ClaimOneTimeKeys(
claimRp.Failures = make(map[string]interface{}) claimRp.Failures = make(map[string]interface{})
// todo: key in this map is restricted to username at the end, yet a mocked one. // 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" claimRp.Failures["@alice:localhost"] = "ran out of offered time"
case <-make(chan interface{}):
// todo : here goes federation chan , still a mocked one
} }
} }
@ -236,21 +231,24 @@ func ClaimOneTimeKeys(
} else { } else {
alTyp = ONETIMEKEYSTRING alTyp = ONETIMEKEYSTRING
} }
key, err := pickOne(*encryptionDB, req.Context(), uid, deviceID, al) key, err := pickOne(req.Context(), *encryptionDB, uid, deviceID, al)
if err != nil { if err != nil {
claimRp.Failures[uid] = fmt.Sprintf("%s:%s", "fail to get keys for device ", deviceID) claimRp.Failures[uid] = fmt.Sprintf("%s:%s", "fail to get keys for device ", deviceID)
} }
claimRp.ClaimBody[uid] = make(map[string]map[string]interface{}) claimRp.ClaimBody[uid] = make(map[string]map[string]interface{})
keymap := claimRp.ClaimBody[uid][deviceID] keyPreMap := claimRp.ClaimBody[uid]
keymap := keyPreMap[deviceID]
if keymap == nil {
keymap = make(map[string]interface{}) keymap = make(map[string]interface{})
}
switch alTyp { switch alTyp {
case ONETIMEKEYSTRING: case ONETIMEKEYSTRING:
keymap[fmt.Sprintf("%s:%s", al, key.Key_id)] = key.Key keymap[fmt.Sprintf("%s:%s", al, key.KeyID)] = key.Key
case ONETIMEKEYOBJECT: case ONETIMEKEYOBJECT:
sig := make(map[string]map[string]string) sig := make(map[string]map[string]string)
sig[uid] = make(map[string]string) sig[uid] = make(map[string]string)
sig[uid][fmt.Sprintf("%s:%s", "ed25519", deviceID)] = key.Signature sig[uid][fmt.Sprintf("%s:%s", "ed25519", deviceID)] = key.Signature
keymap[fmt.Sprintf("%s:%s", al, key.Key_id)] = types.KeyObject{Key: key.Key, Signature: sig} keymap[fmt.Sprintf("%s:%s", al, key.KeyID)] = types.KeyObject{Key: key.Key, Signature: sig}
} }
claimRp.ClaimBody[uid][deviceID] = keymap claimRp.ClaimBody[uid][deviceID] = keymap
} }
@ -261,19 +259,12 @@ func ClaimOneTimeKeys(
} }
} }
func LookUpChangedPKeys() util.JSONResponse {
return util.JSONResponse{
Code: http.StatusOK,
JSON: struct{}{},
}
}
// todo: check through interface for duplicate and what type of request should it be // todo: check through interface for duplicate and what type of request should it be
// whether device or one time or both of them // whether device or one time or both of them
func checkUpload(req *types.UploadEncryptSpecific, typ int) bool { func checkUpload(req *types.UploadEncryptSpecific, typ int) bool {
if typ == BODYDEVICEKEY { if typ == BODYDEVICEKEY {
devicekey := req.DeviceKeys devicekey := req.DeviceKeys
if devicekey.UserId == "" { if devicekey.UserID == "" {
return false return false
} }
} }
@ -285,12 +276,12 @@ func checkUpload(req *types.UploadEncryptSpecific, typ int) bool {
return true return true
} }
// todo: complete this field through claim type // QueryOneTimeKeys todo: complete this field through claim type
func QueryOneTimeKeys( func QueryOneTimeKeys(
ctx context.Context,
typ int, typ int,
userID, deviceID string, userID, deviceID string,
encryptionDB *storage.Database, encryptionDB *storage.Database,
ctx context.Context,
) interface{} { ) interface{} {
if typ == TYPESUM { if typ == TYPESUM {
res, _ := encryptionDB.SelectOneTimeKeyCount(ctx, deviceID, userID) res, _ := encryptionDB.SelectOneTimeKeyCount(ctx, deviceID, userID)
@ -299,14 +290,14 @@ func QueryOneTimeKeys(
return nil 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 // todo: complete this function and invoke through sign out extension or some scenarios else those matter
// when web client sign out, a clean should be processed, cause all keys would never been used from then on.
func ClearUnused() {} func ClearUnused() {}
// persist both device keys and one time keys // persist both device keys and one time keys
func persistKeys( func persistKeys(
database *storage.Database,
ctx context.Context, ctx context.Context,
database *storage.Database,
body *types.UploadEncryptSpecific, body *types.UploadEncryptSpecific,
userID, userID,
deviceID string, deviceID string,
@ -319,73 +310,28 @@ func persistKeys(
if checkUpload(body, BODYDEVICEKEY) { if checkUpload(body, BODYDEVICEKEY) {
deviceKeys := body.DeviceKeys deviceKeys := body.DeviceKeys
al := deviceKeys.Algorithm al := deviceKeys.Algorithm
err = persistAl(*database, ctx, userID, deviceID, al) err = persistAl(ctx, *database, userID, deviceID, al)
if err != nil {
return
}
if checkUpload(body, BODYONETIMEKEY) { if checkUpload(body, BODYONETIMEKEY) {
// insert one time keys firstly if err = bothKeyProcess(ctx, body, userID, deviceID, database, deviceKeys); err != nil {
onetimeKeys := body.OneTimeKey return
for al_keyID, val := range onetimeKeys.KeyString {
al := (strings.Split(al_keyID, ":"))[0]
keyID := (strings.Split(al_keyID, ":"))[1]
keyInfo := val
keyTyp := "one_time_key"
sig := ""
database.InsertKey(ctx, deviceID, userID, keyID, keyTyp, keyInfo, al, sig)
}
for al_keyID, val := range onetimeKeys.KeyObject {
al := (strings.Split(al_keyID, ":"))[0]
keyID := (strings.Split(al_keyID, ":"))[1]
keyInfo := val.Key
keyTyp := "one_time_key"
sig := val.Signature[userID][fmt.Sprintf("%s:%s", "ed25519", deviceID)]
database.InsertKey(ctx, deviceID, userID, keyID, keyTyp, keyInfo, al, sig)
}
// insert device keys
keys := deviceKeys.Keys
sigs := deviceKeys.Signature
for al_device, key := range keys {
al := (strings.Split(al_device, ":"))[0]
keyTyp := "device_key"
keyInfo := key
keyID := ""
sig := sigs[userID][fmt.Sprintf("%s:%s", "ed25519", deviceID)]
database.InsertKey(
ctx, deviceID, userID, keyID, keyTyp, keyInfo, al, sig)
} }
} else { } else {
keys := deviceKeys.Keys if err = dkeyProcess(ctx, userID, deviceID, database, deviceKeys); err != nil {
sigs := deviceKeys.Signature return
for al_device, key := range keys {
al := (strings.Split(al_device, ":"))[0]
keyTyp := "device_key"
keyInfo := key
keyID := ""
sig := sigs[userID][fmt.Sprintf("%s:%s", "ed25519", deviceID)]
database.InsertKey(ctx, deviceID, userID, keyID, keyTyp, keyInfo, al, sig)
} }
} }
// notifier to sync server // notifier to sync server
upnotify(userID) upnotify(userID)
} else { } else {
if checkUpload(body, BODYONETIMEKEY) { if checkUpload(body, BODYONETIMEKEY) {
onetimeKeys := body.OneTimeKey if err = otmKeyProcess(ctx, body, userID, deviceID, database); err != nil {
for al_keyID, val := range onetimeKeys.KeyString { return
al := (strings.Split(al_keyID, ":"))[0]
keyID := (strings.Split(al_keyID, ":"))[1]
keyInfo := val
keyTyp := "one_time_key"
sig := ""
database.InsertKey(ctx, deviceID, userID, keyID, keyTyp, keyInfo, al, sig)
}
for al_keyID, val := range onetimeKeys.KeyObject {
al := (strings.Split(al_keyID, ":"))[0]
keyID := (strings.Split(al_keyID, ":"))[1]
keyInfo := val.Key
keyTyp := "one_time_key"
sig := val.Signature[userID][fmt.Sprintf("%s:%s", "ed25519", deviceID)]
database.InsertKey(ctx, deviceID, userID, keyID, keyTyp, keyInfo, al, sig)
} }
} else { } else {
return errors.New("Fail to touch keys !") return errors.New("failed to touch keys")
} }
} }
return err return err
@ -407,7 +353,10 @@ func turnSpecific(
} else { } else {
valueObject := types.KeyObject{} valueObject := types.KeyObject{}
target, _ := json.Marshal(val) target, _ := json.Marshal(val)
json.Unmarshal(target, &valueObject) err := json.Unmarshal(target, &valueObject)
if err != nil {
continue
}
spec.OneTimeKey.KeyObject[key] = valueObject spec.OneTimeKey.KeyObject[key] = valueObject
} }
} }
@ -415,8 +364,8 @@ func turnSpecific(
} }
func persistAl( func persistAl(
encryptDB storage.Database,
ctx context.Context, ctx context.Context,
encryptDB storage.Database,
uid, device string, uid, device string,
al []string, al []string,
) (err error) { ) (err error) {
@ -425,8 +374,8 @@ func persistAl(
} }
func takeAL( func takeAL(
encryptDB storage.Database,
ctx context.Context, ctx context.Context,
encryptDB storage.Database,
uid, device string, uid, device string,
) (al []string, err error) { ) (al []string, err error) {
al, err = encryptDB.SelectAl(ctx, uid, device) al, err = encryptDB.SelectAl(ctx, uid, device)
@ -434,8 +383,8 @@ func takeAL(
} }
func pickOne( func pickOne(
encryptDB storage.Database,
ctx context.Context, ctx context.Context,
encryptDB storage.Database,
uid, device, al string, uid, device, al string,
) (key types.KeyHolder, err error) { ) (key types.KeyHolder, err error) {
key, err = encryptDB.SelectOneTimeKeySingle(ctx, uid, device, al) key, err = encryptDB.SelectOneTimeKeySingle(ctx, uid, device, al)
@ -451,8 +400,138 @@ func upnotify(userID string) {
keyProducer.ch.Input() <- &m keyProducer.ch.Input() <- &m
} }
// InitNotifier initialize kafka notifier
func InitNotifier(base *basecomponent.BaseDendrite) { func InitNotifier(base *basecomponent.BaseDendrite) {
keyProducer.base = base keyProducer.base = base
pro, _ := sarama.NewAsyncProducer(base.Cfg.Kafka.Addresses, nil) pro, _ := sarama.NewAsyncProducer(base.Cfg.Kafka.Addresses, nil)
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 bothKeyProcess(
ctx context.Context,
body *types.UploadEncryptSpecific,
userID, deviceID string,
database *storage.Database,
deviceKeys types.DeviceKeys,
) (err error) {
// insert one time keys firstly
onetimeKeys := body.OneTimeKey
for alKeyID, val := range onetimeKeys.KeyString {
al := (strings.Split(alKeyID, ":"))[0]
keyID := (strings.Split(alKeyID, ":"))[1]
keyInfo := val
keyStringTyp := ONETIMEKEYSTR
sig := ""
err = database.InsertKey(ctx, deviceID, userID, keyID, keyStringTyp, 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
keyObjectTyp := ONETIMEKEYSTR
sig := val.Signature[userID][fmt.Sprintf("%s:%s", "ed25519", deviceID)]
err = database.InsertKey(ctx, deviceID, userID, keyID, keyObjectTyp, keyInfo, al, sig)
if err != nil {
return
}
}
// insert device keys
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)
if err != nil {
return
}
}
return
}
func dkeyProcess(
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 otmKeyProcess(
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

@ -19,26 +19,21 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common"
"github.com/matrix-org/dendrite/common/config"
"github.com/matrix-org/dendrite/encryptoapi/storage" "github.com/matrix-org/dendrite/encryptoapi/storage"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
const pathPrefixR0 = "/_matrix/client/r0"
const pathPrefixUnstable = "/_matrix/client/unstable" const pathPrefixUnstable = "/_matrix/client/unstable"
// Setup works for setting up encryption api server
func Setup( func Setup(
apiMux *mux.Router, apiMux *mux.Router,
cfg config.Dendrite,
encryptionDB *storage.Database, encryptionDB *storage.Database,
accountDB *accounts.Database,
deviceDB *devices.Database, deviceDB *devices.Database,
) { ) {
//r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter()
unstablemux := apiMux.PathPrefix(pathPrefixUnstable).Subrouter() unstablemux := apiMux.PathPrefix(pathPrefixUnstable).Subrouter()
unstablemux.Handle("/keys/upload/{deviceID}", unstablemux.Handle("/keys/upload/{deviceID}",
@ -56,16 +51,14 @@ func Setup(
unstablemux.Handle("/keys/query", unstablemux.Handle("/keys/query",
common.MakeAuthAPI("query keys", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse { common.MakeAuthAPI("query keys", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
//vars := mux.Vars(req) //vars := mux.Vars(req)
return QueryPKeys(req, encryptionDB, device.UserID, device.ID, deviceDB) return QueryPKeys(req, encryptionDB, device.ID, deviceDB)
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
unstablemux.Handle("/keys/claim", unstablemux.Handle("/keys/claim",
common.MakeAuthAPI("claim keys", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse { common.MakeAuthAPI("claim keys", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
//vars := mux.Vars(req) return ClaimOneTimeKeys(req, encryptionDB)
return ClaimOneTimeKeys(req, encryptionDB, device.UserID, device.ID, deviceDB)
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
} }

View file

@ -15,8 +15,8 @@
package storage package storage
import ( import (
"database/sql"
"context" "context"
"database/sql"
"github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common"
"github.com/matrix-org/dendrite/encryptoapi/types" "github.com/matrix-org/dendrite/encryptoapi/types"
) )
@ -59,29 +59,29 @@ func (s *alStatements) prepare(db *sql.DB) (err error) {
} }
// persist algorithms // persist algorithms
func (ks *alStatements) insertAl( func (s *alStatements) insertAl(
ctx context.Context, txn *sql.Tx, ctx context.Context, txn *sql.Tx,
userID, deviceID, algorithms string, userID, deviceID, algorithms string,
) error { ) error {
stmt := common.TxStmt(txn, ks.insertAlStmt) stmt := common.TxStmt(txn, s.insertAlStmt)
_, err := stmt.ExecContext(ctx, deviceID, userID, algorithms) _, err := stmt.ExecContext(ctx, deviceID, userID, algorithms)
return err return err
} }
// select algorithms // select algorithms
func (ks *alStatements) selectAl( func (s *alStatements) selectAl(
ctx context.Context, ctx context.Context,
txn *sql.Tx, txn *sql.Tx,
userID, deviceID string, userID, deviceID string,
) (holder types.AlHolder, err error) { ) (holder types.AlHolder, err error) {
stmt := common.TxStmt(txn, ks.selectAlStmt) stmt := common.TxStmt(txn, s.selectAlStmt)
row := stmt.QueryRowContext(ctx, userID, deviceID) row := stmt.QueryRowContext(ctx, userID, deviceID)
single := types.AlHolder{} single := types.AlHolder{}
err = row.Scan( err = row.Scan(
&single.User_id, &single.UserID,
&single.Device_id, &single.DeviceID,
&single.Supported_algorithm, &single.SupportedAlgorithm,
) )
return single, err return single, err
} }

View file

@ -15,11 +15,11 @@
package storage package storage
import ( import (
"database/sql"
"context" "context"
"database/sql"
"github.com/lib/pq"
"github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common"
"github.com/matrix-org/dendrite/encryptoapi/types" "github.com/matrix-org/dendrite/encryptoapi/types"
"github.com/lib/pq"
) )
const keysSchema = ` const keysSchema = `
@ -96,104 +96,106 @@ func (s *keyStatements) prepare(db *sql.DB) (err error) {
} }
// insert keys // insert keys
func (ks *keyStatements) insertKey( func (s *keyStatements) insertKey(
ctx context.Context, txn *sql.Tx, ctx context.Context, txn *sql.Tx,
deviceID, userID, keyID, keyTyp, keyInfo, algorithm, signature string, deviceID, userID, keyID, keyTyp, keyInfo, algorithm, signature string,
) error { ) error {
stmt := common.TxStmt(txn, ks.insertKeyStmt) stmt := common.TxStmt(txn, s.insertKeyStmt)
_, err := stmt.ExecContext(ctx, deviceID, userID, keyID, keyTyp, keyInfo, algorithm, signature) _, err := stmt.ExecContext(ctx, deviceID, userID, keyID, keyTyp, keyInfo, algorithm, signature)
return err return err
} }
// select by user and device // select by user and device
func (ks *keyStatements) selectKey( func (s *keyStatements) selectKey(
ctx context.Context, ctx context.Context,
txn *sql.Tx, txn *sql.Tx,
deviceID, userID string, deviceID, userID string,
) (holders []types.KeyHolder, err error) { ) ([]types.KeyHolder, error) {
stmt := common.TxStmt(txn, ks.selectKeyStmt) holders := []types.KeyHolder{}
stmt := common.TxStmt(txn, s.selectKeyStmt)
rows, err := stmt.QueryContext(ctx, userID, deviceID) rows, err := stmt.QueryContext(ctx, userID, deviceID)
defer rows.Close()
if err != nil { if err != nil {
return nil, err return nil, err
} }
for rows.Next() { for rows.Next() {
single := &types.KeyHolder{} single := &types.KeyHolder{}
if err := rows.Scan( if err = rows.Scan(
&single.User_id, &single.UserID,
&single.Device_id, &single.DeviceID,
&single.Key_id, &single.KeyID,
&single.Key_type, &single.KeyType,
&single.Key, &single.Key,
&single.Key_algorithm, &single.KeyAlgorithm,
&single.Signature, &single.Signature,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
holders = append(holders, *single) holders = append(holders, *single)
} }
err = rows.Close()
return holders, err return holders, err
} }
// select single one for claim usage // select single one for claim usage
func (ks *keyStatements) selectSingleKey( func (s *keyStatements) selectSingleKey(
ctx context.Context, ctx context.Context,
userID, deviceID, algorithm string, userID, deviceID, algorithm string,
) (holder types.KeyHolder, err error) { ) (holder types.KeyHolder, err error) {
stmt := ks.selectSingleKeyStmt stmt := s.selectSingleKeyStmt
row := stmt.QueryRowContext(ctx, userID, deviceID, algorithm) row := stmt.QueryRowContext(ctx, userID, deviceID, algorithm)
if err != nil { if err != nil {
return holder, err return holder, err
} }
if err := row.Scan( if err = row.Scan(
&holder.User_id, &holder.UserID,
&holder.Device_id, &holder.DeviceID,
&holder.Key_id, &holder.KeyID,
&holder.Key_type, &holder.KeyType,
&holder.Key, &holder.Key,
&holder.Key_algorithm, &holder.KeyAlgorithm,
&holder.Signature, &holder.Signature,
); err != nil { ); err != nil {
deleteStmt := ks.deleteSingleKeyStmt deleteStmt := s.deleteSingleKeyStmt
deleteStmt.ExecContext(ctx, userID, deviceID, algorithm, holder.Key_id) _, err = deleteStmt.ExecContext(ctx, userID, deviceID, algorithm, holder.KeyID)
return holder, err return holder, err
} }
return holder, err return holder, err
} }
// select details by given an array of devices // select details by given an array of devices
func (ks *keyStatements) selectInKeys( func (s *keyStatements) selectInKeys(
ctx context.Context, ctx context.Context,
userID string, userID string,
arr []string, arr []string,
) (holders []types.KeyHolder, err error) { ) (holders []types.KeyHolder, err error) {
rows := &sql.Rows{} rows := sql.Rows{}
defer rows.Close() rowsP := &rows
stmt := ks.selectAllKeyStmt stmt := s.selectAllKeyStmt
if len(arr) == 0 { if len(arr) == 0 {
rows, err = stmt.QueryContext(ctx, userID, "device_key") rowsP, err = stmt.QueryContext(ctx, userID, "device_key")
} else { } else {
stmt = ks.selectInKeysStmt stmt = s.selectInKeysStmt
list := pq.Array(arr) list := pq.Array(arr)
rows, err = stmt.QueryContext(ctx, userID, list) rowsP, err = stmt.QueryContext(ctx, userID, list)
} }
if err != nil { if err != nil {
return nil, err return nil, err
} }
for rows.Next() { for rows.Next() {
single := &types.KeyHolder{} single := &types.KeyHolder{}
if err := rows.Scan( if err = rows.Scan(
&single.User_id, &single.UserID,
&single.Device_id, &single.DeviceID,
&single.Key_id, &single.KeyID,
&single.Key_type, &single.KeyType,
&single.Key, &single.Key,
&single.Key_algorithm, &single.KeyAlgorithm,
&single.Signature, &single.Signature,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
holders = append(holders, *single) holders = append(holders, *single)
} }
err = rowsP.Close()
return holders, err return holders, err
} }

View file

@ -15,9 +15,9 @@
package storage package storage
import ( import (
"context"
"database/sql" "database/sql"
"github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common"
"context"
"github.com/matrix-org/dendrite/encryptoapi/types" "github.com/matrix-org/dendrite/encryptoapi/types"
"strings" "strings"
) )
@ -47,7 +47,7 @@ func NewDatabase(dataSourceName string) (*Database, error) {
return &Database{db: db, keyStatements: keyStatement, alStatements: alStatement}, nil return &Database{db: db, keyStatements: keyStatement, alStatements: alStatement}, nil
} }
// insert device key // InsertKey insert device key
func (d *Database) InsertKey( func (d *Database) InsertKey(
ctx context.Context, ctx context.Context,
deviceID, userID, keyID, keyTyp, keyInfo, al, sig string, deviceID, userID, keyID, keyTyp, keyInfo, al, sig string,
@ -58,7 +58,7 @@ func (d *Database) InsertKey(
return return
} }
// for key upload response usage a map from key algorithm to sum to counterpart // SelectOneTimeKeyCount for key upload response usage a map from key algorithm to sum to counterpart
func (d *Database) SelectOneTimeKeyCount( func (d *Database) SelectOneTimeKeyCount(
ctx context.Context, ctx context.Context,
deviceID, userID string, deviceID, userID string,
@ -67,11 +67,11 @@ func (d *Database) SelectOneTimeKeyCount(
err = common.WithTransaction(d.db, func(txn *sql.Tx) error { err = common.WithTransaction(d.db, func(txn *sql.Tx) error {
elems, err := d.keyStatements.selectKey(ctx, txn, deviceID, userID) elems, err := d.keyStatements.selectKey(ctx, txn, deviceID, userID)
for _, val := range elems { for _, val := range elems {
if _, ok := m[val.Key_algorithm]; !ok { if _, ok := m[val.KeyAlgorithm]; !ok {
m[val.Key_algorithm] = 0 m[val.KeyAlgorithm] = 0
} }
if val.Key_type == "one_time_key" { if val.KeyType == "one_time_key" {
m[val.Key_algorithm] += 1 m[val.KeyAlgorithm]++
} }
} }
return err return err
@ -79,7 +79,7 @@ func (d *Database) SelectOneTimeKeyCount(
return return
} }
// query keys in a range of devices // QueryInRange query keys in a range of devices
func (d *Database) QueryInRange( func (d *Database) QueryInRange(
ctx context.Context, ctx context.Context,
userID string, userID string,
@ -89,30 +89,30 @@ func (d *Database) QueryInRange(
return return
} }
// persist algorithms // InsertAl persist algorithms
func (d *Database) InsertAl( func (d *Database) InsertAl(
ctx context.Context, uid, device string, al []string, ctx context.Context, uid, device string, al []string,
) (err error) { ) (err error) {
err = common.WithTransaction(d.db, func(txn *sql.Tx) (err error) { err = common.WithTransaction(d.db, func(txn *sql.Tx) (err error) {
d.alStatements.insertAl(ctx, txn, uid, device, strings.Join(al, ",")) err = d.alStatements.insertAl(ctx, txn, uid, device, strings.Join(al, ","))
return return
}) })
return return
} }
// select algorithms // SelectAl select algorithms
func (d *Database) SelectAl( func (d *Database) SelectAl(
ctx context.Context, uid, device string, ctx context.Context, uid, device string,
) (res []string, err error) { ) (res []string, err error) {
err = common.WithTransaction(d.db, func(txn *sql.Tx) (err error) { err = common.WithTransaction(d.db, func(txn *sql.Tx) (err error) {
holder, err := d.alStatements.selectAl(ctx, txn, uid, device) holder, err := d.alStatements.selectAl(ctx, txn, uid, device)
res = strings.Split(holder.Supported_algorithm, ",") res = strings.Split(holder.SupportedAlgorithm, ",")
return return
}) })
return return
} }
// claim for one time key one for once // SelectOneTimeKeySingle claim for one time key one for once
func (d *Database) SelectOneTimeKeySingle( func (d *Database) SelectOneTimeKeySingle(
ctx context.Context, ctx context.Context,
userID, deviceID, algorithm string, userID, deviceID, algorithm string,

View file

@ -14,40 +14,13 @@
package types package types
/* // ClaimRequest structure
{
"timeout": 10000,
"one_time_keys": {
"@alice:example.com": {
"JLAFKJWSCS": "curve25519"
}
}
}
*/
type ClaimRequest struct { type ClaimRequest struct {
Timeout int64 `json:"timeout"` Timeout int64 `json:"timeout"`
ClaimDetail map[string]map[string]string `json:"one_time_keys"` ClaimDetail map[string]map[string]string `json:"one_time_keys"`
} }
/* // ClaimResponse structure
{
"failures": {},
"one_time_keys": {
"@alice:example.com": {
"JLAFKJWSCS": {
"signed_curve25519:AAAAHg": {
"key": "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs",
"signatures": {
"@alice:example.com": {
"ed25519:JLAFKJWSCS": "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw"
}
}
}
}
}
}
}
*/
type ClaimResponse struct { type ClaimResponse struct {
Failures map[string]interface{} `json:"failures"` Failures map[string]interface{} `json:"failures"`
ClaimBody map[string]map[string]map[string]interface{} `json:"one_time_keys"` ClaimBody map[string]map[string]map[string]interface{} `json:"one_time_keys"`

View file

@ -14,63 +14,30 @@
package types package types
/* // QueryRequest structure
{
"timeout": 10000,
"device_keys": {
"@alice:example.com": ["DISYYYX","XYIISONM"]
}
}
*/
type QueryRequest struct { type QueryRequest struct {
Timeout int64 `json:"timeout"` Timeout int64 `json:"timeout"`
DeviceKeys map[string]interface{} `json:"device_keys"` DeviceKeys map[string]interface{} `json:"device_keys"`
Token string `json:"token"` Token string `json:"token"`
} }
/* // QueryResponse structure
{
"failures": {},
"device_keys": {
"@alice:example.com": {
"JLAFKJWSCS": {
"user_id": "@alice:example.com",
"device_id": "JLAFKJWSCS",
"algorithms": [
"m.olm.curve25519-aes-sha256",
"m.megolm.v1.aes-sha"
],
"keys": {
"curve25519:JLAFKJWSCS": "3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI",
"ed25519:JLAFKJWSCS": "lEuiRJBit0IG6nUf5pUzWTUEsRVVe/HJkoKuEww9ULI"
},
"signatures": {
"@alice:example.com": {
"ed25519:JLAFKJWSCS": "dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA"
}
},
"unsigned": {
"device_display_name": "Alice's mobile phone"
}
}
}
}
}
*/
type QueryResponse struct { type QueryResponse struct {
Failure map[string]interface{} `json:"failures"` Failure map[string]interface{} `json:"failures"`
DeviceKeys map[string]map[string]DeviceKeysQuery `json:"device_keys"` DeviceKeys map[string]map[string]DeviceKeysQuery `json:"device_keys"`
} }
// DeviceKeysQuery structure
type DeviceKeysQuery struct { type DeviceKeysQuery struct {
UserId string `json:"user_id"` UserID string `json:"user_id"`
DeviceId string `json:"device_id"` DeviceID string `json:"device_id"`
Algorithm []string `json:"algorithms"` Algorithm []string `json:"algorithms"`
Keys map[string]string `json:"keys"` Keys map[string]string `json:"keys"`
Signature map[string]map[string]string `json:"signatures"` Signature map[string]map[string]string `json:"signatures"`
Unsigned UnsignedDeviceInfo `json:"unsigned"` Unsigned UnsignedDeviceInfo `json:"unsigned"`
} }
// UnsignedDeviceInfo structure
type UnsignedDeviceInfo struct { type UnsignedDeviceInfo struct {
Info string `json:"device_display_name"` Info string `json:"device_display_name"`
} }

View file

@ -14,17 +14,20 @@
package types package types
// KeyHolder structure
type KeyHolder struct { type KeyHolder struct {
User_id, UserID,
Device_id, DeviceID,
Signature, key, Signature,
Key_algorithm, KeyAlgorithm,
Key_id, KeyID,
Key, Key,
Key_type string KeyType string
} }
// AlHolder structure
type AlHolder struct { type AlHolder struct {
User_id, UserID,
Device_id, DeviceID,
Supported_algorithm string SupportedAlgorithm string
} }

View file

@ -14,135 +14,46 @@
package types package types
/* // UploadEncrypt structure
{
"device_keys": {
"user_id": "@alice:example.com",
"device_id": "JLAFKJWSCS",
"algorithms": [
"m.olm.curve25519-aes-sha256",
"m.megolm.v1.aes-sha"
],
"keys": {
"curve25519:JLAFKJWSCS": "3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI",
"ed25519:JLAFKJWSCS": "lEuiRJBit0IG6nUf5pUzWTUEsRVVe/HJkoKuEww9ULI"
},
"signatures": {
"@alice:example.com": {
"ed25519:JLAFKJWSCS": "dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA"
}
}
},
"one_time_keys": {
"curve25519:AAAAAQ": "/qyvZvwjiTxGdGU0RCguDCLeR+nmsb3FfNG3/Ve4vU8",
"signed_curve25519:AAAAHg": {
"key": "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs",
"signatures": {
"@alice:example.com": {
"ed25519:JLAFKJWSCS": "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw"
}
}
},
"signed_curve25519:AAAAHQ": {
"key": "j3fR3HemM16M7CWhoI4Sk5ZsdmdfQHsKL1xuSft6MSw",
"signatures": {
"@alice:example.com": {
"ed25519:JLAFKJWSCS": "IQeCEPb9HFk217cU9kw9EOiusC6kMIkoIRnbnfOh5Oc63S1ghgyjShBGpu34blQomoalCyXWyhaaT3MrLZYQAA"
}
}
}
}
}
*/
type UploadEncrypt struct { type UploadEncrypt struct {
DeviceKeys DeviceKeys `json:"device_keys"` DeviceKeys DeviceKeys `json:"device_keys"`
OneTimeKey map[string]interface{} `json:"one_time_keys"` OneTimeKey map[string]interface{} `json:"one_time_keys"`
} }
// UploadEncryptSpecific structure
type UploadEncryptSpecific struct { type UploadEncryptSpecific struct {
DeviceKeys DeviceKeys `json:"device_keys"` DeviceKeys DeviceKeys `json:"device_keys"`
OneTimeKey OneTimeKeySpecific `json:"one_time_keys"` OneTimeKey OneTimeKeySpecific `json:"one_time_keys"`
} }
/* // UploadResponse structure
{
"one_time_key_counts": {
"curve25519": 10,
"signed_curve25519": 20
}
}
*/
type UploadResponse struct { type UploadResponse struct {
Count map[string]int `json:"one_time_key_counts"` Count map[string]int `json:"one_time_key_counts"`
} }
/* // DeviceKeys structure
"device_keys": {
"user_id": "@alice:example.com",
"device_id": "JLAFKJWSCS",
"algorithms": [
"m.olm.curve25519-aes-sha256",
"m.megolm.v1.aes-sha"
],
"keys": {
"curve25519:JLAFKJWSCS": "3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI",
"ed25519:JLAFKJWSCS": "lEuiRJBit0IG6nUf5pUzWTUEsRVVe/HJkoKuEww9ULI"
},
"signatures": {
"@alice:example.com": {
"ed25519:JLAFKJWSCS": "dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA"
}
}
}
*/
type DeviceKeys struct { type DeviceKeys struct {
UserId string `json:"user_id"` UserID string `json:"user_id"`
DeviceId string `json:"device_id"` DeviceID string `json:"device_id"`
Algorithm []string `json:"algorithms"` Algorithm []string `json:"algorithms"`
Keys map[string]string `json:"keys"` Keys map[string]string `json:"keys"`
Signature map[string]map[string]string `json:"signatures"` Signature map[string]map[string]string `json:"signatures"`
} }
/* // KeyObject structure
"signed_curve25519:AAAAHg": {
"key": "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs",
"signatures": {
"@alice:example.com": {
"ed25519:JLAFKJWSCS": "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw"
}
}
}
*/
type KeyObject struct { type KeyObject struct {
Key string `json:"key"` Key string `json:"key"`
Signature map[string]map[string]string `json:"signatures"` Signature map[string]map[string]string `json:"signatures"`
} }
/* // OneTimeKey structure
"one_time_keys": {
"curve25519:AAAAAQ": "/qyvZvwjiTxGdGU0RCguDCLeR+nmsb3FfNG3/Ve4vU8",
"signed_curve25519:AAAAHg": {
"key": "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs",
"signatures": {
"@alice:example.com": {
"ed25519:JLAFKJWSCS": "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw"
}
}
},
"signed_curve25519:AAAAHQ": {
"key": "j3fR3HemM16M7CWhoI4Sk5ZsdmdfQHsKL1xuSft6MSw",
"signatures": {
"@alice:example.com": {
"ed25519:JLAFKJWSCS": "IQeCEPb9HFk217cU9kw9EOiusC6kMIkoIRnbnfOh5Oc63S1ghgyjShBGpu34blQomoalCyXWyhaaT3MrLZYQAA"
}
}
}
}
*/
type OneTimeKey struct { type OneTimeKey struct {
//KeyString map[string]string //KeyString map[string]string
//KeyObject map[string]KeyObject //KeyObject map[string]KeyObject
KeySth map[string]interface{} KeySth map[string]interface{}
} }
// OneTimeKeySpecific structure
type OneTimeKeySpecific struct { type OneTimeKeySpecific struct {
KeyString map[string]string KeyString map[string]string
KeyObject map[string]KeyObject KeyObject map[string]KeyObject