Fix decrypted object size and key derivation in CopyObjectPart (#6141)

This commit fixes the size calculation for multipart
objects. The decrypted size of an encrypted multipart
object is the sum of the decrypted part sizes.

Also fixes the key derivation in CopyObjectPart.
Instead of using the same object-encryption-key for each
part now an unique per-part key is derived.

Updates #6139
master
Andreas Auernhammer 6 years ago committed by Nitish Tiwari
parent 44865596db
commit 15771ebe8d
  1. 20
      cmd/encryption-v1.go
  2. 9
      cmd/object-handlers.go

@ -786,11 +786,23 @@ func (o *ObjectInfo) DecryptedSize() (int64, error) {
if !o.IsEncrypted() {
return 0, errors.New("Cannot compute decrypted size of an unencrypted object")
}
size, err := sio.DecryptedSize(uint64(o.Size))
if err != nil {
err = errObjectTampered // assign correct error type
if len(o.Parts) == 0 {
size, err := sio.DecryptedSize(uint64(o.Size))
if err != nil {
err = errObjectTampered // assign correct error type
}
return int64(size), err
}
var size int64
for _, part := range o.Parts {
partSize, err := sio.DecryptedSize(uint64(part.Size))
if err != nil {
return 0, errObjectTampered
}
size += int64(partSize)
}
return int64(size), err
return size, nil
}
// EncryptedSize returns the size of the object after encryption.

@ -1077,7 +1077,6 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt
return
}
// Calculating object encryption key
var objectEncryptionKey []byte
objectEncryptionKey, err = decryptObjectInfo(key, dstBucket, dstObject, li.UserDefined)
if err != nil {
@ -1086,7 +1085,13 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt
return
}
reader, err = sio.EncryptReader(reader, sio.Config{Key: objectEncryptionKey})
var partIDbin [4]byte
binary.LittleEndian.PutUint32(partIDbin[:], uint32(partID)) // marshal part ID
mac := hmac.New(sha256.New, objectEncryptionKey) // derive part encryption key from part ID and object key
mac.Write(partIDbin[:])
partEncryptionKey := mac.Sum(nil)
reader, err = sio.EncryptReader(reader, sio.Config{Key: partEncryptionKey})
if err != nil {
pipeWriter.CloseWithError(err)
writeErrorResponse(w, toAPIErrorCode(err), r.URL)

Loading…
Cancel
Save