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
- Variables
- func GcmDecrypt(ciphertext []byte, key []byte) ([]byte, error)
- func GcmEncrypt(plaintext []byte, key []byte) ([]byte, error)
- func GetPrivateKeyDERFromPEM(in []byte, password []byte) ([]byte, error)
- func MLDSAMu(pub *mldsa.PublicKey, context string, message []byte) ([]byte, error)
- func MLDSAParameters(size int) (mldsa.Parameters, error)
- func MLDSASignerOptions(opts crypto.SignerOpts) (mu bool, context string, err error)
- func ParsePrivateKeyDER(keyDER []byte) (crypto.PrivateKey, error)
- func ParsePrivateKeyPEM(keyPEM []byte) (key crypto.PrivateKey, err error)
- func ParsePrivateKeyPEMWithPassword(keyPEM []byte, password []byte) (key crypto.PrivateKey, err error)
- func Register(manufacturer string, loader ProviderLoader) error
- func Registered() []string
- type Crypto
- func (c *Crypto) Add(p Provider) error
- func (c *Crypto) ByManufacturer(manufacturer, model string) (Provider, error)
- func (c *Crypto) Default() Provider
- func (c *Crypto) LoadPrivateKey(key []byte) (Provider, crypto.PrivateKey, error)
- func (c *Crypto) LoadTLSKeyPair(certFile, keyFile string) (*tls.Certificate, error)
- func (c *Crypto) NewSignerFromFromFile(caKeyFile string) (crypto.Signer, error)
- func (c *Crypto) NewSignerFromPEM(caKey []byte) (crypto.Signer, error)
- func (c *Crypto) TLSKeyPair(certPEMBlock, keyPEMBlock []byte) (*tls.Certificate, error)
- type KeyGenerator
- type KeyInfo
- type KeyManager
- type PrivateKeyURI
- type Provider
- type ProviderLoader
- type TokenConfig
- type TokenInfo
Constants ¶
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 ¶
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.
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
var ErrInvalidURI = errors.New("invalid URI")
ErrInvalidURI is returned if the PKCS #11 URI is invalid.
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 ¶
GcmDecrypt returns decrypted blob with GCM cipher
func GcmEncrypt ¶
GcmEncrypt returns encrypted blob with GCM cipher
func GetPrivateKeyDERFromPEM ¶
GetPrivateKeyDERFromPEM parses a PEM-encoded private key and returns DER-format key bytes.
func MLDSAMu ¶ added in v1.1.320
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 ¶
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 ¶
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 ¶
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 ¶
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) LoadPrivateKey ¶
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 ¶
NewSignerFromFromFile generates a new signer from a caFile and a caKey file, both PEM encoded or caKey contains PKCS#11 Uri
func (*Crypto) NewSignerFromPEM ¶
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 ¶
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.
Source Files
¶
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. |