diff --git a/cid.go b/cid.go index 993f859..83f879b 100644 --- a/cid.go +++ b/cid.go @@ -138,15 +138,15 @@ type Cid struct { // compatibility with the plain-multihash format used used in IPFS. // NewCidV1 should be used preferentially. func NewCidV0(mhash mh.Multihash) (*Cid, error) { - if mhash[0] != mh.SHA2_256 && mhash[1] != byte(mh.DefaultLengths[mh.SHA2_256]) { - return nil, ErrCid0OnlySHA256 - } - c := &Cid{ version: 0, codec: DagProtobuf, hash: mhash, } + err := ValidateCid(c) + if err != nil { + return nil, err + } return c, nil } diff --git a/validate.go b/validate.go index 7ee50a8..3dac7bd 100644 --- a/validate.go +++ b/validate.go @@ -46,6 +46,13 @@ func IsGoodHash(code uint64) bool { func ValidateCid(c *Cid) error { pref := c.Prefix() + if pref.Version == 0 { + if pref.MhType != mh.SHA2_256 || pref.MhLength != mh.DefaultLengths[mh.SHA2_256] { + return ErrCid0OnlySHA256 + } + return nil + } + if !IsGoodHash(pref.MhType) { return fmt.Errorf("potentially insecure hash functions not allowed") } diff --git a/validate_test.go b/validate_test.go index a161f9a..6347445 100644 --- a/validate_test.go +++ b/validate_test.go @@ -30,7 +30,20 @@ func TestValidateCids(t *testing.T) { assertFalse(IsGoodHash(mh.BLAKE2B_MIN + 5)) - mhcid := func(code uint64, length int) *Cid { + mhcid0 := func(code uint64, length int) *Cid { + c := &Cid{ + version: 0, + codec: DagProtobuf, + } + mhash, err := mh.Sum([]byte{}, code, length) + if err != nil { + t.Fatal(err) + } + c.hash = mhash + return c + } + + mhcid1 := func(code uint64, length int) *Cid { c := &Cid{ version: 1, codec: DagCBOR, @@ -47,9 +60,13 @@ func TestValidateCids(t *testing.T) { cid *Cid err string }{ - {mhcid(mh.SHA2_256, 32), ""}, - {mhcid(mh.SHA2_256, 16), "hashes must be at least 20 bytes long"}, - {mhcid(mh.MURMUR3, 4), "potentially insecure hash functions not allowed"}, + {mhcid0(mh.SHA2_256, 32), ""}, + {mhcid0(mh.SHA3_256, 32), "cidv0 accepts only SHA256 hashes of standard length"}, + {mhcid0(mh.SHA2_256, 16), "cidv0 accepts only SHA256 hashes of standard length"}, + {mhcid0(mh.MURMUR3, 4), "cidv0 accepts only SHA256 hashes of standard length"}, + {mhcid1(mh.SHA2_256, 32), ""}, + {mhcid1(mh.SHA2_256, 16), "hashes must be at least 20 bytes long"}, + {mhcid1(mh.MURMUR3, 4), "potentially insecure hash functions not allowed"}, } for i, cas := range cases {