Ctrl K
ComunidadGuías…

bldr/util/gocompiler/sign-windows.go

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package gocompiler

import (
	"context"
	"os"
	"path/filepath"
	"sync"

	uexec "github.com/aperturerobotics/util/exec"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

// WindowsSignProfileEnv is the env var holding the Trusted Signing
// certificate profile name (Invoke-TrustedSigning -CertificateProfileName).
// When neither this nor WindowsSignCommandEnv is set, SignWindows is a no-op.
const WindowsSignProfileEnv = "BLDR_WINDOWS_SIGN_PROFILE"

// WindowsSignCommandEnv selects an executable that signs one absolute file path
// in place before Bldr commits its manifest. The command is invoked without a
// shell and must return only after signing and verifying the file.
const WindowsSignCommandEnv = "BLDR_WINDOWS_SIGN_COMMAND"

// WindowsSignIdentityEnv identifies the external command's product and publisher
// policy for build caching. Change it when the selected signing identity changes.
const WindowsSignIdentityEnv = "BLDR_WINDOWS_SIGN_IDENTITY"

// WindowsSignAccountEnv is the env var holding the Trusted Signing signing
// account name (Invoke-TrustedSigning -CodeSigningAccountName).
const WindowsSignAccountEnv = "BLDR_WINDOWS_SIGN_ACCOUNT"

// WindowsSignEndpointEnv is the env var holding the regional Trusted
// Signing endpoint URL, e.g. https://wus.codesigning.azure.net/
// (Invoke-TrustedSigning -Endpoint). Defaults to defaultWindowsSignEndpoint
// when unset.
const WindowsSignEndpointEnv = "BLDR_WINDOWS_SIGN_ENDPOINT"

// defaultWindowsSignEndpoint is the default Trusted Signing endpoint when
// WindowsSignEndpointEnv is unset. West US 2 is where our signing account
// lives; override via env for accounts in other regions.
const defaultWindowsSignEndpoint = "https://wus.codesigning.azure.net/"

// WindowsSignDescriptionEnv is the env var holding the Authenticode
// signature description (Invoke-TrustedSigning -Description). Defaults
// to "Spacewave" when unset.
const WindowsSignDescriptionEnv = "BLDR_WINDOWS_SIGN_DESCRIPTION"

// defaultWindowsSignDescription is the default Authenticode description
// when WindowsSignDescriptionEnv is unset.
const defaultWindowsSignDescription = "Spacewave"

// signWindowsMu serializes access to the module's shared metadata file.
var signWindowsMu sync.Mutex

// signWindowsScript is the PowerShell script driving the signing call.
// Values flow in via env vars to avoid PowerShell quoting hazards.
const signWindowsScript = `$ErrorActionPreference = 'Stop'
Invoke-TrustedSigning ` +
	`-Endpoint $env:BLDR_SIGN_ENDPOINT ` +
	`-CodeSigningAccountName $env:BLDR_SIGN_ACCOUNT ` +
	`-CertificateProfileName $env:BLDR_SIGN_PROFILE ` +
	`-Files $env:BLDR_SIGN_FILE ` +
	`-Description $env:BLDR_SIGN_DESCRIPTION ` +
	`-FileDigest SHA256 ` +
	`-TimestampRfc3161 'http://timestamp.acs.microsoft.com' ` +
	`-TimestampDigest SHA256 ` +
	`-ExcludeManagedIdentityCredential ` +
	`-ExcludeSharedTokenCacheCredential ` +
	`-ExcludeVisualStudioCredential ` +
	`-ExcludeVisualStudioCodeCredential ` +
	`-ExcludeAzurePowerShellCredential ` +
	`-ExcludeAzureDeveloperCliCredential ` +
	`-ExcludeInteractiveBrowserCredential`

// WindowsSignStartupCacheEnvKeys returns the configuration that changes signed
// executable identity, including the explicit unsigned configuration.
func WindowsSignStartupCacheEnvKeys() []string {
	return []string{
		WindowsSignCommandEnv,
		WindowsSignIdentityEnv,
		WindowsSignProfileEnv,
		WindowsSignAccountEnv,
		WindowsSignEndpointEnv,
		WindowsSignDescriptionEnv,
	}
}

// SignWindows signs a PE binary through an external command or Azure Artifact
// Signing. External commands support signing a cross-build through a remote job.
//
// For direct Azure signing, the TrustedSigning module must be installed on the host
// (Install-Module -Name TrustedSigning). Authentication uses
// environment, workload identity, or a prior az login (azure/login@v3 in CI).
// Developer-tool and interactive credentials are excluded for unattended builds.
//
// No-op when both signing options are unset. The caller gates on GOOS=windows.
func SignWindows(ctx context.Context, le *logrus.Entry, binPath string) error {
	// A remote signer retains its own credentials and verifies the returned bytes.
	command := os.Getenv(WindowsSignCommandEnv)
	if command != "" {
		if os.Getenv(WindowsSignProfileEnv) != "" {
			return errors.New("select either a Windows signing command or an Azure profile")
		}
		if os.Getenv(WindowsSignIdentityEnv) == "" {
			return errors.Errorf("%s requires %s for build caching", WindowsSignCommandEnv, WindowsSignIdentityEnv)
		}
		absolute, err := filepath.Abs(binPath)
		if err != nil {
			return err
		}
		return errors.Wrap(uexec.ExecCmd(le, uexec.NewCmd(ctx, command, absolute)), "sign windows executable")
	}

	// Resolve the optional signing configuration before starting PowerShell.
	profile := os.Getenv(WindowsSignProfileEnv)
	if profile == "" {
		return nil
	}
	account := os.Getenv(WindowsSignAccountEnv)
	if account == "" {
		return errors.Errorf("%s is set but %s is not", WindowsSignProfileEnv, WindowsSignAccountEnv)
	}
	endpoint := os.Getenv(WindowsSignEndpointEnv)
	if endpoint == "" {
		endpoint = defaultWindowsSignEndpoint
	}
	description := os.Getenv(WindowsSignDescriptionEnv)
	if description == "" {
		description = defaultWindowsSignDescription
	}

	// Keep values out of command syntax and disable interactive credentials.
	cmd := uexec.NewCmd(ctx, "pwsh", "-NoProfile", "-NonInteractive", "-Command", signWindowsScript)
	cmd.Env = append(os.Environ(),
		"BLDR_SIGN_ENDPOINT="+endpoint,
		"BLDR_SIGN_ACCOUNT="+account,
		"BLDR_SIGN_PROFILE="+profile,
		"BLDR_SIGN_FILE="+binPath,
		"BLDR_SIGN_DESCRIPTION="+description,
	)

	// The PowerShell module writes one shared metadata file for every binary.
	signWindowsMu.Lock()
	defer signWindowsMu.Unlock()
	if err := uexec.ExecCmd(le, cmd); err != nil {
		return errors.Wrapf(err, "Invoke-TrustedSigning (profile=%q, account=%q)", profile, account)
	}
	le.WithField("profile", profile).WithField("bin", binPath).Info("signed windows binary")
	return nil
}