2022-04-17 01:02:07 +02:00
|
|
|
package lib
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"crypto/sha256"
|
|
|
|
"encoding/hex"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"os"
|
2022-06-05 06:42:40 +02:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2022-04-17 01:02:07 +02:00
|
|
|
|
2022-09-02 09:15:58 +02:00
|
|
|
"github.com/slsa-framework/slsa-verifier/options"
|
|
|
|
"github.com/slsa-framework/slsa-verifier/verifiers"
|
2022-04-17 01:02:07 +02:00
|
|
|
)
|
|
|
|
|
2022-09-22 05:22:34 +02:00
|
|
|
func verify(ctx *context.Context, provenance []byte, artifactHash, source, branch, versionTag string) error {
|
2022-09-02 09:15:58 +02:00
|
|
|
provenanceOpts := &options.ProvenanceOpts{
|
|
|
|
ExpectedSourceURI: source,
|
|
|
|
ExpectedBranch: &branch,
|
|
|
|
ExpectedDigest: artifactHash,
|
|
|
|
ExpectedVersionedTag: &versionTag,
|
|
|
|
}
|
|
|
|
builderOpts := &options.BuilderOpts{}
|
2022-09-23 03:11:35 +02:00
|
|
|
_, _, err := verifiers.Verify(*ctx, provenance, artifactHash, provenanceOpts, builderOpts)
|
2022-09-02 09:15:58 +02:00
|
|
|
return err
|
2022-04-17 01:02:07 +02:00
|
|
|
}
|
|
|
|
|
2022-06-05 06:42:40 +02:00
|
|
|
func checkForDowngrade(currentVersionS, newVersionS string) error {
|
|
|
|
currentVersion, err := strconv.Atoi(strings.TrimPrefix(currentVersionS, "v0."))
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to parse current version %#v", currentVersionS)
|
|
|
|
}
|
|
|
|
newVersion, err := strconv.Atoi(strings.TrimPrefix(newVersionS, "v0."))
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to parse updated version %#v", newVersionS)
|
|
|
|
}
|
|
|
|
if currentVersion > newVersion {
|
|
|
|
return fmt.Errorf("failed to update because the new version (%#v) is a downgrade compared to the current version (%#v)", newVersionS, currentVersionS)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-09-22 05:22:34 +02:00
|
|
|
func verifyBinary(ctx *context.Context, binaryPath, attestationPath, versionTag string) error {
|
2022-05-27 08:45:08 +02:00
|
|
|
if os.Getenv("HISHTORY_DISABLE_SLSA_ATTESTATION") == "true" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-06-05 06:42:40 +02:00
|
|
|
if err := checkForDowngrade(Version, versionTag); err != nil && os.Getenv("HISHTORY_ALLOW_DOWNGRADE") == "true" {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-04-17 01:02:07 +02:00
|
|
|
attestation, err := os.ReadFile(attestationPath)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to read attestation file: %v", err)
|
|
|
|
}
|
|
|
|
|
2022-05-27 08:45:08 +02:00
|
|
|
hash, err := getFileHash(binaryPath)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-09-22 05:22:34 +02:00
|
|
|
return verify(ctx, attestation, hash, "github.com/ddworken/hishtory", "master", versionTag)
|
2022-05-27 08:45:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func getFileHash(binaryPath string) (string, error) {
|
2022-04-17 01:02:07 +02:00
|
|
|
binaryFile, err := os.Open(binaryPath)
|
|
|
|
if err != nil {
|
2022-05-27 08:45:08 +02:00
|
|
|
return "", fmt.Errorf("failed to read binary for verification purposes: %v", err)
|
2022-04-17 01:02:07 +02:00
|
|
|
}
|
|
|
|
defer binaryFile.Close()
|
|
|
|
|
|
|
|
hasher := sha256.New()
|
|
|
|
if _, err := io.Copy(hasher, binaryFile); err != nil {
|
2022-05-27 08:45:08 +02:00
|
|
|
return "", fmt.Errorf("failed to hash binary: %v", err)
|
2022-04-17 01:02:07 +02:00
|
|
|
}
|
|
|
|
hash := hex.EncodeToString(hasher.Sum(nil))
|
2022-05-27 08:45:08 +02:00
|
|
|
return hash, nil
|
2022-04-17 01:02:07 +02:00
|
|
|
}
|