cryptoprov

package
v1.1.322 Latest Latest
Warning

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

Go to latest
Published: Nov 9, 2026 License: Apache-2.0 Imports: 29 Imported by: 5

Documentation

Overview

Package cryptoprov provides a unified interface for cryptographic operations across different providers and hardware security modules (HSMs).

This package abstracts cryptographic operations to support:

  • PKCS#11 compatible HSMs via the sibling crypto11 package
  • AWS KMS for cloud-based key management
  • Google Cloud KMS for cloud-based key management
  • In-memory providers for testing and development
  • Custom providers through the Provider interface

The package handles key generation, signing, encryption, and key management operations in a provider-agnostic way, allowing applications to switch between different cryptographic backends without code changes. Keys are RSA, ECDSA or ML-DSA (FIPS 204, post-quantum); an ML-DSA signer signs messages rather than digests, see MLDSASignerOptions.

Configuration is a small JSON or YAML token config whose Manufacturer field selects a loader registered with Register; provider packages register themselves in init(), so import them for side effects before calling Load.

Index

Constants

View Source
const (
	// MLDSA44, MLDSA65 and MLDSA87 are the FIPS 204 parameter set numbers as
	// csr.KeyRequest.Size and certutil.KeyInfo.KeySize carry them.
	MLDSA44 = 44
	MLDSA65 = 65
	MLDSA87 = 87

	// MetaParameterSet is the KeyInfo.Meta key under which a provider
	// reports the parameter set of an ML-DSA key, for example "ML-DSA-65".
	MetaParameterSet = "parameter_set"

	// MLDSAMuSize is the length in bytes of the ML-DSA message
	// representative μ (FIPS 204, Algorithm 7) that a signer accepts with
	// crypto.MLDSAMu.
	MLDSAMuSize = 64
)

Variables

View Source
var ErrDuplicateProvider = errors.New("duplicate provider")

ErrDuplicateProvider is returned by Crypto.Add, New and Load when a different provider is already registered for the same manufacturer and model.

View Source
var ErrInvalidPrivateKeyURI = errors.New("invalid URI for private key object")

ErrInvalidPrivateKeyURI is returned if the PKCS #11 URI is invalid for the private key object

View Source
var ErrInvalidURI = errors.New("invalid URI")

ErrInvalidURI is returned if the PKCS #11 URI is invalid.

View Source
var ErrNilProvider = errors.New("nil provider")

ErrNilProvider is returned by New and Crypto.Add for a nil provider, including a typed nil such as a nil *crypto11.PKCS11Lib.

Functions

func GcmDecrypt

func GcmDecrypt(ciphertext []byte, key []byte) ([]byte, error)

GcmDecrypt returns decrypted blob with GCM cipher

func GcmEncrypt

func GcmEncrypt(plaintext []byte, key []byte) ([]byte, error)

GcmEncrypt returns encrypted blob with GCM cipher

func GetPrivateKeyDERFromPEM

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

GetPrivateKeyDERFromPEM parses a PEM-encoded private key and returns DER-format key bytes.

func MLDSAMu added in v1.1.320

func MLDSAMu(pub *mldsa.PublicKey, context string, message []byte) ([]byte, error)

MLDSAMu returns μ, the message representative an ML-DSA signature is computed over (FIPS 204, Algorithm 7): SHAKE256(tr ‖ 0x00 ‖ len(context) ‖ context ‖ message, 64) with tr = SHAKE256(pk, 64). A KMS or HSM external-μ operation over it produces the same signature as signing message with context locally, which mldsa.Verify checks with the same message and context. The context is at most 255 bytes.

func MLDSAParameters added in v1.1.320

func MLDSAParameters(size int) (mldsa.Parameters, error)

MLDSAParameters returns the ML-DSA parameter set for its FIPS 204 number: MLDSA44, MLDSA65 or MLDSA87. Any other number is an error.

func MLDSASignerOptions added in v1.1.320

func MLDSASignerOptions(opts crypto.SignerOpts) (mu bool, context string, err error)

MLDSASignerOptions validates opts against the contract every ML-DSA signer of this module follows: ML-DSA signs a message, not a digest. The signer accepts the message with nil options, options whose HashFunc is zero (x509.CreateCertificate passes crypto.Hash(0)) or *mldsa.Options carrying an optional context string (a nil *mldsa.Options counts as nil), and a 64-byte message representative μ with crypto.MLDSAMu. Any other hash, and a nil pointer of any other options type, is an error, so a hash-then-sign caller fails instead of signing a digest as if it were the message. It returns whether the message is a μ and the context.

func ParsePrivateKeyDER

func ParsePrivateKeyDER(keyDER []byte) (crypto.PrivateKey, error)

ParsePrivateKeyDER parses a PKCS #1, PKCS #8, ECDSA DER-encoded private key. The key must not be in PEM format. PKCS #8 keys may be RSA, ECDSA, Ed25519 or ML-DSA; an ML-DSA key must be in the seed form (RFC 9881), the form x509.MarshalPKCS8PrivateKey and "openssl genpkey -provparam ml-dsa.output_formats=seed-only" write.

func ParsePrivateKeyPEM

func ParsePrivateKeyPEM(keyPEM []byte) (key crypto.PrivateKey, 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; see ParsePrivateKeyDER for the key types.

func ParsePrivateKeyPEMWithPassword

func ParsePrivateKeyPEMWithPassword(keyPEM []byte, password []byte) (key crypto.PrivateKey, 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, or a legacy PEM block encrypted per RFC 1423 (Proc-Type: 4,ENCRYPTED); encrypted PKCS#8 (ENCRYPTED PRIVATE KEY) is not supported. The key may be RSA, ECDSA, Ed25519 or ML-DSA (the last two PKCS#8 only).

func Register

func Register(manufacturer string, loader ProviderLoader) error

Register provider loader by manufacturer

func Registered added in v0.3.0

func Registered() []string

Registered returns registered providers

Types

type Crypto

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

Crypto exposes instances of Provider, found by manufacturer and model. It is safe for concurrent use: Add may run while other goroutines call ByManufacturer or LoadPrivateKey.

func Load

func Load(defaultConfig string, providersConfigs []string) (c *Crypto, err error)

Load returns Crypto with loaded providers from the given config locations. Each config must name a different manufacturer and model than the others (ErrDuplicateProvider). On error, Load closes the providers it already loaded that implement Close() error.

func New

func New(defaultProvider Provider, providers []Provider) (*Crypto, error)

New creates an instance of Crypto providers. defaultProvider is required; providers are added with Add, so a nil entry or a conflicting duplicate fails New.

func (*Crypto) Add

func (c *Crypto) Add(p Provider) error

Add registers p for lookup by its manufacturer and model. Adding the same provider again, including the default one, is a no-op when its dynamic value is comparable, such as a pointer; the provider types in this module are. A provider value that is not comparable (a struct holding a map, slice or func) can not be matched, so adding it again returns ErrDuplicateProvider. A different provider with the manufacturer and model of a registered or the default provider returns ErrDuplicateProvider (XPKI-016), and a nil provider, including a typed nil, returns ErrNilProvider.

func (*Crypto) ByManufacturer

func (c *Crypto) ByManufacturer(manufacturer, model string) (Provider, error)

ByManufacturer returns the default provider or the registered provider for manufacturer and model. It does not lock and may run concurrently with Add.

func (*Crypto) Default

func (c *Crypto) Default() Provider

Default returns a default crypto provider

func (*Crypto) LoadPrivateKey

func (c *Crypto) LoadPrivateKey(key []byte) (Provider, crypto.PrivateKey, error)

LoadPrivateKey returns crypto.PrivateKey. The input key can be in PEM encoded format, or PKCS11 URI.

func (*Crypto) LoadTLSKeyPair

func (c *Crypto) LoadTLSKeyPair(certFile, keyFile string) (*tls.Certificate, error)

LoadTLSKeyPair reads and parses a public/private key pair from a pair of files. The files must contain PEM encoded data. The certificate file may contain intermediate certificates following the leaf certificate to form a certificate chain. On successful return, Certificate.Leaf holds the parsed leaf certificate.

func (*Crypto) NewSignerFromFromFile

func (c *Crypto) NewSignerFromFromFile(caKeyFile string) (crypto.Signer, error)

NewSignerFromFromFile generates a new signer from a caFile and a caKey file, both PEM encoded or caKey contains PKCS#11 Uri

func (*Crypto) NewSignerFromPEM

func (c *Crypto) NewSignerFromPEM(caKey []byte) (crypto.Signer, error)

NewSignerFromPEM generates a new crypto signer from PEM encoded blocks, or caKey contains PKCS#11 Uri

func (*Crypto) TLSKeyPair

func (c *Crypto) TLSKeyPair(certPEMBlock, keyPEMBlock []byte) (*tls.Certificate, error)

TLSKeyPair parses a public/private key pair from PEM encoded data. The key may be a PEM private key or a pkcs11: URI resolved through the registered providers. On successful return, Certificate.Leaf holds the parsed leaf certificate. An error is returned when the private key does not match the leaf certificate's public key.

type KeyGenerator

type KeyGenerator interface {
	// GenerateRSAKey returns RSA key for purpose: 1-signing, 2-encryption
	GenerateRSAKey(label string, bits int, purpose int) (crypto.PrivateKey, error)
	GenerateECDSAKey(label string, curve elliptic.Curve) (crypto.PrivateKey, error)
	// GenerateMLDSAKey returns an ML-DSA (FIPS 204) signing key of the
	// parameter set params: mldsa.MLDSA44(), MLDSA65() or MLDSA87(), see
	// MLDSAParameters. The key signs messages, not digests.
	GenerateMLDSAKey(label string, params mldsa.Parameters) (crypto.PrivateKey, error)
	IdentifyKey(crypto.PrivateKey) (keyID, label string, err error)
	ExportKey(keyID string) (string, []byte, error)
	GetKey(keyID string) (crypto.PrivateKey, error)
}

KeyGenerator defines interface for key generation operations. Every generated key is a crypto.Signer; an ML-DSA signer follows the contract MLDSASignerOptions describes.

type KeyInfo

type KeyInfo struct {
	ID               string
	Label            string
	Type             string
	Class            string
	CurrentVersionID string
	CreationTime     *time.Time
	PublicKey        string
	Meta             map[string]string
}

KeyInfo provides key information. Type names the key algorithm as crypto/x509 prints it ("RSA", "ECDSA", "ML-DSA"); for an ML-DSA key Meta also carries MetaParameterSet, for example "ML-DSA-65".

type KeyManager

type KeyManager interface {
	CurrentSlotID() uint
	EnumTokens(currentSlotOnly bool) ([]TokenInfo, error)
	EnumKeys(slotID uint, prefix string) ([]KeyInfo, error)
	DestroyKeyPairOnSlot(slotID uint, keyID string) error
	FindKeyPairOnSlot(slotID uint, keyID, label string) (crypto.PrivateKey, error)
	KeyInfo(slotID uint, keyID string, includePublic bool) (*KeyInfo, error)
}

KeyManager defines interface for key management operations

type PrivateKeyURI

type PrivateKeyURI interface {
	// Token manufacturer
	Manufacturer() string

	// Model manufacturer
	Model() string

	// Token serial number
	TokenSerial() string

	// Token label
	TokenLabel() string

	// Key ID
	ID() string
}

PrivateKeyURI holds PKCS#11 private key information.

A token may be identified either by serial number or label. If both are specified then the first match wins.

func ParsePrivateKeyURI

func ParsePrivateKeyURI(uri string) (PrivateKeyURI, error)

ParsePrivateKeyURI parses a PKCS #11 URI (RFC 7512) into a key configuration. The URI must have type=private, serial and id (the id is percent-decoded and may hold binary data). Query attributes are validated like ParseTokenURI does but not returned.

type Provider

type Provider interface {
	KeyGenerator
	Manufacturer() string
	Model() string
}

Provider defines an interface to work with crypto providers: HSM, SoftHSM, KMS, crypto

func LoadProvider

func LoadProvider(configLocation string) (Provider, error)

LoadProvider load a single provider

type ProviderLoader

type ProviderLoader func(cfg TokenConfig) (Provider, error)

ProviderLoader is interface for loading provider by manufacturer

func Unregister

func Unregister(manufacturer string) (ProviderLoader, error)

Unregister provider loader by manufacturer

type TokenConfig

type TokenConfig interface {
	// Manufacturer name of the manufacturer
	Manufacturer() string

	// Model name of the device
	Model() string

	// Full path to PKCS#11 library
	Path() string

	// Token serial number
	TokenSerial() string

	// Token label
	TokenLabel() string

	// Pin is a secret to access the token.
	// If it's prefixed with `file:`, then it will be loaded from the file.
	Pin() string

	// Comma separated key=value pair of attributes(e.g. "ServiceName=x,UserName=y")
	Attributes() string
}

TokenConfig holds PKCS#11 configuration information.

A token may be identified by serial number, label, or both; how they are used is provider specific. The PKCS#11 provider (crypto11) requires at least one of them and selects the first token matching every nonempty one.

Supply this to Configure(), or alternatively use ConfigureFromFile().

func LoadTokenConfig

func LoadTokenConfig(filename string) (TokenConfig, error)

LoadTokenConfig loads PKCS#11 token configuration

func ParseTokenURI

func ParseTokenURI(uri string) (TokenConfig, error)

ParseTokenURI parses a PKCS #11 URI (RFC 7512) into a token configuration. The path attributes manufacturer, model, token and serial select the token; the query attributes module-name, module-path, pin-value and pin-source (a file: URI whose content, trimmed, is the PIN) set the library and the PIN. module-path overrides module-name when both are present. The query attributes are also accepted in the path, as this package did before XPKI-027, but not in both places, and a URI with both pin-source and pin-value is refused (RFC 7512 §2.4). Manufacturer and model are trimmed. Errors never contain a pin-value.

type TokenInfo

type TokenInfo struct {
	SlotID       uint
	Description  string
	Label        string
	Manufacturer string
	Model        string
	Serial       string
}

TokenInfo provides PKCS #11 token info

Directories

Path Synopsis
Package awskmscrypto implements cryptoprov.Provider and cryptoprov.KeyManager over AWS KMS asymmetric signing keys (RSA 2048/3072/4096 and NIST P-256, P-384, P-521).
Package awskmscrypto implements cryptoprov.Provider and cryptoprov.KeyManager over AWS KMS asymmetric signing keys (RSA 2048/3072/4096 and NIST P-256, P-384, P-521).
Package gcpkmscrypto implements cryptoprov.Provider and cryptoprov.KeyManager over Google Cloud KMS (HSM protection level).
Package gcpkmscrypto implements cryptoprov.Provider and cryptoprov.KeyManager over Google Cloud KMS (HSM protection level).
Package inmemcrypto is a software cryptoprov.Provider that keeps RSA, ECDSA and ML-DSA keys in memory and can export them as PEM (PKCS#1, SEC1 and PKCS#8 respectively).
Package inmemcrypto is a software cryptoprov.Provider that keeps RSA, ECDSA and ML-DSA keys in memory and can export them as PEM (PKCS#1, SEC1 and PKCS#8 respectively).
Package testprov is a test-only in-memory cryptoprov.Provider (RSA, ECDSA and ML-DSA keys) whose keys are not exportable: ExportKey returns a pkcs11: URI like the HSM and KMS providers do, and the key wrapper implements crypto.Decrypter.
Package testprov is a test-only in-memory cryptoprov.Provider (RSA, ECDSA and ML-DSA keys) whose keys are not exportable: ExportKey returns a pkcs11: URI like the HSM and KMS providers do, and the key wrapper implements crypto.Decrypter.

Jump to

Keyboard shortcuts

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