storj.io/uplink@v1.13.0/private/piecestore/verification.go (about) 1 // Copyright (C) 2019 Storj Labs, Inc. 2 // See LICENSE for copying information. 3 4 package piecestore 5 6 import ( 7 "bytes" 8 "context" 9 "time" 10 11 "github.com/zeebo/errs" 12 13 "storj.io/common/identity" 14 "storj.io/common/pb" 15 "storj.io/common/signing" 16 ) 17 18 const pieceHashExpiration = 24 * time.Hour 19 20 var ( 21 // ErrInternal is an error class for internal errors. 22 ErrInternal = errs.Class("internal") 23 // ErrProtocol is an error class for unexpected protocol sequence. 24 ErrProtocol = errs.Class("protocol") 25 // ErrVerifyUntrusted is an error in case there is a trust issue. 26 ErrVerifyUntrusted = errs.Class("untrusted") 27 // ErrStorageNodeInvalidResponse is an error when a storage node returns a response with invalid data. 28 ErrStorageNodeInvalidResponse = errs.Class("storage node has returned an invalid response") 29 ) 30 31 // VerifyPieceHash verifies piece hash which is sent by peer. 32 func (client *Client) VerifyPieceHash(ctx context.Context, peer *identity.PeerIdentity, limit *pb.OrderLimit, hash *pb.PieceHash, expectedHash []byte, algorithm pb.PieceHashAlgorithm) (err error) { 33 defer mon.Task()(&ctx)(&err) 34 if peer == nil || limit == nil || hash == nil || len(expectedHash) == 0 { 35 return ErrProtocol.New("invalid arguments") 36 } 37 if limit.PieceId != hash.PieceId { 38 return ErrProtocol.New("piece id changed") // TODO: report rpc status bad message 39 } 40 if algorithm != hash.HashAlgorithm { 41 return ErrVerifyUntrusted.New("hash algorithms don't match expected: %s got: %s", algorithm, hash.HashAlgorithm) 42 } 43 if !bytes.Equal(hash.Hash, expectedHash) { 44 return ErrVerifyUntrusted.New("hashes don't match") // TODO: report rpc status bad message 45 } 46 47 if err := signing.VerifyPieceHashSignature(ctx, signing.SigneeFromPeerIdentity(peer), hash); err != nil { 48 return ErrVerifyUntrusted.New("invalid hash signature: %v", err) // TODO: report rpc status bad message 49 } 50 51 if hash.Timestamp.Before(time.Now().Add(-pieceHashExpiration)) { 52 return ErrStorageNodeInvalidResponse.New("piece has timestamp is too old (%v). Required to be not older than %s", 53 hash.Timestamp, pieceHashExpiration, 54 ) 55 } 56 57 return nil 58 }