51 lines
1.2 KiB
Go
51 lines
1.2 KiB
Go
package bundle
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var digestPattern = regexp.MustCompile(`^sha256:[0-9a-f]{64}$`)
|
|
|
|
// ValidateDigest reports whether value uses the lowercase sha256:<64 hex> form.
|
|
func ValidateDigest(value string) error {
|
|
if !digestPattern.MatchString(value) {
|
|
return fmt.Errorf("must be lowercase sha256:<64 hex>")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func FileDigest(data []byte) string {
|
|
sum := sha256.Sum256(data)
|
|
return "sha256:" + hex.EncodeToString(sum[:])
|
|
}
|
|
|
|
func BundleDigest(files []ManifestFile) string {
|
|
canonical := CanonicalFilePayload(files)
|
|
sum := sha256.Sum256([]byte(canonical))
|
|
return "sha256:" + hex.EncodeToString(sum[:])
|
|
}
|
|
|
|
func CanonicalFilePayload(files []ManifestFile) string {
|
|
var builder strings.Builder
|
|
builder.WriteByte('[')
|
|
for index, file := range files {
|
|
if index > 0 {
|
|
builder.WriteByte(',')
|
|
}
|
|
builder.WriteString(`{"path":`)
|
|
builder.WriteString(strconv.Quote(file.Path))
|
|
builder.WriteString(`,"sha256":`)
|
|
builder.WriteString(strconv.Quote(file.SHA256))
|
|
builder.WriteString(`,"size":`)
|
|
builder.WriteString(strconv.FormatInt(file.Size, 10))
|
|
builder.WriteByte('}')
|
|
}
|
|
builder.WriteByte(']')
|
|
return builder.String()
|
|
}
|