mirror of
https://mau.dev/mautrix/go.git
synced 2026-03-14 14:25:53 +01:00
Add cross-signing TOFU support
This commit is contained in:
parent
d32425a24e
commit
9162944672
12 changed files with 128 additions and 83 deletions
|
|
@ -363,14 +363,32 @@ func (mx *MatrixHandler) sendCryptoStatusError(evt *event.Event, editEvent id.Ev
|
|||
return ""
|
||||
}
|
||||
|
||||
var errDeviceNotVerified = errors.New("your device is not verified")
|
||||
var errDeviceNotTrusted = errors.New("your device is not trusted")
|
||||
var errMessageNotEncrypted = errors.New("unencrypted message")
|
||||
|
||||
func deviceUnverifiedErrorWithExplanation(trust id.TrustState) error {
|
||||
var explanation string
|
||||
switch trust {
|
||||
case id.TrustStateBlacklisted:
|
||||
explanation = "device is blacklisted"
|
||||
case id.TrustStateUnknownDevice:
|
||||
explanation = "device info not found"
|
||||
case id.TrustStateForwarded:
|
||||
explanation = "keys were forwarded from an unknown device"
|
||||
case id.TrustStateCrossSignedUntrusted:
|
||||
explanation = "cross-signing keys changed after setting up the bridge"
|
||||
default:
|
||||
return errDeviceNotTrusted
|
||||
}
|
||||
return fmt.Errorf("%w (%s)", errDeviceNotTrusted, explanation)
|
||||
}
|
||||
|
||||
func (mx *MatrixHandler) postDecrypt(decrypted *event.Event, retryCount int, errorEventID id.EventID) {
|
||||
minLevel := mx.bridge.Config.Bridge.GetEncryptionConfig().VerificationLevels.Send
|
||||
if decrypted.Mautrix.TrustState < minLevel {
|
||||
mx.log.Warnfln("Dropping %s due to insufficient verification level (event: %s, required: %s)", decrypted.ID, decrypted.Mautrix.TrustState.Description(), minLevel.Description())
|
||||
go mx.sendCryptoStatusError(decrypted, errorEventID, errDeviceNotVerified, retryCount, true)
|
||||
mx.log.Warnfln("Dropping %s due to insufficient verification level (event: %s, required: %s)", decrypted.ID, decrypted.Mautrix.TrustState, minLevel)
|
||||
err := deviceUnverifiedErrorWithExplanation(decrypted.Mautrix.TrustState)
|
||||
go mx.sendCryptoStatusError(decrypted, errorEventID, err, retryCount, true)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2020 Tulir Asokan
|
||||
// Copyright (c) 2022 Tulir Asokan
|
||||
//
|
||||
// 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
|
||||
|
|
@ -51,9 +51,9 @@ func (mach *OlmMachine) GetCrossSigningPublicKeys(userID id.UserID) (*CrossSigni
|
|||
selfSigning, _ := dbKeys[id.XSUsageSelfSigning]
|
||||
userSigning, _ := dbKeys[id.XSUsageUserSigning]
|
||||
return &CrossSigningPublicKeysCache{
|
||||
MasterKey: masterKey,
|
||||
SelfSigningKey: selfSigning,
|
||||
UserSigningKey: userSigning,
|
||||
MasterKey: masterKey.Key,
|
||||
SelfSigningKey: selfSigning.Key,
|
||||
UserSigningKey: userSigning.Key,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright (c) 2020 Nikos Filippakis
|
||||
// Copyright (c) 2022 Tulir Asokan
|
||||
//
|
||||
// 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
|
||||
|
|
@ -41,20 +42,20 @@ func (mach *OlmMachine) fetchMasterKey(device *DeviceIdentity, content *event.Ve
|
|||
if !ok {
|
||||
return "", ErrCrossSigningMasterKeyNotFound
|
||||
}
|
||||
masterKeyID := id.NewKeyID(id.KeyAlgorithmEd25519, masterKey.String())
|
||||
masterKeyID := id.NewKeyID(id.KeyAlgorithmEd25519, masterKey.Key.String())
|
||||
masterKeyMAC, ok := content.Mac[masterKeyID]
|
||||
if !ok {
|
||||
return masterKey, ErrMasterKeyMACNotFound
|
||||
return masterKey.Key, ErrMasterKeyMACNotFound
|
||||
}
|
||||
expectedMasterKeyMAC, _, err := mach.getPKAndKeysMAC(verState.sas, device.UserID, device.DeviceID,
|
||||
mach.Client.UserID, mach.Client.DeviceID, transactionID, masterKey, masterKeyID, content.Mac)
|
||||
mach.Client.UserID, mach.Client.DeviceID, transactionID, masterKey.Key, masterKeyID, content.Mac)
|
||||
if err != nil {
|
||||
return masterKey, fmt.Errorf("failed to calculate expected MAC for master key: %w", err)
|
||||
return masterKey.Key, fmt.Errorf("failed to calculate expected MAC for master key: %w", err)
|
||||
}
|
||||
if masterKeyMAC != expectedMasterKeyMAC {
|
||||
err = fmt.Errorf("%w: expected %s, got %s", ErrMismatchingMasterKeyMAC, expectedMasterKeyMAC, masterKeyMAC)
|
||||
}
|
||||
return masterKey, err
|
||||
return masterKey.Key, err
|
||||
}
|
||||
|
||||
// SignUser creates a cross-signing signature for a user, stores it and uploads it to the server.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright (c) 2020 Nikos Filippakis
|
||||
// Copyright (c) 2022 Tulir Asokan
|
||||
//
|
||||
// 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
|
||||
|
|
@ -23,9 +24,9 @@ func (mach *OlmMachine) storeCrossSigningKeys(crossSigningKeys map[id.UserID]mau
|
|||
// got a new key with the same usage as an existing key
|
||||
for _, newKeyUsage := range userKeys.Usage {
|
||||
if newKeyUsage == curKeyUsage {
|
||||
if _, ok := userKeys.Keys[id.NewKeyID(id.KeyAlgorithmEd25519, curKey.String())]; !ok {
|
||||
if _, ok := userKeys.Keys[id.NewKeyID(id.KeyAlgorithmEd25519, curKey.Key.String())]; !ok {
|
||||
// old key is not in the new key map, so we drop signatures made by it
|
||||
if count, err := mach.CryptoStore.DropSignaturesByKey(userID, curKey); err != nil {
|
||||
if count, err := mach.CryptoStore.DropSignaturesByKey(userID, curKey.Key); err != nil {
|
||||
mach.Log.Error("Error deleting old signatures made by %s (%s): %v", curKey, curKeyUsage, err)
|
||||
} else {
|
||||
mach.Log.Debug("Dropped %d signatures made by key %s (%s) as it has been replaced", count, curKey, curKeyUsage)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright (c) 2020 Nikos Filippakis
|
||||
// Copyright (c) 2022 Tulir Asokan
|
||||
//
|
||||
// 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
|
||||
|
|
@ -10,49 +11,47 @@ import (
|
|||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
func (mach *OlmMachine) IsKeyCrossSigned(userID id.UserID, deviceSigningKey id.SigningKey) bool {
|
||||
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, deviceSigningKey, 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
|
||||
}
|
||||
|
||||
// ResolveTrust resolves the trust state of the device from cross-signing.
|
||||
func (mach *OlmMachine) ResolveTrust(device *DeviceIdentity) id.TrustState {
|
||||
if device.Trust == id.TrustStateVerified || device.Trust == id.TrustStateBlacklisted {
|
||||
return device.Trust
|
||||
}
|
||||
if mach.IsKeyCrossSigned(device.UserID, device.SigningKey) {
|
||||
theirKeys, err := mach.CryptoStore.GetCrossSigningKeys(device.UserID)
|
||||
if err != nil {
|
||||
mach.Log.Error("Error retrieving cross-singing key of user %v from database: %v", device.UserID, err)
|
||||
return id.TrustStateUnset
|
||||
}
|
||||
theirMSK, ok := theirKeys[id.XSUsageMaster]
|
||||
if !ok {
|
||||
mach.Log.Error("Master key of user %v not found", device.UserID)
|
||||
return id.TrustStateUnset
|
||||
}
|
||||
theirSSK, ok := theirKeys[id.XSUsageSelfSigning]
|
||||
if !ok {
|
||||
mach.Log.Error("Self-signing key of user %v not found", device.UserID)
|
||||
return id.TrustStateUnset
|
||||
}
|
||||
sskSigExists, err := mach.CryptoStore.IsKeySignedBy(device.UserID, theirSSK.Key, device.UserID, theirMSK.Key)
|
||||
if err != nil {
|
||||
mach.Log.Error("Error retrieving cross-singing signatures for master key of user %v from database: %v", device.UserID, err)
|
||||
return id.TrustStateUnset
|
||||
}
|
||||
if !sskSigExists {
|
||||
mach.Log.Warn("Self-signing key of user %v is not signed by their master key", device.UserID)
|
||||
return id.TrustStateUnset
|
||||
}
|
||||
deviceSigExists, err := mach.CryptoStore.IsKeySignedBy(device.UserID, device.SigningKey, device.UserID, theirSSK.Key)
|
||||
if err != nil {
|
||||
mach.Log.Error("Error retrieving cross-singing signatures for master key of user %v from database: %v", device.UserID, err)
|
||||
return id.TrustStateUnset
|
||||
}
|
||||
if deviceSigExists {
|
||||
if mach.IsUserTrusted(device.UserID) {
|
||||
return id.TrustStateCrossSignedTrusted
|
||||
return id.TrustStateCrossSignedVerified
|
||||
} else if theirMSK.Key == theirMSK.First {
|
||||
return id.TrustStateCrossSignedTOFU
|
||||
}
|
||||
return id.TrustStateCrossSigned
|
||||
return id.TrustStateCrossSignedUntrusted
|
||||
}
|
||||
return id.TrustStateUnset
|
||||
}
|
||||
|
|
@ -60,7 +59,7 @@ func (mach *OlmMachine) ResolveTrust(device *DeviceIdentity) id.TrustState {
|
|||
// IsDeviceTrusted returns whether a device has been determined to be trusted either through verification or cross-signing.
|
||||
func (mach *OlmMachine) IsDeviceTrusted(device *DeviceIdentity) bool {
|
||||
switch mach.ResolveTrust(device) {
|
||||
case id.TrustStateVerified, id.TrustStateCrossSigned, id.TrustStateCrossSignedTrusted:
|
||||
case id.TrustStateVerified, id.TrustStateCrossSignedTOFU, id.TrustStateCrossSignedVerified:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
|
@ -97,7 +96,7 @@ func (mach *OlmMachine) IsUserTrusted(userID id.UserID) bool {
|
|||
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)
|
||||
sigExists, err := mach.CryptoStore.IsKeySignedBy(userID, theirMskKey.Key, 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
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ func (mach *OlmMachine) findOlmSessionsForUser(session *OutboundGroupSession, us
|
|||
} else if trustState := mach.ResolveTrust(device); trustState < mach.SendKeysMinTrust {
|
||||
mach.Log.Debug(
|
||||
"Not encrypting group session %s for %s of %s: device is not verified (minimum: %s, device: %s)",
|
||||
session.ID(), deviceID, userID, mach.SendKeysMinTrust.Description(), trustState.Description(),
|
||||
session.ID(), deviceID, userID, mach.SendKeysMinTrust, trustState,
|
||||
)
|
||||
withheld[deviceID] = &event.Content{Parsed: &event.RoomKeyWithheldEventContent{
|
||||
RoomID: session.RoomID,
|
||||
|
|
|
|||
|
|
@ -194,10 +194,10 @@ func (mach *OlmMachine) defaultAllowKeyShare(device *DeviceIdentity, _ event.Req
|
|||
mach.Log.Debug("Ignoring key request from blacklisted device %s", device.DeviceID)
|
||||
return &KeyShareRejectBlacklisted
|
||||
} else if trustState := mach.ResolveTrust(device); trustState >= mach.ShareKeysMinTrust {
|
||||
mach.Log.Debug("Accepting key request from device %s (trust state: %s)", device.DeviceID, trustState.Description())
|
||||
mach.Log.Debug("Accepting key request from device %s (trust state: %s)", device.DeviceID, trustState)
|
||||
return nil
|
||||
} else {
|
||||
mach.Log.Debug("Ignoring key request from unverified device %s (trust state: %s)", device.DeviceID, trustState.Description())
|
||||
mach.Log.Debug("Ignoring key request from unverified device %s (trust state: %s)", device.DeviceID, trustState)
|
||||
return &KeyShareRejectUnverified
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ func NewOlmMachine(client *mautrix.Client, log Logger, cryptoStore Store, stateS
|
|||
StateStore: stateStore,
|
||||
|
||||
SendKeysMinTrust: id.TrustStateUnset,
|
||||
ShareKeysMinTrust: id.TrustStateCrossSigned,
|
||||
ShareKeysMinTrust: id.TrustStateCrossSignedTOFU,
|
||||
|
||||
DefaultSASTimeout: 10 * time.Minute,
|
||||
AcceptVerificationFrom: func(string, *DeviceIdentity, id.RoomID) (VerificationRequestResponse, VerificationHooks) {
|
||||
|
|
|
|||
|
|
@ -630,27 +630,27 @@ func (store *SQLCryptoStore) FilterTrackedUsers(users []id.UserID) []id.UserID {
|
|||
// PutCrossSigningKey stores a cross-signing key of some user along with its usage.
|
||||
func (store *SQLCryptoStore) PutCrossSigningKey(userID id.UserID, usage id.CrossSigningUsage, key id.Ed25519) error {
|
||||
_, err := store.DB.Exec(`
|
||||
INSERT INTO crypto_cross_signing_keys (user_id, usage, key) VALUES ($1, $2, $3)
|
||||
INSERT INTO crypto_cross_signing_keys (user_id, usage, key, first_seen_key) VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (user_id, usage) DO UPDATE SET key=excluded.key
|
||||
`, userID, usage, key)
|
||||
`, userID, usage, key, key)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetCrossSigningKeys retrieves a user's stored cross-signing keys.
|
||||
func (store *SQLCryptoStore) GetCrossSigningKeys(userID id.UserID) (map[id.CrossSigningUsage]id.Ed25519, error) {
|
||||
rows, err := store.DB.Query("SELECT usage, key FROM crypto_cross_signing_keys WHERE user_id=$1", userID)
|
||||
func (store *SQLCryptoStore) GetCrossSigningKeys(userID id.UserID) (map[id.CrossSigningUsage]CrossSigningKey, error) {
|
||||
rows, err := store.DB.Query("SELECT usage, key, first_seen_key FROM crypto_cross_signing_keys WHERE user_id=$1", userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data := make(map[id.CrossSigningUsage]id.Ed25519)
|
||||
data := make(map[id.CrossSigningUsage]CrossSigningKey)
|
||||
for rows.Next() {
|
||||
var usage id.CrossSigningUsage
|
||||
var key id.Ed25519
|
||||
err := rows.Scan(&usage, &key)
|
||||
var key, first id.Ed25519
|
||||
err := rows.Scan(&usage, &key, &first)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data[usage] = key
|
||||
data[usage] = CrossSigningKey{key, first}
|
||||
}
|
||||
|
||||
return data, nil
|
||||
|
|
|
|||
5
crypto/sql_store_upgrade/08-cs-key-expired-field.sql
Normal file
5
crypto/sql_store_upgrade/08-cs-key-expired-field.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
-- v8: Add expired field to cross signing keys
|
||||
ALTER TABLE crypto_cross_signing_keys ADD COLUMN first_seen_key CHAR(43);
|
||||
UPDATE crypto_cross_signing_keys SET first_seen_key=key;
|
||||
-- only: postgres
|
||||
ALTER TABLE crypto_cross_signing_keys ALTER COLUMN first_seen_key SET NOT NULL;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2020 Tulir Asokan
|
||||
// Copyright (c) 2022 Tulir Asokan
|
||||
//
|
||||
// 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
|
||||
|
|
@ -34,6 +34,11 @@ func (device *DeviceIdentity) Fingerprint() string {
|
|||
return Fingerprint(device.SigningKey)
|
||||
}
|
||||
|
||||
type CrossSigningKey struct {
|
||||
Key id.Ed25519
|
||||
First id.Ed25519
|
||||
}
|
||||
|
||||
var ErrGroupSessionWithheld = errors.New("group session has been withheld")
|
||||
|
||||
// Store is used by OlmMachine to store Olm and Megolm sessions, user device lists and message indices.
|
||||
|
|
@ -122,7 +127,7 @@ type Store interface {
|
|||
// PutCrossSigningKey stores a cross-signing key of some user along with its usage.
|
||||
PutCrossSigningKey(id.UserID, id.CrossSigningUsage, id.Ed25519) error
|
||||
// GetCrossSigningKeys retrieves a user's stored cross-signing keys.
|
||||
GetCrossSigningKeys(id.UserID) (map[id.CrossSigningUsage]id.Ed25519, error)
|
||||
GetCrossSigningKeys(id.UserID) (map[id.CrossSigningUsage]CrossSigningKey, error)
|
||||
// PutSignature stores a signature of a cross-signing or device key along with the signer's user ID and key.
|
||||
PutSignature(id.UserID, id.Ed25519, id.UserID, id.Ed25519, string) error
|
||||
// GetSignaturesForKeyBy returns the signatures for a cross-signing or device key by the given signer.
|
||||
|
|
@ -158,7 +163,7 @@ type GobStore struct {
|
|||
OutGroupSessions map[id.RoomID]*OutboundGroupSession
|
||||
MessageIndices map[messageIndexKey]messageIndexValue
|
||||
Devices map[id.UserID]map[id.DeviceID]*DeviceIdentity
|
||||
CrossSigningKeys map[id.UserID]map[id.CrossSigningUsage]id.Ed25519
|
||||
CrossSigningKeys map[id.UserID]map[id.CrossSigningUsage]CrossSigningKey
|
||||
KeySignatures map[id.UserID]map[id.Ed25519]map[id.UserID]map[id.Ed25519]string
|
||||
}
|
||||
|
||||
|
|
@ -176,7 +181,7 @@ func NewGobStore(path string) (*GobStore, error) {
|
|||
OutGroupSessions: make(map[id.RoomID]*OutboundGroupSession),
|
||||
MessageIndices: make(map[messageIndexKey]messageIndexValue),
|
||||
Devices: make(map[id.UserID]map[id.DeviceID]*DeviceIdentity),
|
||||
CrossSigningKeys: make(map[id.UserID]map[id.CrossSigningUsage]id.Ed25519),
|
||||
CrossSigningKeys: make(map[id.UserID]map[id.CrossSigningUsage]CrossSigningKey),
|
||||
KeySignatures: make(map[id.UserID]map[id.Ed25519]map[id.UserID]map[id.Ed25519]string),
|
||||
}
|
||||
return gs, gs.load()
|
||||
|
|
@ -502,21 +507,30 @@ func (gs *GobStore) PutCrossSigningKey(userID id.UserID, usage id.CrossSigningUs
|
|||
gs.lock.RLock()
|
||||
userKeys, ok := gs.CrossSigningKeys[userID]
|
||||
if !ok {
|
||||
userKeys = make(map[id.CrossSigningUsage]id.Ed25519)
|
||||
userKeys = make(map[id.CrossSigningUsage]CrossSigningKey)
|
||||
gs.CrossSigningKeys[userID] = userKeys
|
||||
}
|
||||
userKeys[usage] = key
|
||||
existing, ok := userKeys[usage]
|
||||
if ok {
|
||||
existing.Key = key
|
||||
userKeys[usage] = existing
|
||||
} else {
|
||||
userKeys[usage] = CrossSigningKey{
|
||||
Key: key,
|
||||
First: key,
|
||||
}
|
||||
}
|
||||
err := gs.save()
|
||||
gs.lock.RUnlock()
|
||||
return err
|
||||
}
|
||||
|
||||
func (gs *GobStore) GetCrossSigningKeys(userID id.UserID) (map[id.CrossSigningUsage]id.Ed25519, error) {
|
||||
func (gs *GobStore) GetCrossSigningKeys(userID id.UserID) (map[id.CrossSigningUsage]CrossSigningKey, error) {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
keys, ok := gs.CrossSigningKeys[userID]
|
||||
if !ok {
|
||||
return map[id.CrossSigningUsage]id.Ed25519{}, nil
|
||||
return map[id.CrossSigningUsage]CrossSigningKey{}, nil
|
||||
}
|
||||
return keys, nil
|
||||
}
|
||||
|
|
|
|||
47
id/trust.go
47
id/trust.go
|
|
@ -15,14 +15,15 @@ import (
|
|||
type TrustState int
|
||||
|
||||
const (
|
||||
TrustStateBlacklisted TrustState = -100
|
||||
TrustStateUnset TrustState = 0
|
||||
TrustStateUnknownDevice TrustState = 10
|
||||
TrustStateForwarded TrustState = 20
|
||||
TrustStateCrossSigned TrustState = 100
|
||||
TrustStateCrossSignedTrusted TrustState = 200
|
||||
TrustStateVerified TrustState = 300
|
||||
TrustStateInvalid TrustState = (1 << 31) - 1
|
||||
TrustStateBlacklisted TrustState = -100
|
||||
TrustStateUnset TrustState = 0
|
||||
TrustStateUnknownDevice TrustState = 10
|
||||
TrustStateForwarded TrustState = 20
|
||||
TrustStateCrossSignedUntrusted TrustState = 50
|
||||
TrustStateCrossSignedTOFU TrustState = 100
|
||||
TrustStateCrossSignedVerified TrustState = 200
|
||||
TrustStateVerified TrustState = 300
|
||||
TrustStateInvalid TrustState = (1 << 31) - 1
|
||||
)
|
||||
|
||||
func (ts *TrustState) UnmarshalText(data []byte) error {
|
||||
|
|
@ -45,14 +46,16 @@ func ParseTrustState(val string) TrustState {
|
|||
return TrustStateBlacklisted
|
||||
case "unverified":
|
||||
return TrustStateUnset
|
||||
case "cross-signed-untrusted", "cross-signed, untrusted":
|
||||
return TrustStateCrossSignedUntrusted
|
||||
case "unknown-device", "unknown device":
|
||||
return TrustStateUnknownDevice
|
||||
case "forwarded":
|
||||
return TrustStateForwarded
|
||||
case "cross-signed", "tofu", "verified (via cross-signing, tofu)":
|
||||
return TrustStateCrossSigned
|
||||
case "cross-signed-trusted", "verified (via cross-signing, trusted user)":
|
||||
return TrustStateCrossSignedTrusted
|
||||
case "cross-signed-tofu", "cross-signed", "cross-signed, trusted on first use":
|
||||
return TrustStateCrossSignedTOFU
|
||||
case "cross-signed-verified", "cross-signed-trusted", "cross-signed, verified user user":
|
||||
return TrustStateCrossSignedVerified
|
||||
case "verified":
|
||||
return TrustStateVerified
|
||||
default:
|
||||
|
|
@ -66,14 +69,16 @@ func (ts TrustState) String() string {
|
|||
return "blacklisted"
|
||||
case TrustStateUnset:
|
||||
return "unverified"
|
||||
case TrustStateCrossSignedUntrusted:
|
||||
return "cross-signed-untrusted"
|
||||
case TrustStateUnknownDevice:
|
||||
return "unknown-device"
|
||||
case TrustStateForwarded:
|
||||
return "forwarded"
|
||||
case TrustStateCrossSigned:
|
||||
return "cross-signed"
|
||||
case TrustStateCrossSignedTrusted:
|
||||
return "cross-signed-trusted"
|
||||
case TrustStateCrossSignedTOFU:
|
||||
return "cross-signed-tofu"
|
||||
case TrustStateCrossSignedVerified:
|
||||
return "cross-signed-verified"
|
||||
case TrustStateVerified:
|
||||
return "verified"
|
||||
default:
|
||||
|
|
@ -87,14 +92,16 @@ func (ts TrustState) Description() string {
|
|||
return "blacklisted"
|
||||
case TrustStateUnset:
|
||||
return "unverified"
|
||||
case TrustStateCrossSignedUntrusted:
|
||||
return "cross-signed, untrusted"
|
||||
case TrustStateUnknownDevice:
|
||||
return "unknown device"
|
||||
case TrustStateForwarded:
|
||||
return "forwarded"
|
||||
case TrustStateCrossSigned:
|
||||
return "cross-signed, tofu"
|
||||
case TrustStateCrossSignedTrusted:
|
||||
return "cross-signed, trusted user"
|
||||
case TrustStateCrossSignedTOFU:
|
||||
return "cross-signed, trusted on first use"
|
||||
case TrustStateCrossSignedVerified:
|
||||
return "cross-signed, verified user"
|
||||
case TrustStateVerified:
|
||||
return "verified locally"
|
||||
default:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue