94 lines
3.2 KiB
Go
94 lines
3.2 KiB
Go
|
// Copyright (c) 2020 Nikos Filippakis
|
||
|
//
|
||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||
|
|
||
|
package crypto
|
||
|
|
||
|
import (
|
||
|
"maunium.net/go/mautrix/id"
|
||
|
)
|
||
|
|
||
|
// IsDeviceTrusted returns whether a device has been determined to be trusted either through verification or cross-signing.
|
||
|
func (mach *OlmMachine) IsDeviceTrusted(device *DeviceIdentity) bool {
|
||
|
userID := device.UserID
|
||
|
if device.Trust == TrustStateVerified {
|
||
|
return true
|
||
|
} else if device.Trust == TrustStateBlacklisted {
|
||
|
return false
|
||
|
}
|
||
|
if !mach.IsUserTrusted(userID) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
theirKeys, err := mach.CryptoStore.GetCrossSigningKeys(userID)
|
||
|
if err != nil {
|
||
|
mach.Log.Error("Error retrieving cross-singing key of user %v from database: %v", userID, err)
|
||
|
return false
|
||
|
}
|
||
|
theirMSK, ok := theirKeys[id.XSUsageMaster]
|
||
|
if !ok {
|
||
|
mach.Log.Error("Master key of user %v not found", userID)
|
||
|
return false
|
||
|
}
|
||
|
theirSSK, ok := theirKeys[id.XSUsageSelfSigning]
|
||
|
if !ok {
|
||
|
mach.Log.Error("Self-signing key of user %v not found", userID)
|
||
|
return false
|
||
|
}
|
||
|
sskSigExists, err := mach.CryptoStore.IsKeySignedBy(userID, theirSSK, userID, theirMSK)
|
||
|
if err != nil {
|
||
|
mach.Log.Error("Error retrieving cross-singing signatures for master key of user %v from database: %v", userID, err)
|
||
|
return false
|
||
|
}
|
||
|
if !sskSigExists {
|
||
|
mach.Log.Warn("Self-signing key of user %v is not signed by their master key", userID)
|
||
|
return false
|
||
|
}
|
||
|
deviceSigExists, err := mach.CryptoStore.IsKeySignedBy(userID, device.SigningKey, userID, theirSSK)
|
||
|
if err != nil {
|
||
|
mach.Log.Error("Error retrieving cross-singing signatures for master key of user %v from database: %v", userID, err)
|
||
|
return false
|
||
|
}
|
||
|
return deviceSigExists
|
||
|
}
|
||
|
|
||
|
// IsUserTrusted returns whether a user has been determined to be trusted by our user-signing key having signed their master key.
|
||
|
// In the case the user ID is our own and we have successfully retrieved our cross-signing keys, we trust our own user.
|
||
|
func (mach *OlmMachine) IsUserTrusted(userID id.UserID) bool {
|
||
|
csPubkeys := mach.GetOwnCrossSigningPublicKeys()
|
||
|
if csPubkeys == nil {
|
||
|
return false
|
||
|
}
|
||
|
if userID == mach.Client.UserID {
|
||
|
return true
|
||
|
}
|
||
|
// first we verify our user-signing key
|
||
|
sskSigs, err := mach.CryptoStore.GetSignaturesForKeyBy(mach.Client.UserID, csPubkeys.UserSigningKey, mach.Client.UserID)
|
||
|
if err != nil {
|
||
|
mach.Log.Error("Error retrieving our self-singing key signatures: %v", err)
|
||
|
return false
|
||
|
}
|
||
|
if _, ok := sskSigs[csPubkeys.MasterKey]; !ok {
|
||
|
// our user-signing key was not signed by our master key
|
||
|
return false
|
||
|
}
|
||
|
theirKeys, err := mach.CryptoStore.GetCrossSigningKeys(userID)
|
||
|
if err != nil {
|
||
|
mach.Log.Error("Error retrieving cross-singing key of user %v from database: %v", userID, err)
|
||
|
return false
|
||
|
}
|
||
|
theirMskKey, ok := theirKeys[id.XSUsageMaster]
|
||
|
if !ok {
|
||
|
mach.Log.Error("Master key of user %v not found", userID)
|
||
|
return false
|
||
|
}
|
||
|
sigExists, err := mach.CryptoStore.IsKeySignedBy(userID, theirMskKey, mach.Client.UserID, csPubkeys.UserSigningKey)
|
||
|
if err != nil {
|
||
|
mach.Log.Error("Error retrieving cross-singing signatures for master key of user %v from database: %v", userID, err)
|
||
|
return false
|
||
|
}
|
||
|
return sigExists
|
||
|
}
|