mirror of
https://github.com/octoleo/restic.git
synced 2024-11-21 20:35:12 +00:00
backup: verify blobs before upload
This only covers the blobs themselves, the pack header is not verified so far. Unpacked files are also not covered by the integrity check.
This commit is contained in:
parent
16e3f79e8b
commit
c01a0c6da7
@ -423,6 +423,11 @@ func (r *Repository) saveAndEncrypt(ctx context.Context, t restic.BlobType, data
|
|||||||
// encrypt blob
|
// encrypt blob
|
||||||
ciphertext = r.key.Seal(ciphertext, nonce, data, nil)
|
ciphertext = r.key.Seal(ciphertext, nonce, data, nil)
|
||||||
|
|
||||||
|
if err := r.verifyCiphertext(ciphertext, uncompressedLength, id); err != nil {
|
||||||
|
// FIXME call to action
|
||||||
|
return 0, fmt.Errorf("detected data corruption while saving blob %v: %w", id, err)
|
||||||
|
}
|
||||||
|
|
||||||
// find suitable packer and add blob
|
// find suitable packer and add blob
|
||||||
var pm *packerManager
|
var pm *packerManager
|
||||||
|
|
||||||
@ -438,6 +443,27 @@ func (r *Repository) saveAndEncrypt(ctx context.Context, t restic.BlobType, data
|
|||||||
return pm.SaveBlob(ctx, t, id, ciphertext, uncompressedLength)
|
return pm.SaveBlob(ctx, t, id, ciphertext, uncompressedLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Repository) verifyCiphertext(buf []byte, uncompressedLength int, id restic.ID) error {
|
||||||
|
nonce, ciphertext := buf[:r.key.NonceSize()], buf[r.key.NonceSize():]
|
||||||
|
plaintext, err := r.key.Open(nil, nonce, ciphertext, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("decryption failed: %w", err)
|
||||||
|
}
|
||||||
|
if uncompressedLength != 0 {
|
||||||
|
// DecodeAll will allocate a slice if it is not large enough since it
|
||||||
|
// knows the decompressed size (because we're using EncodeAll)
|
||||||
|
plaintext, err = r.getZstdDecoder().DecodeAll(plaintext, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("decompression failed: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !restic.Hash(plaintext).Equal(id) {
|
||||||
|
return errors.New("hash mismatch")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) compressUnpacked(p []byte) ([]byte, error) {
|
func (r *Repository) compressUnpacked(p []byte) ([]byte, error) {
|
||||||
// compression is only available starting from version 2
|
// compression is only available starting from version 2
|
||||||
if r.cfg.Version < 2 {
|
if r.cfg.Version < 2 {
|
||||||
|
Loading…
Reference in New Issue
Block a user