package getproviders

import (
	"bufio"
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"log"
	"strings"

	// TODO: replace crypto/openpgp since it is deprecated
	// https://github.com/golang/go/issues/44226
	//lint:file-ignore SA1019 openpgp is deprecated but there are no good alternatives yet
	"golang.org/x/crypto/openpgp"
	openpgpArmor "golang.org/x/crypto/openpgp/armor"
	openpgpErrors "golang.org/x/crypto/openpgp/errors"
)

type packageAuthenticationResult int

const (
	verifiedChecksum packageAuthenticationResult = iota
	officialProvider
	partnerProvider
	communityProvider
)

// PackageAuthenticationResult is returned from a PackageAuthentication
// implementation. It is a mostly-opaque type intended for use in UI, which
// implements Stringer.
//
// A failed PackageAuthentication attempt will return an "unauthenticated"
// result, which is represented by nil.
type PackageAuthenticationResult struct {
	result packageAuthenticationResult
	KeyID  string
}

func (t *PackageAuthenticationResult) String() string {
	if t == nil {
		return "unauthenticated"
	}
	return []string{
		"verified checksum",
		"signed by HashiCorp",
		"signed by a HashiCorp partner",
		"self-signed",
	}[t.result]
}

// SignedByHashiCorp returns whether the package was authenticated as signed
// by HashiCorp.
func (t *PackageAuthenticationResult) SignedByHashiCorp() bool {
	if t == nil {
		return false
	}
	if t.result == officialProvider {
		return true
	}

	return false
}

// SignedByAnyParty returns whether the package was authenticated as signed
// by either HashiCorp or by a third-party.
func (t *PackageAuthenticationResult) SignedByAnyParty() bool {
	if t == nil {
		return false
	}
	if t.result == officialProvider || t.result == partnerProvider || t.result == communityProvider {
		return true
	}

	return false
}

// ThirdPartySigned returns whether the package was authenticated as signed by a party
// other than HashiCorp.
func (t *PackageAuthenticationResult) ThirdPartySigned() bool {
	if t == nil {
		return false
	}
	if t.result == partnerProvider || t.result == communityProvider {
		return true
	}

	return false
}

// SigningKey represents a key used to sign packages from a registry, along
// with an optional trust signature from the registry operator. These are
// both in ASCII armored OpenPGP format.
//
// The JSON struct tags represent the field names used by the Registry API.
type SigningKey struct {
	ASCIIArmor     string `json:"ascii_armor"`
	TrustSignature string `json:"trust_signature"`
}

// PackageAuthentication is an interface implemented by the optional package
// authentication implementations a source may include on its PackageMeta
// objects.
//
// A PackageAuthentication implementation is responsible for authenticating
// that a package is what its distributor intended to distribute and that it
// has not been tampered with.
type PackageAuthentication interface {
	// AuthenticatePackage takes the local location of a package (which may or
	// may not be the same as the original source location), and returns a
	// PackageAuthenticationResult, or an error if the authentication checks
	// fail.
	//
	// The local location is guaranteed not to be a PackageHTTPURL: a remote
	// package will always be staged locally for inspection first.
	AuthenticatePackage(localLocation PackageLocation) (*PackageAuthenticationResult, error)
}

// PackageAuthenticationHashes is an optional interface implemented by
// PackageAuthentication implementations that are able to return a set of
// hashes they would consider valid if a given PackageLocation referred to
// a package that matched that hash string.
//
// This can be used to record a set of acceptable hashes for a particular
// package in a lock file so that future install operations can determine
// whether the package has changed since its initial installation.
type PackageAuthenticationHashes interface {
	PackageAuthentication

	// AcceptableHashes returns a set of hashes that this authenticator
	// considers to be valid for the current package or, where possible,
	// equivalent packages on other platforms. The order of the items in
	// the result is not significant, and it may contain duplicates
	// that are also not significant.
	//
	// This method's result should only be used to create a "lock" for a
	// particular provider if an earlier call to AuthenticatePackage for
	// the corresponding package succeeded. A caller might choose to apply
	// differing levels of trust for the acceptable hashes depending on
	// the authentication result: a "verified checksum" result only checked
	// that the downloaded package matched what the source claimed, which
	// could be considered to be less trustworthy than a check that includes
	// verifying a signature from the origin registry, depending on what the
	// hashes are going to be used for.
	//
	// Implementations of PackageAuthenticationHashes may return multiple
	// hashes with different schemes, which means that all of them are equally
	// acceptable. Implementors may also return hashes that use schemes the
	// current version of the authenticator would not allow but that could be
	// accepted by other versions of Terraform, e.g. if a particular hash
	// scheme has been deprecated.
	//
	// Authenticators that don't use hashes as their authentication procedure
	// will either not implement this interface or will have an implementation
	// that returns an empty result.
	AcceptableHashes() []Hash
}

type packageAuthenticationAll []PackageAuthentication

// PackageAuthenticationAll combines several authentications together into a
// single check value, which passes only if all of the given ones pass.
//
// The checks are processed in the order given, so a failure of an earlier
// check will prevent execution of a later one.
//
// The returned result is from the last authentication, so callers should
// take care to order the authentications such that the strongest is last.
//
// The returned object also implements the AcceptableHashes method from
// interface PackageAuthenticationHashes, returning the hashes from the
// last of the given checks that indicates at least one acceptable hash,
// or no hashes at all if none of the constituents indicate any. The result
// may therefore be incomplete if there is more than one check that can provide
// hashes and they disagree about which hashes are acceptable.
func PackageAuthenticationAll(checks ...PackageAuthentication) PackageAuthentication {
	return packageAuthenticationAll(checks)
}

func (checks packageAuthenticationAll) AuthenticatePackage(localLocation PackageLocation) (*PackageAuthenticationResult, error) {
	var authResult *PackageAuthenticationResult
	for _, check := range checks {
		var err error
		authResult, err = check.AuthenticatePackage(localLocation)
		if err != nil {
			return authResult, err
		}
	}
	return authResult, nil
}

func (checks packageAuthenticationAll) AcceptableHashes() []Hash {
	// The elements of checks are expected to be ordered so that the strongest
	// one is later in the list, so we'll visit them in reverse order and
	// take the first one that implements the interface and returns a non-empty
	// result.
	for i := len(checks) - 1; i >= 0; i-- {
		check, ok := checks[i].(PackageAuthenticationHashes)
		if !ok {
			continue
		}
		allHashes := check.AcceptableHashes()
		if len(allHashes) > 0 {
			return allHashes
		}
	}
	return nil
}

type packageHashAuthentication struct {
	RequiredHashes []Hash
	AllHashes      []Hash
	Platform       Platform
}

// NewPackageHashAuthentication returns a PackageAuthentication implementation
// that checks whether the contents of the package match whatever subset of the
// given hashes are considered acceptable by the current version of Terraform.
//
// This uses the hash algorithms implemented by functions PackageHash and
// MatchesHash. The PreferredHashes function will select which of the given
// hashes are considered by Terraform to be the strongest verification, and
// authentication succeeds as long as one of those matches.
func NewPackageHashAuthentication(platform Platform, validHashes []Hash) PackageAuthentication {
	requiredHashes := PreferredHashes(validHashes)
	return packageHashAuthentication{
		RequiredHashes: requiredHashes,
		AllHashes:      validHashes,
		Platform:       platform,
	}
}

func (a packageHashAuthentication) AuthenticatePackage(localLocation PackageLocation) (*PackageAuthenticationResult, error) {
	if len(a.RequiredHashes) == 0 {
		// Indicates that none of the hashes given to
		// NewPackageHashAuthentication were considered to be usable by this
		// version of Terraform.
		return nil, fmt.Errorf("this version of Terraform does not support any of the checksum formats given for this provider")
	}

	matches, err := PackageMatchesAnyHash(localLocation, a.RequiredHashes)
	if err != nil {
		return nil, fmt.Errorf("failed to verify provider package checksums: %s", err)
	}

	if matches {
		return &PackageAuthenticationResult{result: verifiedChecksum}, nil
	}
	if len(a.RequiredHashes) == 1 {
		return nil, fmt.Errorf("provider package doesn't match the expected checksum %q", a.RequiredHashes[0].String())
	}
	// It's non-ideal that this doesn't actually list the expected checksums,
	// but in the many-checksum case the message would get pretty unweildy.
	// In practice today we typically use this authenticator only with a
	// single hash returned from a network mirror, so the better message
	// above will prevail in that case. Maybe we'll improve on this somehow
	// if the future introduction of a new hash scheme causes there to more
	// commonly be multiple hashes.
	return nil, fmt.Errorf("provider package doesn't match the any of the expected checksums")
}

func (a packageHashAuthentication) AcceptableHashes() []Hash {
	// In this case we include even hashes the current version of Terraform
	// doesn't prefer, because this result is used for building a lock file
	// and so it's helpful to include older hash formats that other Terraform
	// versions might need in order to do authentication successfully.
	return a.AllHashes
}

type archiveHashAuthentication struct {
	Platform      Platform
	WantSHA256Sum [sha256.Size]byte
}

// NewArchiveChecksumAuthentication returns a PackageAuthentication
// implementation that checks that the original distribution archive matches
// the given hash.
//
// This authentication is suitable only for PackageHTTPURL and
// PackageLocalArchive source locations, because the unpacked layout
// (represented by PackageLocalDir) does not retain access to the original
// source archive. Therefore this authenticator will return an error if its
// given localLocation is not PackageLocalArchive.
//
// NewPackageHashAuthentication is preferable to use when possible because
// it uses the newer hashing scheme (implemented by function PackageHash) that
// can work with both packed and unpacked provider packages.
func NewArchiveChecksumAuthentication(platform Platform, wantSHA256Sum [sha256.Size]byte) PackageAuthentication {
	return archiveHashAuthentication{platform, wantSHA256Sum}
}

func (a archiveHashAuthentication) AuthenticatePackage(localLocation PackageLocation) (*PackageAuthenticationResult, error) {
	archiveLocation, ok := localLocation.(PackageLocalArchive)
	if !ok {
		// A source should not use this authentication type for non-archive
		// locations.
		return nil, fmt.Errorf("cannot check archive hash for non-archive location %s", localLocation)
	}

	gotHash, err := PackageHashLegacyZipSHA(archiveLocation)
	if err != nil {
		return nil, fmt.Errorf("failed to compute checksum for %s: %s", archiveLocation, err)
	}
	wantHash := HashLegacyZipSHAFromSHA(a.WantSHA256Sum)
	if gotHash != wantHash {
		return nil, fmt.Errorf("archive has incorrect checksum %s (expected %s)", gotHash, wantHash)
	}
	return &PackageAuthenticationResult{result: verifiedChecksum}, nil
}

func (a archiveHashAuthentication) AcceptableHashes() []Hash {
	return []Hash{HashLegacyZipSHAFromSHA(a.WantSHA256Sum)}
}

type matchingChecksumAuthentication struct {
	Document      []byte
	Filename      string
	WantSHA256Sum [sha256.Size]byte
}

// NewMatchingChecksumAuthentication returns a PackageAuthentication
// implementation that scans a registry-provided SHA256SUMS document for a
// specified filename, and compares the SHA256 hash against the expected hash.
// This is necessary to ensure that the signed SHA256SUMS document matches the
// declared SHA256 hash for the package, and therefore that a valid signature
// of this document authenticates the package.
//
// This authentication always returns a nil result, since it alone cannot offer
// any assertions about package integrity. It should be combined with other
// authentications to be useful.
func NewMatchingChecksumAuthentication(document []byte, filename string, wantSHA256Sum [sha256.Size]byte) PackageAuthentication {
	return matchingChecksumAuthentication{
		Document:      document,
		Filename:      filename,
		WantSHA256Sum: wantSHA256Sum,
	}
}

func (m matchingChecksumAuthentication) AuthenticatePackage(location PackageLocation) (*PackageAuthenticationResult, error) {
	// Find the checksum in the list with matching filename. The document is
	// in the form "0123456789abcdef filename.zip".
	filename := []byte(m.Filename)
	var checksum []byte
	for _, line := range bytes.Split(m.Document, []byte("\n")) {
		parts := bytes.Fields(line)
		if len(parts) > 1 && bytes.Equal(parts[1], filename) {
			checksum = parts[0]
			break
		}
	}
	if checksum == nil {
		return nil, fmt.Errorf("checksum list has no SHA-256 hash for %q", m.Filename)
	}

	// Decode the ASCII checksum into a byte array for comparison.
	var gotSHA256Sum [sha256.Size]byte
	if _, err := hex.Decode(gotSHA256Sum[:], checksum); err != nil {
		return nil, fmt.Errorf("checksum list has invalid SHA256 hash %q: %s", string(checksum), err)
	}

	// If the checksums don't match, authentication fails.
	if !bytes.Equal(gotSHA256Sum[:], m.WantSHA256Sum[:]) {
		return nil, fmt.Errorf("checksum list has unexpected SHA-256 hash %x (expected %x)", gotSHA256Sum, m.WantSHA256Sum[:])
	}

	// Success! But this doesn't result in any real authentication, only a
	// lack of authentication errors, so we return a nil result.
	return nil, nil
}

type signatureAuthentication struct {
	Document  []byte
	Signature []byte
	Keys      []SigningKey
}

// NewSignatureAuthentication returns a PackageAuthentication implementation
// that verifies the cryptographic signature for a package against any of the
// provided keys.
//
// The signing key for a package will be auto detected by attempting each key
// in turn until one is successful. If such a key is found, there are three
// possible successful authentication results:
//
// 1. If the signing key is the HashiCorp official key, it is an official
//    provider;
// 2. Otherwise, if the signing key has a trust signature from the HashiCorp
//    Partners key, it is a partner provider;
// 3. If neither of the above is true, it is a community provider.
//
// Any failure in the process of validating the signature will result in an
// unauthenticated result.
func NewSignatureAuthentication(document, signature []byte, keys []SigningKey) PackageAuthentication {
	return signatureAuthentication{
		Document:  document,
		Signature: signature,
		Keys:      keys,
	}
}

func (s signatureAuthentication) AuthenticatePackage(location PackageLocation) (*PackageAuthenticationResult, error) {
	// Find the key that signed the checksum file. This can fail if there is no
	// valid signature for any of the provided keys.
	signingKey, keyID, err := s.findSigningKey()
	if err != nil {
		return nil, err
	}

	// Verify the signature using the HashiCorp public key. If this succeeds,
	// this is an official provider.
	hashicorpKeyring, err := openpgp.ReadArmoredKeyRing(strings.NewReader(HashicorpPublicKey))
	if err != nil {
		return nil, fmt.Errorf("error creating HashiCorp keyring: %s", err)
	}
	_, err = openpgp.CheckDetachedSignature(hashicorpKeyring, bytes.NewReader(s.Document), bytes.NewReader(s.Signature))
	if err == nil {
		return &PackageAuthenticationResult{result: officialProvider, KeyID: keyID}, nil
	}

	// If the signing key has a trust signature, attempt to verify it with the
	// HashiCorp partners public key.
	if signingKey.TrustSignature != "" {
		hashicorpPartnersKeyring, err := openpgp.ReadArmoredKeyRing(strings.NewReader(HashicorpPartnersKey))
		if err != nil {
			return nil, fmt.Errorf("error creating HashiCorp Partners keyring: %s", err)
		}

		authorKey, err := openpgpArmor.Decode(strings.NewReader(signingKey.ASCIIArmor))
		if err != nil {
			return nil, fmt.Errorf("error decoding signing key: %s", err)
		}

		trustSignature, err := openpgpArmor.Decode(strings.NewReader(signingKey.TrustSignature))
		if err != nil {
			return nil, fmt.Errorf("error decoding trust signature: %s", err)
		}

		_, err = openpgp.CheckDetachedSignature(hashicorpPartnersKeyring, authorKey.Body, trustSignature.Body)
		if err != nil {
			return nil, fmt.Errorf("error verifying trust signature: %s", err)
		}

		return &PackageAuthenticationResult{result: partnerProvider, KeyID: keyID}, nil
	}

	// We have a valid signature, but it's not from the HashiCorp key, and it
	// also isn't a trusted partner. This is a community provider.
	return &PackageAuthenticationResult{result: communityProvider, KeyID: keyID}, nil
}

func (s signatureAuthentication) AcceptableHashes() []Hash {
	// This is a bit of an abstraction leak because signatureAuthentication
	// otherwise just treats the document as an opaque blob that's been
	// signed, but here we're making assumptions about its format because
	// we only want to trust that _all_ of the checksums are valid (rather
	// than just the current platform's one) if we've also verified that the
	// bag of checksums is signed.
	//
	// In recognition of that layering quirk this implementation is intended to
	// be somewhat resilient to potentially using this authenticator with
	// non-checksums files in future (in which case it'll return nothing at all)
	// but it might be better in the long run to instead combine
	// signatureAuthentication and matchingChecksumAuthentication together and
	// be explicit that the resulting merged authenticator is exclusively for
	// checksums files.

	var ret []Hash
	sc := bufio.NewScanner(bytes.NewReader(s.Document))
	for sc.Scan() {
		parts := bytes.Fields(sc.Bytes())
		if len(parts) != 0 && len(parts) < 2 {
			// Doesn't look like a valid sums file line, so we'll assume
			// this whole thing isn't a checksums file.
			return nil
		}

		// If this is a checksums file then the first part should be a
		// hex-encoded SHA256 hash, so it should be 64 characters long
		// and contain only hex digits.
		hashStr := parts[0]
		if len(hashStr) != 64 {
			return nil // doesn't look like a checksums file
		}

		var gotSHA256Sum [sha256.Size]byte
		if _, err := hex.Decode(gotSHA256Sum[:], hashStr); err != nil {
			return nil // doesn't look like a checksums file
		}

		ret = append(ret, HashLegacyZipSHAFromSHA(gotSHA256Sum))
	}

	return ret
}

// findSigningKey attempts to verify the signature using each of the keys
// returned by the registry. If a valid signature is found, it returns the
// signing key.
//
// Note: currently the registry only returns one key, but this may change in
// the future.
func (s signatureAuthentication) findSigningKey() (*SigningKey, string, error) {
	for _, key := range s.Keys {
		keyring, err := openpgp.ReadArmoredKeyRing(strings.NewReader(key.ASCIIArmor))
		if err != nil {
			return nil, "", fmt.Errorf("error decoding signing key: %s", err)
		}

		entity, err := openpgp.CheckDetachedSignature(keyring, bytes.NewReader(s.Document), bytes.NewReader(s.Signature))

		// If the signature issuer does not match the the key, keep trying the
		// rest of the provided keys.
		if err == openpgpErrors.ErrUnknownIssuer {
			continue
		}

		// Any other signature error is terminal.
		if err != nil {
			return nil, "", fmt.Errorf("error checking signature: %s", err)
		}

		keyID := "n/a"
		if entity.PrimaryKey != nil {
			keyID = entity.PrimaryKey.KeyIdString()
		}

		log.Printf("[DEBUG] Provider signed by %s", entityString(entity))
		return &key, keyID, nil
	}

	// If none of the provided keys issued the signature, this package is
	// unsigned. This is currently a terminal authentication error.
	return nil, "", fmt.Errorf("authentication signature from unknown issuer")
}

// entityString extracts the key ID and identity name(s) from an openpgp.Entity
// for logging.
func entityString(entity *openpgp.Entity) string {
	if entity == nil {
		return ""
	}

	keyID := "n/a"
	if entity.PrimaryKey != nil {
		keyID = entity.PrimaryKey.KeyIdString()
	}

	var names []string
	for _, identity := range entity.Identities {
		names = append(names, identity.Name)
	}

	return fmt.Sprintf("%s %s", keyID, strings.Join(names, ", "))
}
