github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/gateway/sig/sha_256_reader.go (about)

     1  package sig
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"encoding/hex"
     6  	"hash"
     7  	"io"
     8  
     9  	"github.com/treeverse/lakefs/pkg/gateway/errors"
    10  )
    11  
    12  type Sha256Reader struct {
    13  	src          io.ReadCloser
    14  	expectedHash []byte
    15  	hash         hash.Hash
    16  }
    17  
    18  func NewSha265Reader(src io.ReadCloser, sha256Hex string) (io.ReadCloser, error) {
    19  	expectedHash, err := hex.DecodeString(sha256Hex)
    20  	if err != nil {
    21  		return nil, err
    22  	}
    23  
    24  	Sha256hash := sha256.New()
    25  
    26  	return &Sha256Reader{
    27  		expectedHash: expectedHash,
    28  		src:          src,
    29  		hash:         Sha256hash,
    30  	}, nil
    31  }
    32  
    33  func (r *Sha256Reader) Read(p []byte) (int, error) {
    34  	n, err := r.src.Read(p)
    35  	if n > 0 {
    36  		if _, err := r.hash.Write(p[:n]); err != nil {
    37  			return n, err
    38  		}
    39  	}
    40  	if err == io.EOF {
    41  		if err := r.Verify(); err != nil {
    42  			return n, err
    43  		}
    44  	}
    45  	return n, err
    46  }
    47  
    48  func (r *Sha256Reader) Verify() error {
    49  	if sum := r.hash.Sum(nil); !Equal(r.expectedHash, sum) {
    50  		return errors.ErrSignatureDoesNotMatch
    51  	}
    52  	return nil
    53  }
    54  
    55  func (r *Sha256Reader) Close() error {
    56  	return r.src.Close()
    57  }