mirror of https://github.com/docker/docs.git
Utility function for comparing multihash
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
This commit is contained in:
parent
0256cee017
commit
ade6b0736e
|
@ -161,6 +161,44 @@ func CheckHashes(payload []byte, name string, hashes Hashes) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// CompareMultiHashes verifies that the two Hashes passed in can represent the same data.
|
||||
// This means that both maps must have at least one key defined for which they map, and no conflicts.
|
||||
// Note that we only check supported hashes, like in CheckHashes
|
||||
func CompareMultiHashes(hashes1, hashes2 Hashes) error {
|
||||
// First check if the two hash structures are valid
|
||||
if err := CheckValidHashStructures(hashes1); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := CheckValidHashStructures(hashes2); err != nil {
|
||||
return err
|
||||
}
|
||||
// Check if they have at least one matching hash, and no conflicts
|
||||
cnt := 0
|
||||
for _, hashAlg := range NotaryDefaultHashes {
|
||||
hash1, ok := hashes1[hashAlg]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
hash2, ok := hashes2[hashAlg]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if subtle.ConstantTimeCompare(hash1[:], hash2[:]) == 0 {
|
||||
return fmt.Errorf("mismatched %s checksum", hashAlg)
|
||||
}
|
||||
// If we reached here, we had a match
|
||||
cnt++
|
||||
}
|
||||
|
||||
if cnt == 0 {
|
||||
return fmt.Errorf("at least one supported and matching hash needed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckValidHashStructures returns an error, or nil, depending on whether
|
||||
// the content of the hashes is valid or not.
|
||||
func CheckValidHashStructures(hashes Hashes) error {
|
||||
|
|
|
@ -3,6 +3,7 @@ package data
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/go/canonical/json"
|
||||
|
@ -176,3 +177,52 @@ func TestCheckValidHashStructures(t *testing.T) {
|
|||
err = CheckValidHashStructures(hashes)
|
||||
require.IsType(t, ErrInvalidChecksum{}, err)
|
||||
}
|
||||
|
||||
func TestCompareMultiHashes(t *testing.T) {
|
||||
var err error
|
||||
hashes1 := make(Hashes)
|
||||
hashes2 := make(Hashes)
|
||||
|
||||
// Expected to fail since there are no checksums at all
|
||||
err = CompareMultiHashes(hashes1, hashes2)
|
||||
require.Error(t, err)
|
||||
|
||||
// Expected to fail even though the checksum of sha384 is valid,
|
||||
// because we haven't provided a supported hash algorithm yet (ex: sha256).
|
||||
hashes1["sha384"], err = hex.DecodeString("64becc3c23843942b1040ffd4743d1368d988ddf046d17d448a6e199c02c3044b425a680112b399d4dbe9b35b7ccc989")
|
||||
hashes2["sha384"], err = hex.DecodeString("64becc3c23843942b1040ffd4743d1368d988ddf046d17d448a6e199c02c3044b425a680112b399d4dbe9b35b7ccc989")
|
||||
err = CompareMultiHashes(hashes1, hashes2)
|
||||
require.Error(t, err)
|
||||
|
||||
// Now both have a matching sha256, so this will pass
|
||||
hashes1["sha256"], err = hex.DecodeString("766af0ef090a4f2307e49160fa242db6fb95f071ad81a198eeb7d770e61cd6d8")
|
||||
hashes2["sha256"], err = hex.DecodeString("766af0ef090a4f2307e49160fa242db6fb95f071ad81a198eeb7d770e61cd6d8")
|
||||
err = CompareMultiHashes(hashes1, hashes2)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Because the sha384 algorithm isn't supported, it's treated as an extra key that won't be checked
|
||||
// So even if it doesn't match, that's fine as long as all supported keys match
|
||||
hashes2["sha384"], err = hex.DecodeString(strings.Repeat("a", 96))
|
||||
err = CompareMultiHashes(hashes1, hashes2)
|
||||
require.NoError(t, err)
|
||||
|
||||
// only add a sha512 to hashes1, but comparison will still succeed because there's no mismatch and we have the sha256 match
|
||||
hashes1["sha512"], err = hex.DecodeString("795d9e95db099464b6730844f28effddb010b0d5abae5d5892a6ee04deacb09c9e622f89e816458b5a1a81761278d7d3a6a7c269d9707eff8858b16c51de0315")
|
||||
err = CompareMultiHashes(hashes1, hashes2)
|
||||
require.NoError(t, err)
|
||||
|
||||
// remove sha256 from hashes1, comparison will fail now because there are no matches
|
||||
delete(hashes1, "sha256")
|
||||
err = CompareMultiHashes(hashes1, hashes2)
|
||||
require.Error(t, err)
|
||||
|
||||
// add sha512 to hashes2, comparison will now pass because both have matching sha512s
|
||||
hashes2["sha512"], err = hex.DecodeString("795d9e95db099464b6730844f28effddb010b0d5abae5d5892a6ee04deacb09c9e622f89e816458b5a1a81761278d7d3a6a7c269d9707eff8858b16c51de0315")
|
||||
err = CompareMultiHashes(hashes1, hashes2)
|
||||
require.NoError(t, err)
|
||||
|
||||
// change the sha512 for hashes2, comparison will now fail
|
||||
hashes2["sha512"], err = hex.DecodeString(strings.Repeat("a", notary.Sha512HexSize))
|
||||
err = CompareMultiHashes(hashes1, hashes2)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue