Help us shape the future of Go! Take the 2026 Go Developer Survey

certutil

package
v1.0.316 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2026 License: Apache-2.0 Imports: 38 Imported by: 9

Documentation

Overview

Package certutil provides utilities to work with certificates.

A Bundler builds and verifies certificate chains. It trusts only the roots it is given, plus the platform trust store when WithSystemRoots(true) is set; without trust roots it defaults to Force, which checks signatures only. AIA downloads (WithAIA) are bounded by the WithHTTPClient timeout and the context given to BundleContext. One Bundler can be shared by goroutines; intermediates it learns over AIA are reused by later calls:

b, err := certutil.NewBundler(nil, intermediates,
	certutil.WithSystemRoots(true),
	certutil.WithAIA(true),
)
if err != nil {
	return err
}
chain, err := b.BundleContext(ctx, []*x509.Certificate{leaf}, nil)

Index

Constants

View Source
const (
	BundleExpiringBit      int = 1 << iota // 0x01
	BundleNotUbiquitousBit                 // 0x02
)

Warning code for a success

Variables

View Source
var ErrNoCertificates = errors.New("no certificates")

ErrNoCertificates is returned, wrapped, when a Bundler or BuildBundle is given no certificate to bundle.

View Source
var HTTPClient = http.DefaultClient

HTTPClient is not read by this package.

Deprecated: AIA downloads use the client passed to WithHTTPClient, or a client with a 3s timeout when none is given; setting this variable has no effect (XPKI-044).

View Source
var IntermediateStash string

IntermediateStash contains the path to the directory where downloaded intermediates should be saved. When unspecified, downloaded intermediates are not saved.

View Source
var RandReader randSource = rand.Reader

RandReader is used so that it can be replaced in tests that require deterministic output

Functions

func BuildBundle added in v0.3.0

func BuildBundle(c *Chain) (bundle *Bundle, status *BundleStatus, err error)

BuildBundle returns the Bundle and BundleStatus of a Chain built by a Bundler. A nil c or c.Cert returns an error; a nil c.Status is treated as an empty status, and a nil c.Root (a Force chain) leaves RootCert and RootCertPEM empty (XPKI-042).

func CreateOCSPRequest added in v0.3.0

func CreateOCSPRequest(crt, issuer *x509.Certificate, hash crypto.Hash) ([]byte, error)

CreateOCSPRequest returns the DER encoded OCSP request for crt issued by issuer, hashing the issuer key with hash. A nil crt or issuer or an unavailable hash returns an error before any work (XPKI-103), and so does an issuer whose subject is not crt's issuer name or whose key did not sign crt (XPKI-121). The signature check accepts SHA-1 and applies no CA policy.

func CreatePoolFromPEM

func CreatePoolFromPEM(pemBytes []byte) (*x509.CertPool, error)

CreatePoolFromPEM returns CertPool from PEM encoded certs

func Digest

func Digest(hash crypto.Hash, data []byte) []byte

Digest returns computed digest bytes

func EncodePrivateKeyToPEM

func EncodePrivateKeyToPEM(priv crypto.PrivateKey) (key []byte, err error)

EncodePrivateKeyToPEM returns PEM encoded private key

func EncodePublicKeyToPEM

func EncodePublicKeyToPEM(pubKey crypto.PublicKey) ([]byte, error)

EncodePublicKeyToPEM returns PEM encoded public key

func EncodeToPEM

func EncodeToPEM(out io.Writer, withComments bool, certs ...*x509.Certificate) error

EncodeToPEM converts certificates to PEM format, with optional comments

func EncodeToPEMString

func EncodeToPEMString(withComments bool, certs ...*x509.Certificate) (string, error)

EncodeToPEMString converts certificates to PEM format, with optional comments

func ExpiryTime added in v0.2.0

func ExpiryTime(chain []*x509.Certificate) (notAfter time.Time)

ExpiryTime returns the time when the certificate chain is expired.

func FindExtension added in v0.2.0

func FindExtension(list []pkix.Extension, oid asn1.ObjectIdentifier) *pkix.Extension

FindExtension returns extension, or nil

func FindExtensionValue added in v0.2.0

func FindExtensionValue(list []pkix.Extension, oid asn1.ObjectIdentifier) []byte

FindExtensionValue returns extension value, or nil

func FindIssuer

func FindIssuer(crt *x509.Certificate, chain []*x509.Certificate, root *x509.Certificate) *x509.Certificate

FindIssuer returns an issuer cert

func GetAuthorityKeyID

func GetAuthorityKeyID(c *x509.Certificate) string

GetAuthorityKeyID returns Authority Key Identifier

func GetIssuerID

func GetIssuerID(c *x509.Certificate) string

GetIssuerID returns ID of the issuer. If present, it uses Authority Key Identifier, otherwise SHA1 of the Issuer name

func GetKeyDERFromPEM added in v0.2.0

func GetKeyDERFromPEM(in []byte, password []byte) ([]byte, error)

GetKeyDERFromPEM parses a PEM-encoded private key and returns DER-format key bytes, decrypting it with password when it is encrypted. Encrypted PKCS#8 keys are supported only with PBES2, PBKDF2 (HMAC-SHA1, -SHA224, -SHA256, -SHA384 or -SHA512, at most 10,000,000 iterations) and AES-128/192/256-CBC, which OpenSSL 3 writes by default. Other PKCS#8 schemes (PBES1, PKCS#12 PBE, scrypt, DES) return an "unsupported PKCS#8 encryption" error (XPKI-043). The decrypted bytes are returned only when they are a PKCS#8 PrivateKeyInfo; otherwise, as for bad padding, the error matches x509.IncorrectPasswordError (XPKI-115).

func GetSubjectID

func GetSubjectID(c *x509.Certificate) string

GetSubjectID returns ID of the cert. If present, it uses Subject Key Identifier, otherwise SHA1 of the Subject name

func GetSubjectKeyID

func GetSubjectKeyID(c *x509.Certificate) string

GetSubjectKeyID returns Subject Key Identifier

func GetThumbprintStr

func GetThumbprintStr(c *x509.Certificate) string

GetThumbprintStr returns hex-encoded SHA1 of the certificate

func HasOCSPNoCheck added in v0.3.0

func HasOCSPNoCheck(crt *x509.Certificate) bool

HasOCSPNoCheck returns true if certificate has ocsp-no-check. Both Extensions (populated on a parsed certificate) and ExtraExtensions (populated on a template before signing) are inspected.

func HashAlgoToStr

func HashAlgoToStr(hash crypto.Hash) string

HashAlgoToStr converts hash algorithm to string

func HashToBase64URL

func HashToBase64URL(hash crypto.Hash, data []byte) string

HashToBase64URL returns Base64URL encoded digest

func HashToHex

func HashToHex(hash crypto.Hash, data []byte) string

HashToHex returns hex-encoded digest

func IsOCSPSigner added in v0.3.0

func IsOCSPSigner(crt *x509.Certificate) bool

IsOCSPSigner returns true for OCSP key usage

func JoinPEM

func JoinPEM(p1, p2 []byte) []byte

JoinPEM returns concantenated PEM

func LoadAndVerifyBundleFromPEM

func LoadAndVerifyBundleFromPEM(certFile, intCAFile, rootFile string, opt ...Option) (*Bundle, *BundleStatus, error)

LoadAndVerifyBundleFromPEM constructs and verifies the cert chain

func LoadChainFromPEM

func LoadChainFromPEM(certFile string) ([]*x509.Certificate, error)

LoadChainFromPEM returns Certificates loaded from the file

func LoadFromPEM

func LoadFromPEM(certFile string) (*x509.Certificate, error)

LoadFromPEM returns Certificate loaded from the file

func LoadPEMFiles

func LoadPEMFiles(files ...string) ([]byte, error)

LoadPEMFiles loads and concatenates PEM files into one slice

func NameToString

func NameToString(name *pkix.Name) string

NameToString converts Name to string, compatible with openssl output

func NewHash

func NewHash(algo string) (hash.Hash, error)

NewHash returns hash instance

func ParseChainFromPEM

func ParseChainFromPEM(certificateChainPem []byte) ([]*x509.Certificate, error)

ParseChainFromPEM returns Certificates parsed from PEM

func ParseFromPEM

func ParseFromPEM(bytes []byte) (*x509.Certificate, error)

ParseFromPEM returns Certificate parsed from PEM

func ParseHexDigestWithPrefix

func ParseHexDigestWithPrefix(digest string) (hash.Hash, []byte, error)

ParseHexDigestWithPrefix parses encoded digest in {alg}:{hex} format

func ParsePrivateKeyDER added in v0.2.0

func ParsePrivateKeyDER(keyDER []byte) (key crypto.Signer, err error)

ParsePrivateKeyDER parses a PKCS #1, PKCS #8, ECDSA, or Ed25519 DER-encoded private key. The key must not be in PEM format.

func ParsePrivateKeyPEM added in v0.2.0

func ParsePrivateKeyPEM(keyPEM []byte) (key crypto.Signer, err error)

ParsePrivateKeyPEM parses and returns a PEM-encoded private key. The private key may be either an unencrypted PKCS#8, PKCS#1, or elliptic private key.

func ParsePrivateKeyPEMWithPassword added in v0.2.0

func ParsePrivateKeyPEMWithPassword(keyPEM []byte, password []byte) (key crypto.Signer, err error)

ParsePrivateKeyPEMWithPassword parses and returns a PEM-encoded private key. The private key may be an unencrypted PKCS#8, PKCS#1, or SEC1 key, a legacy PEM block encrypted per RFC 1423 (Proc-Type: 4,ENCRYPTED), or an encrypted PKCS#8 key (ENCRYPTED PRIVATE KEY) as described by GetKeyDERFromPEM. The key may be RSA, ECDSA, or Ed25519 (PKCS#8 only). A nil password fails for an encrypted key; a wrong password returns an error that matches x509.IncorrectPasswordError.

func ParseRSAPublicKeyFromPEM

func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error)

ParseRSAPublicKeyFromPEM parses PEM encoded RSA public key

func Random

func Random(byteLength int) []byte

Random returns a randomly generated bytes of the requested length.

func RandomString

func RandomString(length int) string

RandomString returns a random string of the given length over [0-9A-Za-z]. It panics if the random source fails.

func SHA1

func SHA1(data []byte) []byte

SHA1 returns SHA1 digest

func SHA1Base64

func SHA1Base64(data []byte) string

SHA1Base64 returns Base64URL encoded SHA1

func SHA1Hex

func SHA1Hex(data []byte) string

SHA1Hex returns hex-encoded SHA1

func SHA256

func SHA256(data []byte) []byte

SHA256 returns SHA256 digest

func SHA256Base64

func SHA256Base64(data []byte) string

SHA256Base64 returns Base64URL encoded SHA256

func SHA256Hex

func SHA256Hex(data []byte) string

SHA256Hex returns hex-encoded SHA256

func StrToHashAlgo

func StrToHashAlgo(algo string) crypto.Hash

StrToHashAlgo converts string to hash algorithm

func VerifyBundleFromPEM

func VerifyBundleFromPEM(certPEM, intCAPEM, rootPEM []byte, opt ...Option) (bundle *Bundle, status *BundleStatus, err error)

VerifyBundleFromPEM constructs and verifies the cert chain

Types

type Bundle

type Bundle struct {
	// Chain does not include the root anchor
	Chain       []*x509.Certificate
	Cert        *x509.Certificate
	IssuerCert  *x509.Certificate
	RootCert    *x509.Certificate
	Issuer      *pkix.Name
	Subject     *pkix.Name
	IssuerID    string
	SubjectID   string
	Expires     time.Time
	Hostnames   []string
	CertPEM     string
	CACertsPEM  string
	RootCertPEM string
}

A Bundle contains a certificate and its trust chain. It is intended to store the most widely applicable chain, with shortness an explicit goal.

func SortBundlesByExpiration

func SortBundlesByExpiration(bundles []*Bundle) []*Bundle

SortBundlesByExpiration returns a new slice of bundles sorted by Expires in descending order. The sort is stable, so bundles with the same Expires keep their input order, and nil bundles go last. The caller's slice is not reordered; the bundles themselves are shared (XPKI-038).

func (*Bundle) ExpiresInHours

func (b *Bundle) ExpiresInHours() time.Duration

ExpiresInHours returns the time until Expires truncated toward zero to whole hours: 90 minutes is 1h, and an expiry 90 minutes ago is -1h (XPKI-045).

type BundleFlavor added in v0.2.0

type BundleFlavor string

BundleFlavor is named optimization strategy on certificate chain selection when bundling.

const (
	// Optimal means the shortest chain with newest intermediates and
	// the most advanced crypto.
	Optimal BundleFlavor = "optimal"

	// Force means the bundler only verifies the input as a valid bundle, not optimization is done.
	Force BundleFlavor = "force"
)

type BundleStatus

type BundleStatus struct {
	// A list of SKIs of expiring certificates
	ExpiringSKIs []string `json:"expiring_SKIs"`
	// A list of untrusted root store names
	Untrusted []string `json:"untrusted_root_stores"`
	// A list of human readable warning messages based on the bundle status.
	Messages []string `json:"messages"`

	Code int `json:"code"`
}

BundleStatus is designated for various status reporting.

func (*BundleStatus) IsExpiring

func (b *BundleStatus) IsExpiring() bool

IsExpiring returns true if bundle is expiring in less than 30 days

func (*BundleStatus) IsUntrusted

func (b *BundleStatus) IsUntrusted() bool

IsUntrusted returns true if the cert's issuers are not trusted

type Bundler added in v0.2.0

type Bundler struct {
	RootPool         *x509.CertPool
	IntermediatePool *x509.CertPool
	KnownIssuers     map[string]bool
	// contains filtered or unexported fields
}

A Bundler contains the certificate pools for producing certificate bundles. It contains any intermediates and root certificates that should be used.

A Bundler is safe for concurrent use. Intermediates learned over AIA are shared by later calls: they are published by replacing IntermediatePool and KnownIssuers with updated copies, so a pool or map once read is never modified (XPKI-035).

The exported fields are set-up state. Set or replace them only before the first Bundle, ChainFromPEM or VerifyOptions call, and do not modify the pools or the map in place. After that, read the pools through VerifyOptions; reading the fields directly races with learning.

func LoadBundler added in v0.3.0

func LoadBundler(rootBundleFile, intBundleFile string, opt ...Option) (*Bundler, error)

LoadBundler creates a new Bundler from the files passed in; these files should contain a list of valid root certificates and a list of valid intermediate certificates, respectively.

func NewBundler added in v0.2.0

func NewBundler(roots, intermediates []*x509.Certificate, opt ...Option) (*Bundler, error)

NewBundler returns a Bundler that trusts roots, plus the system roots with WithSystemRoots, and uses intermediates to build chains. The flavor defaults to Optimal with trust roots and to Force without them; Optimal without trust roots is an error, so a Bundler never trusts system roots implicitly. RootPool is nil only when there are no trust roots.

func NewBundlerFromPEM added in v0.2.0

func NewBundlerFromPEM(rootBundlePEM, intBundlePEM []byte, opt ...Option) (*Bundler, error)

NewBundlerFromPEM creates a new Bundler from PEM-encoded root certificates and intermediate certificates. Without root certificates the default flavor is Force; see NewBundler.

func (*Bundler) Bundle added in v0.2.0

func (b *Bundler) Bundle(certs []*x509.Certificate, key crypto.Signer) (*Chain, error)

Bundle takes an X509 certificate (already in the Certificate structure), a private key as crypto.Signer in one of the appropriate formats (i.e. *rsa.PrivateKey or *ecdsa.PrivateKey, or even a opaque key), using them to build a certificate bundle. certs[0] is the leaf (a reversed chain is detected). A nil or empty certs returns an error matching ErrNoCertificates, and a nil entry returns an error (XPKI-036).

func (*Bundler) BundleContext added in v0.29.306

func (b *Bundler) BundleContext(ctx context.Context, certs []*x509.Certificate, key crypto.Signer) (*Chain, error)

BundleContext is Bundle with a context that bounds and cancels AIA downloads. When ctx is done during an AIA download, the returned error matches ctx.Err() with errors.Is. An Optimal Bundler whose RootPool is nil fails instead of verifying against the system roots.

func (*Bundler) ChainFromFile added in v0.3.0

func (b *Bundler) ChainFromFile(bundleFile, keyFile string, password string) (*Chain, error)

ChainFromFile takes a set of files containing the PEM-encoded leaf certificate (optionally along with some intermediate certs), the PEM-encoded private key and returns the bundle built from that key and the certificate(s).

func (*Bundler) ChainFromPEM added in v0.3.0

func (b *Bundler) ChainFromPEM(certsRaw, keyPEM []byte, password string) (*Chain, error)

ChainFromPEM builds a certificate chain from the set of byte slices containing the PEM or DER-encoded certificate(s), private key.

func (*Bundler) ChainFromPEMContext added in v0.29.306

func (b *Bundler) ChainFromPEMContext(ctx context.Context, certsRaw, keyPEM []byte, password string) (*Chain, error)

ChainFromPEMContext is ChainFromPEM with a context that bounds and cancels AIA downloads; see BundleContext.

func (*Bundler) VerifyOptions added in v0.2.0

func (b *Bundler) VerifyOptions() x509.VerifyOptions

VerifyOptions returns the x509.VerifyOptions used by Optimal bundling. Roots is never nil: without a RootPool it is an empty pool, so the options never fall back to the system roots. It is a snapshot: intermediates learned later are not added to it.

type Chain added in v0.2.0

type Chain struct {
	Chain       []*x509.Certificate
	Cert        *x509.Certificate
	Root        *x509.Certificate
	Key         any
	Issuer      *pkix.Name
	Subject     *pkix.Name
	Expires     time.Time
	LeafExpires time.Time
	Hostnames   []string
	Status      *BundleStatus
}

Chain contains a certificate and its trust chain. It is intended to store the most widely applicable chain, with shortness an explicit goal.

type KeyInfo

type KeyInfo struct {
	KeySize   int
	Type      string
	IsPrivate bool
	Hash      crypto.Hash
	Key       any
}

KeyInfo provides information about the key

func NewKeyInfo

func NewKeyInfo(k any) (*KeyInfo, error)

NewKeyInfo returns *KeyInfo

type Option added in v0.2.0

type Option func(*options)

An Option sets options such as allowed key usages, etc.

func WithAIA added in v0.3.0

func WithAIA(enable bool) Option

WithAIA lets to enable downloading issuers from AIA.

func WithBundleFlavor added in v0.3.0

func WithBundleFlavor(flavor BundleFlavor) Option

WithBundleFlavor selects Optimal or Force chain building. Without this option the flavor is Optimal when the Bundler has trust roots (explicit roots or WithSystemRoots) and Force otherwise. NewBundler rejects Optimal without trust roots and any other flavor value; the last option wins.

func WithHTTPClient added in v0.3.0

func WithHTTPClient(client *http.Client) Option

WithHTTPClient sets the client for AIA downloads. Each request is bounded by the client's Timeout, or 3s when it is zero, and by the context given to BundleContext. Only a 200 response of at most 1 MiB is parsed. Without this option a client with a 3s timeout is used.

func WithKeyUsages added in v0.2.0

func WithKeyUsages(usages ...x509.ExtKeyUsage) Option

WithKeyUsages lets you set which Extended Key Usage values are acceptable. By default x509.ExtKeyUsageAny will be used.

func WithSystemRoots added in v0.29.306

func WithSystemRoots(enable bool) Option

WithSystemRoots adds the platform trust store (x509.SystemCertPool) to the explicit roots. It is the only way a Bundler trusts system roots: without it, Optimal verification uses the explicit roots alone (XPKI-041).

Jump to

Keyboard shortcuts

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