hash_io.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package s3crypto
  2. import (
  3. "crypto/md5"
  4. "crypto/sha256"
  5. "hash"
  6. "io"
  7. )
  8. // hashReader is used for calculating SHA256 when following the sigv4 specification.
  9. // Additionally this used for calculating the unencrypted MD5.
  10. type hashReader interface {
  11. GetValue() []byte
  12. GetContentLength() int64
  13. }
  14. type sha256Writer struct {
  15. sha256 []byte
  16. hash hash.Hash
  17. out io.Writer
  18. }
  19. func newSHA256Writer(f io.Writer) *sha256Writer {
  20. return &sha256Writer{hash: sha256.New(), out: f}
  21. }
  22. func (r *sha256Writer) Write(b []byte) (int, error) {
  23. r.hash.Write(b)
  24. return r.out.Write(b)
  25. }
  26. func (r *sha256Writer) GetValue() []byte {
  27. return r.hash.Sum(nil)
  28. }
  29. type md5Reader struct {
  30. contentLength int64
  31. hash hash.Hash
  32. body io.Reader
  33. }
  34. func newMD5Reader(body io.Reader) *md5Reader {
  35. return &md5Reader{hash: md5.New(), body: body}
  36. }
  37. func (w *md5Reader) Read(b []byte) (int, error) {
  38. n, err := w.body.Read(b)
  39. if err != nil && err != io.EOF {
  40. return n, err
  41. }
  42. w.contentLength += int64(n)
  43. w.hash.Write(b[:n])
  44. return n, err
  45. }
  46. func (w *md5Reader) GetValue() []byte {
  47. return w.hash.Sum(nil)
  48. }
  49. func (w *md5Reader) GetContentLength() int64 {
  50. return w.contentLength
  51. }