Documentation
¶
Overview ¶
Package signing provides package signing infrastructure for YAP.
This package establishes the foundation for signing packages across all supported formats (APK, DEB, RPM, Pacman). It defines the Signer interface, signing configuration, and resolution logic for keys and passphrases.
Signing implementations are provided for APK (RSA PKCS#1 v1.5 SHA1) and DEB/RPM/Pacman (OpenPGP).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SignerName ¶ added in v2.3.3
SignerName extracts a human-readable identity (e.g. "Fedora Project <[email protected]>" or "Ubuntu Archive Automatic Signing Key (2018) <[email protected]>") from a verified OpenPGP entity, or returns the hex key ID when no UID is present. Shared by the apt and rpm repository/package verifiers.
Types ¶
type Config ¶
type Config struct {
// Enabled indicates whether signing is active.
Enabled bool
// KeyPath is the resolved absolute path to the private key
// (PEM format for RSA, ASCII-armored for GPG).
KeyPath string
// Passphrase is the resolved passphrase, may be empty.
// Use Config.String() / %v formatters never expose this field.
Passphrase string
// KeyName is optional, used for APK key naming (e.g., "mykey").
KeyName string
}
Config holds resolved signing configuration for a build.
func Resolve ¶
Resolve produces a final Config for a given Format, applying the priority: CLI flag > environment variable > project config > ~/.config/yap/keys/ default.
For keys, the resolution order is:
- flagKey (CLI --sign-key)
- YAP_<FORMAT>_KEY env var (e.g., YAP_DEB_KEY)
- YAP_SIGN_KEY env var
- configKey (from yap.json signing.keyPath)
- Default search in ~/.config/yap/keys/
For passphrases, the resolution order is:
- flagPass (CLI --sign-passphrase)
- YAP_<FORMAT>_PASSPHRASE env var (e.g., YAP_DEB_PASSPHRASE)
- YAP_SIGN_PASSPHRASE env var
- configPass (from yap.json signing.passphrase)
- Empty string (no passphrase)
If signing is requested but no key can be resolved, an error is returned. If no key is found, signing is disabled and passphrase is cleared.
func ResolveGeneric ¶
ResolveGeneric produces a final Config without format-specific resolution. This is used at the project level where the actual artifact format is not yet known. Format-specific resolution happens later in signArtifact() for each artifact.
For keys, the resolution order is:
- flagKey (CLI --sign-key)
- YAP_SIGN_KEY env var (global only, no format-specific vars)
- configKey (from yap.json signing.keyPath)
- Default search in ~/.config/yap/keys/ (tries both default.rsa and default.gpg)
For passphrases, the resolution order is:
- flagPass (CLI --sign-passphrase)
- YAP_SIGN_PASSPHRASE env var (global only, no format-specific vars)
- configPass (from yap.json signing.passphrase)
- Empty string (no passphrase)
If no key is found, signing is disabled and passphrase is cleared.
func (*Config) Clear ¶ added in v2.0.5
func (c *Config) Clear()
Clear zeroes sensitive fields on the Config and marks signing disabled. Call after signing completes to drop the passphrase reference promptly. The underlying string memory cannot be zeroed (Go strings are immutable), but dropping the reference reduces the window in which the passphrase remains reachable from goroutine stacks and pinned closures.
type Format ¶
type Format string
Format identifies a package format that needs signing.
const ( // FormatAPK represents Alpine Linux APK packages. FormatAPK Format = "apk" // FormatDEB represents Debian packages. FormatDEB Format = "deb" // FormatRPM represents Red Hat RPM packages. FormatRPM Format = "rpm" // FormatPacman represents Arch Linux Pacman packages. FormatPacman Format = "pacman" )
type GPGSigner ¶
type GPGSigner struct {
// contains filtered or unexported fields
}
GPGSigner produces detached OpenPGP signatures for DEB, RPM, and Pacman formats. - DEB: writes <package>.deb.asc (ASCII-armored detached signature) - RPM: provides signing function for rpmpack.SetPGPSigner (binary signature) - Pacman: writes <package>.pkg.tar.zst.sig (binary detached signature)
func NewGPGSigner ¶
NewGPGSigner loads the private key from cfg.KeyPath. The key must be an ASCII-armored OpenPGP private key. If cfg.Passphrase is set, it is used to decrypt the key.
type NoopSigner ¶
type NoopSigner struct{}
NoopSigner is returned when signing is disabled. It implements Signer but performs no operation.
type RSASigner ¶
type RSASigner struct {
// contains filtered or unexported fields
}
RSASigner signs APK packages with PKCS#1 v1.5 SHA1, matching Alpine abuild-sign. The signature is computed over the control.tar.gz bytes and prepended as a third gzip stream in the final APK file.
func NewRSASigner ¶
NewRSASigner loads the private key from cfg.KeyPath. The key must be a PEM-encoded RSA private key (PKCS#1 or PKCS#8 unencrypted).
Encrypted PEM blocks (RFC 1423) are not supported because the underlying stdlib helpers (x509.IsEncryptedPEMBlock, x509.DecryptPEMBlock) are deprecated and the format is cryptographically broken. Users with password-protected keys should re-encode them as unencrypted PEM (e.g. via openssl rsa) or use PKCS#8 without password.
func (*RSASigner) Sign ¶
Sign reads the APK at artifactPath, computes the RSA signature over the control.tar.gz stream, and rewrites the APK with the signature stream prepended.
The final APK structure is:
- signature.tar.gz — contains .SIGN.RSA.<keyname>.rsa.pub with signature bytes
- control.tar.gz — unchanged from original
- data.tar.gz — unchanged from original
The signature is computed as PKCS#1 v1.5 SHA1(control.tar.gz bytes).
type Signer ¶
type Signer interface {
// Sign signs the artifact at artifactPath.
Sign(ctx context.Context, artifactPath string) error
}
Signer signs a package artifact in place or writes a detached signature. Concrete implementations live in this package (RSA for APK, GPG for others).
The behavior depends on the format:
- APK: rebuilds the package with a third concatenated gzip stream containing .SIGN.RSA.<keyname>.rsa.pub
- DEB: appends _gpgorigin to the ar archive (dpkg-sig style)
- RPM: writes signature into the RPM lead/header (delegated to rpmpack)
- Pacman: writes detached <artifactPath>.sig