crypto/ssss: skip verifying recovery key if MAC or IV are missing
Some checks are pending
Go / Lint (latest) (push) Waiting to run
Go / Build (old, libolm) (push) Waiting to run
Go / Build (latest, libolm) (push) Waiting to run
Go / Build (old, goolm) (push) Waiting to run
Go / Build (latest, goolm) (push) Waiting to run

This commit is contained in:
Tulir Asokan 2026-01-28 12:51:46 +02:00
commit c4ce008c8e
3 changed files with 19 additions and 5 deletions

View file

@ -8,6 +8,7 @@ package crypto
import (
"context"
"errors"
"fmt"
"maunium.net/go/mautrix"
@ -77,7 +78,11 @@ func (mach *OlmMachine) VerifyWithRecoveryKey(ctx context.Context, recoveryKey s
return fmt.Errorf("failed to get default SSSS key data: %w", err)
}
key, err := keyData.VerifyRecoveryKey(keyID, recoveryKey)
if err != nil {
if errors.Is(err, ssss.ErrUnverifiableKey) {
mach.machOrContextLog(ctx).Warn().
Str("key_id", keyID).
Msg("SSSS key is unverifiable, trying to use without verifying")
} else if err != nil {
return err
}
err = mach.FetchCrossSigningKeysFromSSSS(ctx, key)

View file

@ -8,6 +8,7 @@ package ssss
import (
"encoding/base64"
"errors"
"fmt"
"strings"
@ -33,7 +34,9 @@ func (kd *KeyMetadata) VerifyPassphrase(keyID, passphrase string) (*Key, error)
ssssKey, err := kd.Passphrase.GetKey(passphrase)
if err != nil {
return nil, err
} else if err = kd.verifyKey(ssssKey); err != nil {
}
err = kd.verifyKey(ssssKey)
if err != nil && !errors.Is(err, ErrUnverifiableKey) {
return nil, err
}
@ -49,7 +52,9 @@ func (kd *KeyMetadata) VerifyRecoveryKey(keyID, recoveryKey string) (*Key, error
ssssKey := utils.DecodeBase58RecoveryKey(recoveryKey)
if ssssKey == nil {
return nil, ErrInvalidRecoveryKey
} else if err := kd.verifyKey(ssssKey); err != nil {
}
err := kd.verifyKey(ssssKey)
if err != nil && !errors.Is(err, ErrUnverifiableKey) {
return nil, err
}
@ -57,10 +62,13 @@ func (kd *KeyMetadata) VerifyRecoveryKey(keyID, recoveryKey string) (*Key, error
ID: keyID,
Key: ssssKey,
Metadata: kd,
}, nil
}, err
}
func (kd *KeyMetadata) verifyKey(key []byte) error {
if kd.MAC == "" || kd.IV == "" {
return ErrUnverifiableKey
}
unpaddedMAC := strings.TrimRight(kd.MAC, "=")
expectedMACLength := base64.RawStdEncoding.EncodedLen(utils.SHAHashLength)
if len(unpaddedMAC) != expectedMACLength {

View file

@ -26,7 +26,8 @@ var (
ErrUnsupportedPassphraseAlgorithm = errors.New("unsupported passphrase KDF algorithm")
ErrIncorrectSSSSKey = errors.New("incorrect SSSS key")
ErrInvalidRecoveryKey = errors.New("invalid recovery key")
ErrCorruptedKeyMetadata = errors.New("corrupted key metadata")
ErrCorruptedKeyMetadata = errors.New("corrupted recovery key metadata")
ErrUnverifiableKey = errors.New("cannot verify recovery key: missing MAC or IV in metadata")
)
// Algorithm is the identifier for an SSSS encryption algorithm.