mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-15 10:53:09 -06:00
find lint revision in encryption api server codes
This commit is contained in:
parent
2e20f7bcab
commit
d97c71992c
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 = iota
|
// TYPESUM sum type
|
||||||
TYPECLAIM
|
TYPESUM = iota
|
||||||
TYPEVAL
|
// BODYDEVICEKEY device key body
|
||||||
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 = make(map[string]interface{})
|
keymap := keyPreMap[deviceID]
|
||||||
|
if keymap == nil {
|
||||||
|
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,12 +383,12 @@ 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)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func upnotify(userID string) {
|
func upnotify(userID string) {
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -14,41 +14,14 @@
|
||||||
|
|
||||||
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"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue