Repository: microsoft/CBL-Mariner
File: toolkit/tools/internal/rpm/rpm.go (Go)

Code before:
	}

	return
}

// InstallRPM installs the given RPM or SRPM
func InstallRPM(rpmFile string) (err error) {
	const installOption = "-ihv"

	logger.Log.Debugf("Installing RPM (%s)", rpmFile)

	_, stderr, err := shell.Execute(rpmProgram, installOption, rpmFile)
	if err != nil {
		err = fmt.Errorf("%v\n%w", stderr, err)
	}

	return
}

const rpmKeysProgram = "rpmkeys"

// ImportGpgKeysToRpmDb imports GPG keys into an RPM database for signature verification.
// - rpmDbRoot: path to a directory to use as the RPM database root (will be created if it doesn't exist)
// - gpgKeyPaths: paths to GPG key files to import into the RPM database
// This should be called once before validating multiple RPMs with CheckRpmSignature.
func ImportGpgKeysToRpmDb(rpmDbRoot string, gpgKeyPaths []string) (err error) {
	if _, err := exec.LookPath(rpmKeysProgram); err != nil {
		return fmt.Errorf("%s command not found - explicit GPG signature enforcement requires this tool", rpmKeysProgram)
	}
	for _, keyPath := range gpgKeyPaths {
		_, stderr, importErr := shell.Execute(rpmKeysProgram, "--root", rpmDbRoot, "--import", keyPath)
		if importErr != nil {
			return fmt.Errorf("failed to import GPG key (%s) into RPM database:\n%v\n%w", keyPath, stderr, importErr)
		}
	}
	return nil
}

// CheckRpmSignature validates the GPG signature of an RPM file.
// - rpmFile: path to the RPM file to validate
// - rpmDbRoot: path to a directory used as the RPM database root (must have GPG keys already imported via ImportGpgKeysToRpmDb)
// Returns an error if the RPM signature is missing or invalid.
func CheckRpmSignature(rpmFile string, rpmDbRoot string) (err error) {
	_, stderr, err := shell.Execute(rpmKeysProgram, "--root", rpmDbRoot, "--checksig", rpmFile, "-D", "%_pkgverify_level signature")
	if err != nil {
		return fmt.Errorf("RPM signature validation failed for (%s):\n%v\n%w", rpmFile, stderr, err)
	}
	return nil
}

// ValidateDirectoryRpmSignatures validates the GPG signatures of all RPM files in a directory.

Review comment (suggestion):
Naming nit-pick:

```suggestion
func ImportGPGKeysToRPMDb(rpmDbRoot string, gpgKeyPaths []string) (err error) {
```

Code after:
	}

	return
}

// InstallRPM installs the given RPM or SRPM
func InstallRPM(rpmFile string) (err error) {
	const installOption = "-ihv"

	logger.Log.Debugf("Installing RPM (%s)", rpmFile)

	_, stderr, err := shell.Execute(rpmProgram, installOption, rpmFile)
	if err != nil {
		err = fmt.Errorf("%v\n%w", stderr, err)
	}

	return
}

const rpmKeysProgram = "rpmkeys"

// importGPGKeysToRPMDb imports GPG keys into an RPM database for signature verification.
// - rpmDbRoot: path to a directory to use as the RPM database root (will be created if it doesn't exist)
// - gpgKeyPaths: paths to GPG key files to import into the RPM database
// This should be called once before validating multiple RPMs with checkRPMSignature.
func importGPGKeysToRPMDb(rpmDbRoot string, gpgKeyPaths []string) (err error) {
	if _, err := exec.LookPath(rpmKeysProgram); err != nil {
		return fmt.Errorf("%s command not found - explicit GPG signature enforcement requires this tool:\n%w", rpmKeysProgram, err)
	}
	for _, keyPath := range gpgKeyPaths {
		_, stderr, importErr := shell.Execute(rpmKeysProgram, "--root", rpmDbRoot, "--import", keyPath)
		if importErr != nil {
			return fmt.Errorf("failed to import GPG key (%s) into RPM database: %v:\n%w", keyPath, stderr, importErr)
		}
	}
	return nil
}

// checkRPMSignature validates the GPG signature of an RPM file.
// - rpmFile: path to the RPM file to validate
// - rpmDbRoot: path to a directory used as the RPM database root (must have GPG keys already imported via importGPGKeysToRpmDb)
// Returns an error if the RPM signature is missing or invalid.
func checkRPMSignature(rpmFile string, rpmDbRoot string) (err error) {
	_, stderr, err := shell.Execute(rpmKeysProgram, "--root", rpmDbRoot, "--checksig", rpmFile, "-D", "%_pkgverify_level signature")
	if err != nil {
		return fmt.Errorf("RPM signature validation failed for (%s): %v\n%w", rpmFile, stderr, err)
	}
	return nil
}

// ValidateDirectoryRPMSignatures validates the GPG signatures of all RPM files in a directory.