Documentation
¶
Overview ¶
Package local is the on-disk PEM-encoded RSA private key backend for pkg/signing. Blank-import to activate; the init() call registers the backend under the name "local" against pkg/signing's global registry.
import _ "gitlab.com/phpboyscout/signing/local"
The backend reads a PEM file from disk (path supplied via the command-line --key-id) and returns its *rsa.PrivateKey as a crypto.Signer. Pairs with `gtb keys generate --algorithm rsa` for the tutorial / no-cloud-KMS path — the generate command produces a PEM private half that this backend consumes.
Supported PEM formats:
- Unencrypted PKCS#1 RSA private key (header "-----BEGIN RSA PRIVATE KEY-----").
- Unencrypted PKCS#8 (header "-----BEGIN PRIVATE KEY-----").
Encrypted-PKCS#8 PEMs are not supported in v0.1 — the standard library does not expose PKCS#8 decryption. Operators who need at-rest encryption should either use the aws-kms backend (recommended for production) or encrypt the PEM file at the filesystem layer (LUKS, FileVault, age). Adding encrypted-PKCS#8 support is additive and slated for v0.2 if a real consumer asks.
Non-RSA keys in the PEM file are rejected — Ed25519 / ECDSA in PEM flowing through this backend is unsupported in v0.1 (the only consumer is `gtb keys mint`, which currently only mints RSA via this path).
Example ¶
Example shows the signing side using the registered "local" PEM backend: a front-end resolves a crypto.Signer by backend name, signs a manifest, and the result verifies. A custom backend (KMS/HSM) is a drop-in replacement — implement signing.Backend and blank-import it instead.
package main
import (
"bytes"
"context"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"os"
"path/filepath"
"time"
"gitlab.com/phpboyscout/signing"
_ "gitlab.com/phpboyscout/signing/local"
"gitlab.com/phpboyscout/signing/openpgpkey"
"gitlab.com/phpboyscout/signing/verify"
)
func main() {
// Write a PKCS#8 RSA key the local backend can read (in real use this is
// provisioned out of band).
priv, _ := rsa.GenerateKey(rand.Reader, 3072)
der, _ := x509.MarshalPKCS8PrivateKey(priv)
path := filepath.Join(os.TempDir(), "signing-local-example.pem")
_ = os.WriteFile(path, pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: der}), 0o600)
defer func() { _ = os.Remove(path) }()
// Resolve a signer through the registry by backend name; keyID is the PEM
// path for "local" (an ARN/alias for a KMS backend, etc.).
backend, _ := signing.Get("local")
signer, _ := backend.NewSigner(context.Background(), path)
now := time.Unix(0, 0)
pub, _ := openpgpkey.ArmoredPublicKey(signer, "Release", "release@example.test", now)
manifest := []byte("sha256 artifact.bin 0xc0ffee\n")
sig, _ := openpgpkey.DetachSign(signer, pub, bytes.NewReader(manifest), now)
trust, _ := verify.LoadTrustSet(pub)
fmt.Println("verified:", trust.VerifyManifestSignature(manifest, sig) == nil)
}
Output: verified: true
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrUnsupportedKeyType is returned when the PEM file contains // a non-RSA key (Ed25519, ECDSA, etc.). v0.1 only supports RSA // via the local backend. ErrUnsupportedKeyType = errors.New("PEM key is not RSA; only RSA private keys are supported") // ErrMissingPEMBlock is returned when the file decodes to zero // PEM blocks (e.g. the file is empty or contains only comments). ErrMissingPEMBlock = errors.New("no PEM block found in file") // ErrEncryptedPEMUnsupported is returned when the PEM block is // encrypted — the standard library does not expose a clean PKCS#8 // decryption path. v0.1 operators who need encryption use the // aws-kms backend or filesystem-level encryption. ErrEncryptedPEMUnsupported = errors.New("encrypted PEM private keys are not supported in v0.1; decrypt out-of-band first or use the aws-kms backend") )
Exported sentinel errors so callers (and tests) can errors.Is against specific failure modes.
Functions ¶
Types ¶
This section is empty.