go-certstore

Access X.509 certificate identities and their private-key signers from Go. Use native operating-system stores, PKCS#11 tokens, or NSS databases through one focused API.

Private keys stay in their original backend.

The library returns a crypto.Signer. Signing happens in Keychain, the Windows Certificate Store, a token, HSM, or NSS database.

Installation#

Add the latest release to your module:

shell
go get github.com/sukujgrg/go-certstore@latest

Quick start#

Open the default backend for the current platform and list its identities:

Go
package main

import (
    "context"
    "fmt"

    certstore "github.com/sukujgrg/go-certstore"
)

func main() {
    ctx := context.Background()
    store, err := certstore.Open(ctx)
    if err != nil {
        panic(err)
    }
    defer store.Close()

    identities, err := store.Identities(ctx)
    if err != nil {
        panic(err)
    }
    fmt.Printf("found %d identities\n", len(identities))
}
Linux

Linux has no native backend. Select BackendPKCS11 or BackendNSS explicitly.

Platform support#

BackendHost OSStatuscgo
KeychainSecurity.frameworkmacOSSupportedYes
Certificate StoreCNG or CryptoAPIWindowsSupportedYes
Native system storeLinuxUnavailableNo
PKCS#11Explicit module pathmacOS, Windows, LinuxSupportedYes
NSSExplicit module + profilemacOS, Windows, LinuxSupportedYes

Configure a backend#

Native stores require no backend options. PKCS#11 and NSS remain explicit so your application controls module discovery, profiles, tokens, and credentials.

Native stores

Uses macOS Keychain or the Windows Certificate Store for the current user.

Go
store, err := certstore.Open(ctx)
if err != nil {
    return err
}
defer store.Close()

TLS client certificates#

For long-lived clients, open the store once and use NewClientCertificateSource. It caches compatible certificates and keeps signers alive for concurrent handshakes.

Go
source := certstore.NewClientCertificateSource(ctx, store,
    certstore.SelectOptions{
        SubjectCN:            "client.example.com",
        RequireClientAuthEKU: true,
    },
)
defer source.Close()

tlsConfig := &tls.Config{
    GetClientCertificate: source.GetClientCertificate,
}
Resource lifetime

Close the source before the store. Close signers obtained directly with certstore.CloseSigner.

Identity selection#

Single-result helpers rank matches. The current score prefers hardware-backed identities when requested, then currently valid certificates, then later expiration dates.

  • Set RequireCurrentlyValid to reject expired or not-yet-valid certificates.
  • Use FindIdentities or FilterIdentities when you need every match.
  • ClientCertificateSource always requires a currently valid certificate.

Credentials & resource lifetime#

WithCredentialPrompt gives credential collection to the application. The callback returns []byte, and the library clears that buffer after use.

Security boundary

Return a dedicated buffer. The cgo runtime or a dependency can make an internal copy, so this is not a high-assurance secret-memory system.

Runnable examples#

The repository includes complete programs. They inspect local state and do not connect to a remote server.