certstore

package
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 15, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Overview

Package certstore provides a shared certificate and key processing pipeline used by both the CLI and WASM builds. It is intentionally free of SQLite dependencies so it can compile to js/wasm.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExportMatchedBundles

func ExportMatchedBundles(ctx context.Context, input ExportMatchedBundleInput) error

ExportMatchedBundles builds certificate chains and writes bundle files for each matched key-cert pair. This is the shared orchestration used by both CLI and WASM exports.

func FormatCN

func FormatCN(cert *x509.Certificate) string

FormatCN returns the common name of the certificate for display. Falls back to the first DNS SAN, then to "serial:<hex>" if no CN or SAN is present.

func FormatIPAddresses

func FormatIPAddresses(ips []net.IP) []string

FormatIPAddresses converts IP addresses to their string representations.

func GenerateCSR

func GenerateCSR(leaf *x509.Certificate, keyPEM []byte, subject *CSRSubjectOverride) (csrPEM []byte, csrJSON []byte, err error)

GenerateCSR creates a CSR using the certificate's details and private key. The subject parameter optionally overrides the certificate's subject fields.

func GenerateJSON

func GenerateJSON(bundle *certkit.BundleResult) ([]byte, error)

GenerateJSON creates a JSON representation of the certificate bundle. The PEM field contains leaf + intermediates only (no root).

func GenerateYAML

func GenerateYAML(bundle *certkit.BundleResult, keyPEM []byte, keyType string, bitLength int) ([]byte, error)

GenerateYAML creates a YAML representation of the certificate bundle.

func GetKeyType

func GetKeyType(cert *x509.Certificate) string

GetKeyType returns a human-readable description of the certificate's public key type, including bit length for RSA and curve name for ECDSA.

func HasBinaryExtension

func HasBinaryExtension(path string) bool

HasBinaryExtension reports whether the file path has a recognized DER or JKS extension. The extension is matched case-insensitively. For virtual paths containing a ":" separator (e.g., "archive.zip:certs/server.p12"), the extension is extracted from the portion after the last ":" to avoid filepath.Ext misinterpreting the archive path component.

func LoadFromSQLite

func LoadFromSQLite(store *MemStore, dbPath string) error

LoadFromSQLite opens a SQLite database file and copies its certificates and keys into the given MemStore.

func ProcessData

func ProcessData(input ProcessInput) error

ProcessData ingests certificates and keys from in-memory data, dispatching parsed objects to the handler. It detects PEM vs binary format and tries all known crypto formats in priority order. All certificates are ingested regardless of expiry — expired filtering is an output concern.

func ResolveAIA

func ResolveAIA(ctx context.Context, input ResolveAIAInput) []string

ResolveAIA walks AIA CA Issuers URLs for all non-root certificates in the store, fetching any missing intermediate issuers. Certificates whose issuer is already in the store or is a Mozilla root are skipped.

Returns warnings for fetch/parse failures. Callers should surface these to the user.

func SanitizeFileName

func SanitizeFileName(name string) string

SanitizeFileName replaces wildcards and other unsafe characters for file and ZIP entry paths.

func SaveToSQLite

func SaveToSQLite(store *MemStore, dbPath string) error

SaveToSQLite writes the contents of a MemStore to a SQLite database file.

Types

type AIAFetcher

type AIAFetcher func(ctx context.Context, url string) ([]byte, error)

AIAFetcher fetches raw certificate bytes from a URL. Implementations handle transport details: CLI uses net/http, WASM delegates to JavaScript fetch.

type BundleExportInput

type BundleExportInput struct {
	Bundle     *certkit.BundleResult
	KeyPEM     []byte
	KeyType    string
	BitLength  int
	Prefix     string              // sanitized file name prefix
	SecretName string              // Kubernetes secret metadata.name
	CSRSubject *CSRSubjectOverride // optional; nil uses cert's own subject
}

BundleExportInput holds parameters for GenerateBundleFiles.

type BundleFile

type BundleFile struct {
	Name      string
	Data      []byte
	Sensitive bool // true for files containing private key material (mode 0600)
}

BundleFile represents a single output file in a bundle export.

func GenerateBundleFiles

func GenerateBundleFiles(input BundleExportInput) ([]BundleFile, error)

GenerateBundleFiles creates all output files for a certificate bundle. The returned files include PEM variants, private key, PKCS#12, Kubernetes TLS secret, JSON, YAML, CSR, and CSR JSON. Conditional files (intermediates, root) are only included when the corresponding certificates exist.

type BundleWriter

type BundleWriter interface {
	WriteBundleFiles(folder string, files []BundleFile) error
}

BundleWriter receives generated bundle files for output. CLI writes to the filesystem; WASM writes to a ZIP archive.

type CSRSubjectOverride

type CSRSubjectOverride struct {
	Country            []string
	Province           []string
	Locality           []string
	Organization       []string
	OrganizationalUnit []string
}

CSRSubjectOverride allows overriding X.509 subject fields for CSR generation. If nil is passed to GenerateBundleFiles, the certificate's own subject fields are used.

type CertHandler

type CertHandler interface {
	HandleCertificate(cert *x509.Certificate, source string) error
	HandleKey(key any, pemData []byte, source string) error
}

CertHandler receives parsed certificates and keys from the processing pipeline.

type CertRecord

type CertRecord struct {
	Cert       *x509.Certificate
	SKI        string // hex-encoded RFC 7093 SKI
	CertType   string // "root", "intermediate", "leaf"
	KeyType    string // e.g. "RSA 2048 bits", "ECDSA P-256"
	NotAfter   time.Time
	NotBefore  time.Time
	Source     string // filename that contributed this cert
	BundleName string // determined by CLI bundle config matching
}

CertRecord holds a parsed certificate and its computed metadata.

type ContainerContents

type ContainerContents struct {
	Leaf       *x509.Certificate
	Key        crypto.PrivateKey
	ExtraCerts []*x509.Certificate
}

ContainerContents holds the parsed contents of a certificate container file.

func ParseContainerData

func ParseContainerData(data []byte, passwords []string) (*ContainerContents, error)

ParseContainerData attempts to parse raw data as PKCS#12, JKS, PKCS#7, PEM, or DER. Returns the leaf certificate, optional private key, and any extra certificates.

type ExportMatchedBundleInput

type ExportMatchedBundleInput struct {
	Store         *MemStore
	SKIs          []string // matched-pair SKIs to export
	BundleOpts    certkit.BundleOptions
	Writer        BundleWriter
	CSRSubject    *CSRSubjectOverride // optional; nil uses cert's own subject
	RetryNoVerify bool                // retry bundle without verification on failure
}

ExportMatchedBundleInput holds parameters for ExportMatchedBundles.

type K8sMetadata

type K8sMetadata struct {
	Name        string            `yaml:"name"`
	Annotations map[string]string `yaml:"annotations,omitempty"`
}

K8sMetadata represents Kubernetes resource metadata.

type K8sSecret

type K8sSecret struct {
	APIVersion string            `yaml:"apiVersion"`
	Kind       string            `yaml:"kind"`
	Type       string            `yaml:"type"`
	Metadata   K8sMetadata       `yaml:"metadata"`
	Data       map[string]string `yaml:"data"`
}

K8sSecret represents a Kubernetes TLS secret.

type KeyRecord

type KeyRecord struct {
	Key       crypto.PrivateKey
	SKI       string // hex-encoded RFC 7093 SKI
	KeyType   string // "RSA", "ECDSA", "Ed25519"
	BitLength int
	PEM       []byte // PEM-encoded key data for export
	Source    string // filename that contributed this key
}

KeyRecord holds a parsed private key and its computed metadata.

type MemStore

type MemStore struct {
	// contains filtered or unexported fields
}

MemStore is an in-memory certificate and key store that implements CertHandler. It is used by both CLI and WASM builds.

func NewMemStore

func NewMemStore() *MemStore

NewMemStore creates an empty MemStore.

func (*MemStore) AllCerts

func (s *MemStore) AllCerts() map[string]*CertRecord

AllCerts returns a map of the latest-expiring certificate per SKI. This preserves backward compatibility with WASM code that iterates by SKI.

func (*MemStore) AllCertsFlat

func (s *MemStore) AllCertsFlat() []*CertRecord

AllCertsFlat returns all certificate records as a flat slice.

func (*MemStore) AllKeys

func (s *MemStore) AllKeys() map[string]*KeyRecord

AllKeys returns a snapshot of all key records keyed by SKI.

func (*MemStore) AllKeysFlat

func (s *MemStore) AllKeysFlat() []*KeyRecord

AllKeysFlat returns all key records as a flat slice.

func (*MemStore) BundleNames

func (s *MemStore) BundleNames() []string

BundleNames returns unique bundle names that have at least one certificate with a matching key in the store. Empty bundle names are excluded.

func (*MemStore) CertsByBundleName

func (s *MemStore) CertsByBundleName(name string) []*CertRecord

CertsByBundleName returns all certificates with the given bundle name, sorted by NotAfter descending (newest first).

func (*MemStore) DumpDebug

func (s *MemStore) DumpDebug()

DumpDebug logs all certificates and keys at debug level.

func (*MemStore) GetCert

func (s *MemStore) GetCert(ski string) *CertRecord

GetCert returns the certificate record with the latest NotAfter for the given SKI, or nil if not found. This preserves backward compatibility with callers that expect a single cert per SKI.

func (*MemStore) GetKey

func (s *MemStore) GetKey(ski string) *KeyRecord

GetKey returns the key record for the given SKI, or nil.

func (*MemStore) HandleCertificate

func (s *MemStore) HandleCertificate(cert *x509.Certificate, source string) error

HandleCertificate computes the SKI and stores the certificate. Certificates are deduplicated by (serial, AKI) — the same composite key the SQLite schema uses. Multiple certificates with the same SKI but different serials (key reuse across renewals) are all retained.

func (*MemStore) HandleKey

func (s *MemStore) HandleKey(key any, pemData []byte, source string) error

HandleKey computes the SKI and stores the private key with its PEM encoding.

func (*MemStore) HasIssuer

func (s *MemStore) HasIssuer(cert *x509.Certificate) bool

HasIssuer reports whether the store contains the issuer for the given cert, by comparing raw ASN.1 subject/issuer bytes.

func (*MemStore) IntermediatePool

func (s *MemStore) IntermediatePool() *x509.CertPool

IntermediatePool returns an x509.CertPool containing all intermediate certificates in the store. Useful for chain verification.

func (*MemStore) Intermediates

func (s *MemStore) Intermediates() []*x509.Certificate

Intermediates returns all intermediate certificates in the store.

func (*MemStore) MatchedPairs

func (s *MemStore) MatchedPairs() []string

MatchedPairs returns SKIs that have both a leaf certificate and a key.

func (*MemStore) Reset

func (s *MemStore) Reset()

Reset clears all stored certificates and keys.

func (*MemStore) ScanSummary

func (s *MemStore) ScanSummary() ScanSummary

ScanSummary returns aggregate counts of stored certificates and keys.

func (*MemStore) SetBundleName

func (s *MemStore) SetBundleName(ski, name string)

SetBundleName sets the bundle name on all certificates matching the given SKI.

type ProcessInput

type ProcessInput struct {
	Data      []byte      // raw file content
	Path      string      // virtual path for logging and extension detection
	Passwords []string    // passwords to try for encrypted formats
	Handler   CertHandler // receives parsed items
}

ProcessInput holds parameters for ProcessData.

type ResolveAIAInput

type ResolveAIAInput struct {
	Store    *MemStore
	Fetch    AIAFetcher
	MaxDepth int // 0 defaults to 5
}

ResolveAIAInput holds parameters for ResolveAIA.

type ScanSummary

type ScanSummary struct {
	Roots         int `json:"roots"`
	Intermediates int `json:"intermediates"`
	Leaves        int `json:"leaves"`
	Keys          int `json:"keys"`
	Matched       int `json:"key_cert_pairs"`
}

ScanSummary holds aggregate counts from a scan operation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL