mirror of
https://github.com/hoernschen/dendrite.git
synced 2024-12-29 08:18:27 +00:00
Sanity checking of uploads
This commit is contained in:
parent
701ffdeb36
commit
dd33f2b76d
4 changed files with 135 additions and 52 deletions
|
@ -71,7 +71,9 @@ func UploadCrossSigningDeviceKeys(
|
||||||
}
|
}
|
||||||
AddCompletedSessionStage(sessionID, authtypes.LoginTypePassword)
|
AddCompletedSessionStage(sessionID, authtypes.LoginTypePassword)
|
||||||
|
|
||||||
|
uploadReq.UserID = device.UserID
|
||||||
keyserverAPI.PerformUploadDeviceKeys(req.Context(), &uploadReq.PerformUploadDeviceKeysRequest, uploadRes)
|
keyserverAPI.PerformUploadDeviceKeys(req.Context(), &uploadReq.PerformUploadDeviceKeysRequest, uploadRes)
|
||||||
|
|
||||||
if err := uploadRes.Error; err != nil {
|
if err := uploadRes.Error; err != nil {
|
||||||
switch {
|
switch {
|
||||||
case err.IsInvalidSignature:
|
case err.IsInvalidSignature:
|
||||||
|
@ -103,7 +105,9 @@ func UploadCrossSigningDeviceSignatures(req *http.Request, keyserverAPI api.KeyI
|
||||||
return *err
|
return *err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uploadReq.UserID = device.UserID
|
||||||
keyserverAPI.PerformUploadDeviceSignatures(req.Context(), uploadReq, uploadRes)
|
keyserverAPI.PerformUploadDeviceSignatures(req.Context(), uploadReq, uploadRes)
|
||||||
|
|
||||||
if err := uploadRes.Error; err != nil {
|
if err := uploadRes.Error; err != nil {
|
||||||
switch {
|
switch {
|
||||||
case err.IsInvalidSignature:
|
case err.IsInvalidSignature:
|
||||||
|
|
|
@ -159,6 +159,8 @@ type PerformClaimKeysResponse struct {
|
||||||
|
|
||||||
type PerformUploadDeviceKeysRequest struct {
|
type PerformUploadDeviceKeysRequest struct {
|
||||||
gomatrixserverlib.CrossSigningKeys
|
gomatrixserverlib.CrossSigningKeys
|
||||||
|
// The user that uploaded the key, should be populated by the clientapi.
|
||||||
|
UserID string `json:"user_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PerformUploadDeviceKeysResponse struct {
|
type PerformUploadDeviceKeysResponse struct {
|
||||||
|
@ -167,6 +169,8 @@ type PerformUploadDeviceKeysResponse struct {
|
||||||
|
|
||||||
type PerformUploadDeviceSignaturesRequest struct {
|
type PerformUploadDeviceSignaturesRequest struct {
|
||||||
gomatrixserverlib.CrossSigningSignatures
|
gomatrixserverlib.CrossSigningSignatures
|
||||||
|
// The user that uploaded the sig, should be populated by the clientapi.
|
||||||
|
UserID string `json:"user_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PerformUploadDeviceSignaturesResponse struct {
|
type PerformUploadDeviceSignaturesResponse struct {
|
||||||
|
|
127
keyserver/internal/cross_signing.go
Normal file
127
keyserver/internal/cross_signing.go
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/keyserver/api"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func sanityCheckKey(key gomatrixserverlib.CrossSigningKey, userID string, purpose gomatrixserverlib.CrossSigningKeyPurpose) error {
|
||||||
|
// Is there exactly one key?
|
||||||
|
if len(key.Keys) != 1 {
|
||||||
|
return fmt.Errorf("should contain exactly one key")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does the key ID match the key value? Iterates exactly once
|
||||||
|
for keyID, keyData := range key.Keys {
|
||||||
|
b64 := keyData.Encode()
|
||||||
|
tokens := strings.Split(string(keyID), ":")
|
||||||
|
if len(tokens) != 2 {
|
||||||
|
return fmt.Errorf("key ID is incorrectly formatted")
|
||||||
|
}
|
||||||
|
if tokens[1] != b64 {
|
||||||
|
return fmt.Errorf("key ID isn't correct")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does the key claim to be from the right user?
|
||||||
|
if userID != key.UserID {
|
||||||
|
return fmt.Errorf("key has a user ID mismatch")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does the key contain the correct purpose?
|
||||||
|
useful := false
|
||||||
|
for _, usage := range key.Usage {
|
||||||
|
if usage == purpose {
|
||||||
|
useful = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !useful {
|
||||||
|
return fmt.Errorf("key does not contain correct usage purpose")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.PerformUploadDeviceKeysRequest, res *api.PerformUploadDeviceKeysResponse) {
|
||||||
|
if len(req.MasterKey.Keys) > 0 {
|
||||||
|
if err := sanityCheckKey(req.MasterKey, req.UserID, gomatrixserverlib.CrossSigningKeyPurposeMaster); err != nil {
|
||||||
|
res.Error = &api.KeyError{
|
||||||
|
Err: "Master key sanity check failed: " + err.Error(),
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.SelfSigningKey.Keys) > 0 {
|
||||||
|
if err := sanityCheckKey(req.SelfSigningKey, req.UserID, gomatrixserverlib.CrossSigningKeyPurposeSelfSigning); err != nil {
|
||||||
|
res.Error = &api.KeyError{
|
||||||
|
Err: "Self-signing key sanity check failed: " + err.Error(),
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.UserSigningKey.Keys) > 0 {
|
||||||
|
if err := sanityCheckKey(req.UserSigningKey, req.UserID, gomatrixserverlib.CrossSigningKeyPurposeUserSigning); err != nil {
|
||||||
|
res.Error = &api.KeyError{
|
||||||
|
Err: "User-signing key sanity check failed: " + err.Error(),
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res.Error = &api.KeyError{
|
||||||
|
Err: "Not supported yet",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *KeyInternalAPI) PerformUploadDeviceSignatures(ctx context.Context, req *api.PerformUploadDeviceSignaturesRequest, res *api.PerformUploadDeviceSignaturesResponse) {
|
||||||
|
res.Error = &api.KeyError{
|
||||||
|
Err: "Not supported yet",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *KeyInternalAPI) crossSigningKeys(
|
||||||
|
ctx context.Context, req *api.QueryKeysRequest, res *api.QueryKeysResponse,
|
||||||
|
) error {
|
||||||
|
for userID := range req.UserToDevices {
|
||||||
|
keys, err := a.DB.CrossSigningKeysForUser(ctx, userID)
|
||||||
|
if err != nil {
|
||||||
|
logrus.WithError(err).Errorf("Failed to get cross-signing keys for user %q", userID)
|
||||||
|
return fmt.Errorf("a.DB.CrossSigningKeysForUser (%q): %w", userID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for keyType, keyData := range keys {
|
||||||
|
b64 := keyData.Encode()
|
||||||
|
key := gomatrixserverlib.CrossSigningKey{
|
||||||
|
UserID: userID,
|
||||||
|
Usage: []gomatrixserverlib.CrossSigningKeyPurpose{
|
||||||
|
keyType,
|
||||||
|
},
|
||||||
|
Keys: map[gomatrixserverlib.KeyID]gomatrixserverlib.Base64Bytes{
|
||||||
|
gomatrixserverlib.KeyID("ed25519:" + b64): keyData,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: populate signatures
|
||||||
|
|
||||||
|
switch keyType {
|
||||||
|
case gomatrixserverlib.CrossSigningKeyPurposeMaster:
|
||||||
|
res.MasterKeys[userID] = key
|
||||||
|
|
||||||
|
case gomatrixserverlib.CrossSigningKeyPurposeSelfSigning:
|
||||||
|
res.SelfSigningKeys[userID] = key
|
||||||
|
|
||||||
|
case gomatrixserverlib.CrossSigningKeyPurposeUserSigning:
|
||||||
|
res.UserSigningKeys[userID] = key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -427,46 +427,6 @@ func (a *KeyInternalAPI) queryRemoteKeysOnServer(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *KeyInternalAPI) crossSigningKeys(
|
|
||||||
ctx context.Context, req *api.QueryKeysRequest, res *api.QueryKeysResponse,
|
|
||||||
) error {
|
|
||||||
for userID := range req.UserToDevices {
|
|
||||||
keys, err := a.DB.CrossSigningKeysForUser(ctx, userID)
|
|
||||||
if err != nil {
|
|
||||||
logrus.WithError(err).Errorf("Failed to get cross-signing keys for user %q", userID)
|
|
||||||
return fmt.Errorf("a.DB.CrossSigningKeysForUser (%q): %w", userID, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for keyType, keyData := range keys {
|
|
||||||
b64 := keyData.Encode()
|
|
||||||
key := gomatrixserverlib.CrossSigningKey{
|
|
||||||
UserID: userID,
|
|
||||||
Usage: []gomatrixserverlib.CrossSigningKeyPurpose{
|
|
||||||
keyType,
|
|
||||||
},
|
|
||||||
Keys: map[gomatrixserverlib.KeyID]gomatrixserverlib.Base64Bytes{
|
|
||||||
gomatrixserverlib.KeyID("ed25519:" + b64): keyData,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: populate signatures
|
|
||||||
|
|
||||||
switch keyType {
|
|
||||||
case gomatrixserverlib.CrossSigningKeyPurposeMaster:
|
|
||||||
res.MasterKeys[userID] = key
|
|
||||||
|
|
||||||
case gomatrixserverlib.CrossSigningKeyPurposeSelfSigning:
|
|
||||||
res.SelfSigningKeys[userID] = key
|
|
||||||
|
|
||||||
case gomatrixserverlib.CrossSigningKeyPurposeUserSigning:
|
|
||||||
res.UserSigningKeys[userID] = key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *KeyInternalAPI) populateResponseWithDeviceKeysFromDatabase(
|
func (a *KeyInternalAPI) populateResponseWithDeviceKeysFromDatabase(
|
||||||
ctx context.Context, res *api.QueryKeysResponse, userID string, deviceIDs []string,
|
ctx context.Context, res *api.QueryKeysResponse, userID string, deviceIDs []string,
|
||||||
) error {
|
) error {
|
||||||
|
@ -618,18 +578,6 @@ func (a *KeyInternalAPI) uploadOneTimeKeys(ctx context.Context, req *api.Perform
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.PerformUploadDeviceKeysRequest, res *api.PerformUploadDeviceKeysResponse) {
|
|
||||||
res.Error = &api.KeyError{
|
|
||||||
Err: "Not supported yet",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *KeyInternalAPI) PerformUploadDeviceSignatures(ctx context.Context, req *api.PerformUploadDeviceSignaturesRequest, res *api.PerformUploadDeviceSignaturesResponse) {
|
|
||||||
res.Error = &api.KeyError{
|
|
||||||
Err: "Not supported yet",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func emitDeviceKeyChanges(producer KeyChangeProducer, existing, new []api.DeviceMessage) error {
|
func emitDeviceKeyChanges(producer KeyChangeProducer, existing, new []api.DeviceMessage) error {
|
||||||
// find keys in new that are not in existing
|
// find keys in new that are not in existing
|
||||||
var keysAdded []api.DeviceMessage
|
var keysAdded []api.DeviceMessage
|
||||||
|
|
Loading…
Reference in a new issue