mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
crypto/hmac: wrap ErrUnsupported returned by Clone
Updates #69521 Change-Id: I6a6a4656403b9d35d5e4641b5c5c4975f3fa0e43 Reviewed-on: https://go-review.googlesource.com/c/go/+/675555 Reviewed-by: Austin Clements <austin@google.com> Auto-Submit: Filippo Valsorda <filippo@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Roland Shoemaker <roland@golang.org>
This commit is contained in:
parent
03ad694dcb
commit
4731832342
3 changed files with 32 additions and 8 deletions
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash"
|
"hash"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -583,6 +584,18 @@ func TestHMAC(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNoClone(t *testing.T) {
|
||||||
|
h := New(func() hash.Hash { return justHash{sha256.New()} }, []byte("key"))
|
||||||
|
if _, ok := h.(hash.Cloner); !ok {
|
||||||
|
t.Skip("no Cloner support")
|
||||||
|
}
|
||||||
|
h.Write([]byte("test"))
|
||||||
|
_, err := h.(hash.Cloner).Clone()
|
||||||
|
if !errors.Is(err, errors.ErrUnsupported) {
|
||||||
|
t.Errorf("Clone() = %v, want ErrUnsupported", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestNonUniqueHash(t *testing.T) {
|
func TestNonUniqueHash(t *testing.T) {
|
||||||
if boring.Enabled {
|
if boring.Enabled {
|
||||||
t.Skip("hash.Hash provided by boringcrypto are not comparable")
|
t.Skip("hash.Hash provided by boringcrypto are not comparable")
|
||||||
|
|
|
||||||
|
|
@ -130,26 +130,36 @@ func (h *HMAC) Reset() {
|
||||||
h.marshaled = true
|
h.marshaled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type errCloneUnsupported struct{}
|
||||||
|
|
||||||
|
func (e errCloneUnsupported) Error() string {
|
||||||
|
return "crypto/hmac: hash does not support hash.Cloner"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e errCloneUnsupported) Unwrap() error {
|
||||||
|
return errors.ErrUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
// Clone implements [hash.Cloner] if the underlying hash does.
|
// Clone implements [hash.Cloner] if the underlying hash does.
|
||||||
// Otherwise, it returns [errors.ErrUnsupported].
|
// Otherwise, it returns an error wrapping [errors.ErrUnsupported].
|
||||||
func (h *HMAC) Clone() (hash.Cloner, error) {
|
func (h *HMAC) Clone() (hash.Cloner, error) {
|
||||||
r := *h
|
r := *h
|
||||||
ic, ok := h.inner.(hash.Cloner)
|
ic, ok := h.inner.(hash.Cloner)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.ErrUnsupported
|
return nil, errCloneUnsupported{}
|
||||||
}
|
}
|
||||||
oc, ok := h.outer.(hash.Cloner)
|
oc, ok := h.outer.(hash.Cloner)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.ErrUnsupported
|
return nil, errCloneUnsupported{}
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
r.inner, err = ic.Clone()
|
r.inner, err = ic.Clone()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.ErrUnsupported
|
return nil, errCloneUnsupported{}
|
||||||
}
|
}
|
||||||
r.outer, err = oc.Clone()
|
r.outer, err = oc.Clone()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.ErrUnsupported
|
return nil, errCloneUnsupported{}
|
||||||
}
|
}
|
||||||
return &r, nil
|
return &r, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,13 +57,14 @@ type Hash64 interface {
|
||||||
Sum64() uint64
|
Sum64() uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Cloner is a hash function whose state can be cloned.
|
// A Cloner is a hash function whose state can be cloned, returning a value with
|
||||||
|
// equivalent and independent state.
|
||||||
//
|
//
|
||||||
// All [Hash] implementations in the standard library implement this interface,
|
// All [Hash] implementations in the standard library implement this interface,
|
||||||
// unless GOFIPS140=v1.0.0 is set.
|
// unless GOFIPS140=v1.0.0 is set.
|
||||||
//
|
//
|
||||||
// If a hash can only determine at runtime if it can be cloned,
|
// If a hash can only determine at runtime if it can be cloned (e.g. if it wraps
|
||||||
// (e.g., if it wraps another hash), it may return [errors.ErrUnsupported].
|
// another hash), it may return an error wrapping [errors.ErrUnsupported].
|
||||||
type Cloner interface {
|
type Cloner interface {
|
||||||
Hash
|
Hash
|
||||||
Clone() (Cloner, error)
|
Clone() (Cloner, error)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue