crypt: return unexpected EOF instead of Failed to authenticate decrypted block #873

Streams which truncated early with an EOF message would return a
"Failed to authenticate decrypted block" error.  While technically
correct, this isn't a helpful error message as it masks the underlying
problem.  This changes it to return "unexpected EOF" instead.

The rest of rclone knows it should retry such errors.
This commit is contained in:
Nick Craig-Wood 2016-12-12 15:20:40 +00:00
parent 7392cd1a1a
commit ec0916c59d
2 changed files with 33 additions and 6 deletions

View file

@ -579,6 +579,11 @@ func (fh *decrypter) fillBuffer() (err error) {
block := fh.buf
_, ok := secretbox.Open(block[:0], readBuf[:n], fh.nonce.pointer(), &fh.c.dataKey)
if !ok {
// if block wouldn't decode and got unexpected EOF
// then return that as it is probably a better error
if err != nil {
return err
}
return ErrorEncryptedBadBlock
}
fh.bufIndex = 0

View file

@ -917,14 +917,36 @@ func TestDecrypterRead(t *testing.T) {
c, err := newCipher(NameEncryptionStandard, "", "")
assert.NoError(t, err)
// Test truncating the header
for i := 1; i < blockHeaderSize; i++ {
cd := newCloseDetector(bytes.NewBuffer(file1[:len(file1)-i]))
// Test truncating the file at each possible point
for i := 0; i < len(file16)-1; i++ {
what := fmt.Sprintf("truncating to %d/%d", i, len(file16))
cd := newCloseDetector(bytes.NewBuffer(file16[:i]))
fh, err := c.newDecrypter(cd)
assert.NoError(t, err)
if i < fileHeaderSize {
assert.EqualError(t, err, ErrorEncryptedFileTooShort.Error(), what)
continue
}
if err != nil {
assert.NoError(t, err, what)
continue
}
_, err = ioutil.ReadAll(fh)
assert.Error(t, err, ErrorEncryptedFileBadHeader.Error())
assert.Equal(t, 0, cd.closed)
var expectedErr error
switch {
case i == fileHeaderSize:
// This would normally produce an error *except* on the first block
expectedErr = nil
case i <= fileHeaderSize+blockHeaderSize:
expectedErr = ErrorEncryptedFileBadHeader
default:
expectedErr = io.ErrUnexpectedEOF
}
if expectedErr != nil {
assert.EqualError(t, err, expectedErr.Error(), what)
} else {
assert.NoError(t, err, what)
}
assert.Equal(t, 0, cd.closed, what)
}
// Test producing an error on the file on Read the underlying file