diff options
author | Jakob Borg <jakob@kastelo.net> | 2023-03-18 10:22:18 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-18 10:22:18 +0100 |
commit | f378e631472f22df653e0880e1ded251b7e856bf (patch) | |
tree | 3cf7c0a3760d54b9b2708a8f29f5d7a0a1b69230 | |
parent | fb8989846269eaa736fb64bf555a8c9609f4b101 (diff) |
lib/protocol: Handle encrypted requests without encrypted hash (fixes #8277) (#8827)
The layout of the request differs based on whether it comes from an
untrusted device or a trusted device with encrypted enabled. Handle
both.
Closes #8819.
-rw-r--r-- | lib/protocol/encryption.go | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/lib/protocol/encryption.go b/lib/protocol/encryption.go index ea2a4ad01c..322dfedcfe 100644 --- a/lib/protocol/encryption.go +++ b/lib/protocol/encryption.go @@ -96,18 +96,26 @@ func (e encryptedModel) Request(deviceID DeviceID, folder, name string, blockNo, return nil, errors.New("short request") } - // Decrypt the block hash. - + // Attempt to decrypt the block hash; it may be nil depending on what + // type of device the request comes from. Trusted devices with + // encryption enabled know the hash but don't bother to encrypt & send + // it to us. Untrusted devices have the hash from the encrypted index + // data and do send it. The model knows to only verify the hash if it + // actually gets one. + + var realHash []byte fileKey := e.keyGen.FileKey(realName, folderKey) - var additional [8]byte - binary.BigEndian.PutUint64(additional[:], uint64(realOffset)) - realHash, err := decryptDeterministic(hash, fileKey, additional[:]) - if err != nil { - // "Legacy", no offset additional data? - realHash, err = decryptDeterministic(hash, fileKey, nil) - } - if err != nil { - return nil, fmt.Errorf("decrypting block hash: %w", err) + if len(hash) > 0 { + var additional [8]byte + binary.BigEndian.PutUint64(additional[:], uint64(realOffset)) + realHash, err = decryptDeterministic(hash, fileKey, additional[:]) + if err != nil { + // "Legacy", no offset additional data? + realHash, err = decryptDeterministic(hash, fileKey, nil) + } + if err != nil { + return nil, fmt.Errorf("decrypting block hash: %w", err) + } } // Perform that request and grab the data. |