Skip to content

Commit be10948

Browse files
authored
Merge pull request #1676 from aramase/aramase/b/sha_logic
fix: update the hash generation logic
2 parents 6c0fbc3 + b0fdeb5 commit be10948

File tree

2 files changed

+38
-17
lines changed

2 files changed

+38
-17
lines changed

pkg/util/secretutil/secret.go

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,16 @@ import (
2323
"crypto/x509"
2424
"encoding/pem"
2525
"fmt"
26-
"io"
26+
"math"
2727
"os"
28-
"sort"
2928
"strings"
3029

3130
secretsstorev1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1"
3231

32+
"golang.org/x/crypto/cryptobyte"
3333
"golang.org/x/crypto/pkcs12"
3434
corev1 "k8s.io/api/core/v1"
35+
"k8s.io/apimachinery/pkg/util/sets"
3536
)
3637

3738
const (
@@ -217,23 +218,33 @@ func GetSecretData(secretObjData []*secretsstorev1.SecretObjectData, secretType
217218

218219
// GetSHAFromSecret gets SHA for the secret data
219220
func GetSHAFromSecret(data map[string][]byte) (string, error) {
220-
var values []string
221-
for k, v := range data {
222-
values = append(values, k+"="+string(v))
223-
}
224-
// sort the values to always obtain a deterministic SHA for
225-
// same content in different order
226-
sort.Strings(values)
227-
return generateSHA(strings.Join(values, ";"))
228-
}
221+
if len(data) == 0 {
222+
return "", nil
223+
}
224+
225+
b := cryptobyte.NewBuilder(nil)
226+
if len(data) > math.MaxUint32 {
227+
return "", fmt.Errorf("data too large: length exceeds uint32 max")
228+
}
229+
// we are checking the length of the data to be less than uint32 max
230+
// so we can safely cast it to uint32 without worrying about overflow
231+
b.AddUint32(uint32(len(data))) // nolint:gosec
229232

230-
// generateSHA generates SHA from string
231-
func generateSHA(data string) (string, error) {
232-
hasher := sha256.New()
233-
_, err := io.WriteString(hasher, data)
233+
keys := sets.StringKeySet(data).List()
234+
235+
for _, k := range keys {
236+
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
237+
b.AddBytes([]byte(k))
238+
})
239+
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
240+
b.AddBytes(data[k])
241+
})
242+
}
243+
244+
hashData, err := b.Bytes()
234245
if err != nil {
235246
return "", err
236247
}
237-
sha := hasher.Sum(nil)
238-
return fmt.Sprintf("%x", sha), nil
248+
249+
return fmt.Sprintf("%x", sha256.Sum256(hashData)), nil
239250
}

pkg/util/secretutil/secret_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,16 @@ func TestGenerateSHAFromSecret(t *testing.T) {
412412
data2: map[string][]byte{"key2": []byte("value2"), "key1": []byte("value1")},
413413
expectedSHAMatch: true,
414414
},
415+
{
416+
name: "different keys with the same concatenated result but should not match",
417+
data1: map[string][]byte{
418+
"key1": []byte("=value1"),
419+
},
420+
data2: map[string][]byte{
421+
"key1=": []byte("value1"),
422+
},
423+
expectedSHAMatch: false,
424+
},
415425
}
416426

417427
for _, test := range tests {

0 commit comments

Comments
 (0)