Skip to content

Commit

Permalink
Sign multipart objects in the gate (#1001)
Browse files Browse the repository at this point in the history
Closes #975.
  • Loading branch information
roman-khimov authored Sep 13, 2024
2 parents 63fc2aa + 4cff0fc commit 21e6a71
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 6 deletions.
25 changes: 21 additions & 4 deletions api/layer/multipart_upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,15 @@ func (n *layer) uploadPart(ctx context.Context, multipartInfo *data.MultipartInf
if nBts > 0 {
prm.Payload = bytes.NewReader((*chunk)[:nBts])
prm.PayloadSize = uint64(nBts)
prm.Multipart.PayloadHash = sha256.New()
prm.Multipart.PayloadHash.Write((*chunk)[:nBts])

id, _, err = n.objectPutAndHash(ctx, prm, bktInfo)
if n.neoFS.IsHomomorphicHashingEnabled() {
prm.Multipart.HomoHash = tz.New()
prm.Multipart.HomoHash.Write((*chunk)[:nBts])
}

id, err = n.multipartObjectPut(ctx, prm, bktInfo)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -496,11 +503,16 @@ func (n *layer) uploadZeroPart(ctx context.Context, multipartInfo *data.Multipar
Multipart: &Multipart{
MultipartHashes: objHashes,
HeaderObject: &hashlessHeaderObject,
PayloadHash: sha256.New(),
},
Payload: bytes.NewBuffer(nil),
}

id, _, err := n.objectPutAndHash(ctx, prm, bktInfo)
if n.neoFS.IsHomomorphicHashingEnabled() {
prm.Multipart.HomoHash = tz.New()
}

id, err := n.multipartObjectPut(ctx, prm, bktInfo)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -822,11 +834,16 @@ func (n *layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipar
SplitFirstID: &splitFirstID,
SplitPreviousID: &splitPreviousID,
HeaderObject: header,
PayloadHash: sha256.New(),
},
Payload: bytes.NewBuffer(nil),
}

lastPartObjID, _, err := n.objectPutAndHash(ctx, prm, p.Info.Bkt)
if n.neoFS.IsHomomorphicHashingEnabled() {
prm.Multipart.HomoHash = tz.New()
}

lastPartObjID, err := n.multipartObjectPut(ctx, prm, p.Info.Bkt)
if err != nil {
return nil, nil, err
}
Expand All @@ -852,7 +869,7 @@ func (n *layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipar
},
}

_, _, err = n.objectPutAndHash(ctx, prm, p.Info.Bkt)
_, err = n.multipartObjectPut(ctx, prm, p.Info.Bkt)
if err != nil {
return nil, nil, err
}
Expand Down
4 changes: 4 additions & 0 deletions api/layer/neofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ type Multipart struct {
HeaderObject *object.Object
// Link contains info for linking object.
Link *object.Link
// PayloadHash contains precalculated hash for object.
PayloadHash hash.Hash
// HomoHash contains precalculated homomorphic hash for object if enabled.
HomoHash hash.Hash
}

// PrmObjectDelete groups parameters of NeoFS.DeleteObject operation.
Expand Down
18 changes: 16 additions & 2 deletions api/layer/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,20 @@ func (n *layer) objectPutAndHash(ctx context.Context, prm PrmObjectCreate, bktIn
hash := sha256.New()
prm.Payload = wrapReader(prm.Payload, 64*1024, func(buf []byte) {
hash.Write(buf)
})
id, err := n.neoFS.CreateObject(ctx, prm)
if err != nil {
return oid.ID{}, nil, err
}
return id, hash.Sum(nil), nil
}

// multipartObjectPut writes only Multipart hash collection.
// It doesn't calculate hash from payload, it already calculated in prm.Multipart.PayloadHash, if required.
func (n *layer) multipartObjectPut(ctx context.Context, prm PrmObjectCreate, bktInfo *data.BucketInfo) (oid.ID, error) {
n.prepareAuthParameters(ctx, &prm.PrmAuth, bktInfo.Owner)

prm.Payload = wrapReader(prm.Payload, 64*1024, func(buf []byte) {
if prm.Multipart != nil {
for _, h := range prm.Multipart.MultipartHashes {
h.Write(buf)
Expand All @@ -496,9 +510,9 @@ func (n *layer) objectPutAndHash(ctx context.Context, prm PrmObjectCreate, bktIn
})
id, err := n.neoFS.CreateObject(ctx, prm)
if err != nil {
return oid.ID{}, nil, err
return oid.ID{}, err
}
return id, hash.Sum(nil), nil
return id, nil
}

// ListObjectsV1 returns objects in a bucket for requests of Version 1.
Expand Down
31 changes: 31 additions & 0 deletions internal/neofs/neofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/nspcc-dev/neofs-sdk-go/container"
"github.com/nspcc-dev/neofs-sdk-go/container/acl"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
"github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
Expand Down Expand Up @@ -246,6 +247,19 @@ func (x *NeoFS) DeleteContainer(ctx context.Context, id cid.ID, token *session.C
return nil
}

func (x *NeoFS) signMultipartObject(obj *object.Object, signer neofscrypto.Signer, payloadHash, homoHash hash.Hash) error {
obj.SetPayloadChecksum(checksum.NewFromHash(checksum.SHA256, payloadHash))
if homoHash != nil {
obj.SetPayloadHomomorphicHash(checksum.NewFromHash(checksum.TillichZemor, homoHash))
}

if err := obj.SetIDWithSignature(signer); err != nil {
return fmt.Errorf("set id with signature: %w", err)
}

return nil
}

// CreateObject implements neofs.NeoFS interface method.
func (x *NeoFS) CreateObject(ctx context.Context, prm layer.PrmObjectCreate) (oid.ID, error) {
attrNum := len(prm.Attributes) + 1 // + creation time
Expand Down Expand Up @@ -310,9 +324,26 @@ func (x *NeoFS) CreateObject(ctx context.Context, prm layer.PrmObjectCreate) (oi
prm.Payload = bytes.NewReader(obj.Payload())
obj.SetPayloadSize(uint64(len(obj.Payload())))

prm.Multipart.PayloadHash = sha256.New()
prm.Multipart.PayloadHash.Write(obj.Payload())

if x.IsHomomorphicHashingEnabled() {
prm.Multipart.HomoHash = tz.New()
prm.Multipart.HomoHash.Write(obj.Payload())
}

// Link object should never have a previous one.
obj.ResetPreviousID()
}

if err := x.signMultipartObject(
&obj,
x.signer(ctx),
prm.Multipart.PayloadHash,
prm.Multipart.HomoHash,
); err != nil {
return oid.ID{}, errors.New("failed to sign object")
}
}

if len(prm.Locks) > 0 {
Expand Down

0 comments on commit 21e6a71

Please sign in to comment.