You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
terraform/internal/releaseauth/checksum.go

60 lines
1.5 KiB

// Copyright IBM Corp. 2014, 2026
// SPDX-License-Identifier: BUSL-1.1
package releaseauth
import (
"bytes"
"crypto/sha256"
"errors"
"fmt"
"io"
"log"
"os"
)
// ChecksumAuthentication is an archive Authenticator that ensures a given file
// matches a SHA-256 checksum. It is important to verify the authenticity of the
// given checksum prior to using this Authenticator.
type ChecksumAuthentication struct {
Authenticator
expected SHA256Hash
archiveLocation string
}
// ErrChecksumDoesNotMatch is the error returned when the archive checksum does
// not match the given checksum.
var ErrChecksumDoesNotMatch = errors.New("downloaded archive does not match the release checksum")
// NewChecksumAuthentication creates an instance of ChecksumAuthentication with the given
// checksum and file location.
func NewChecksumAuthentication(expected SHA256Hash, archiveLocation string) *ChecksumAuthentication {
return &ChecksumAuthentication{
expected: expected,
archiveLocation: archiveLocation,
}
}
func (a ChecksumAuthentication) Authenticate() error {
f, err := os.Open(a.archiveLocation)
if err != nil {
return fmt.Errorf("failed to open downloaded archive: %w", err)
}
defer f.Close()
h := sha256.New()
_, err = io.Copy(h, f)
if err != nil {
return fmt.Errorf("failed to hash downloaded archive: %w", err)
}
gotHash := h.Sum(nil)
log.Printf("[TRACE] checksummed %q; got hash %x, expected %x", f.Name(), gotHash, a.expected)
if !bytes.Equal(gotHash, a.expected[:]) {
return ErrChecksumDoesNotMatch
}
return nil
}