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

crypto11

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, MIT Imports: 27 Imported by: 2

Documentation

Overview

Package crypto11 provides a Go interface to PKCS#11 cryptographic devices such as Hardware Security Modules (HSMs) and smart cards.

This package implements the standard Go crypto interfaces for:

  • RSA private keys and signatures
  • ECDSA private keys and signatures
  • Random number generation
  • Session management

The package supports common PKCS#11 operations including:

  • Key generation on the device
  • Signing operations using device-stored keys
  • Object discovery and management
  • Session pooling for performance

Keys generated or imported into the HSM cannot be exported, providing hardware-level protection for cryptographic operations.

Open a token with Init or ConfigureFromFile and release it with Close. Every PKCS11Lib on the same library path shares one loaded module: the first one initializes it and the last Close finalizes it. Each PKCS11Lib keeps at most WithMaxSessions pooled sessions per slot (default DefaultMaxSessions); an operation waits while all of them are in use.

lib, err := crypto11.ConfigureFromFile("/path/softhsm.json", crypto11.WithMaxSessions(64))
if err != nil {
	return err
}
defer func() { _ = lib.Close() }()
key, err := lib.GenerateECDSAKeyPair(elliptic.P256())
if err != nil {
	return err
}
sig, err := key.Sign(rand.Reader, digest, crypto.SHA256)

This package is based on github.com/ThalesIgnite/crypto11 with modifications for integration with the xpki ecosystem.

Index

Constants

View Source
const DefaultMaxSessions = 1024

DefaultMaxSessions is the default limit of pooled sessions per slot of one PKCS11Lib; see WithMaxSessions.

Variables

View Source
var AttributeNames = map[uint]string{
	pkcs11.CKA_ID:       "ID",
	pkcs11.CKA_LABEL:    "Label",
	pkcs11.CKA_KEY_TYPE: "Key type",
	pkcs11.CKA_CLASS:    "Class",
}

AttributeNames maps PKCS11 attribute to string

View Source
var KeyTypeNames = map[uint]string{
	pkcs11.CKK_RSA: "RSA",
	pkcs11.CKK_DSA: "DSA",
	pkcs11.CKK_DH:  "DH",
	pkcs11.CKK_EC:  "ECDSA",
}

KeyTypeNames maps PKCS11 key type to string

View Source
var ObjectClassNames = map[uint]string{
	pkcs11.CKO_DATA:        "Data",
	pkcs11.CKO_CERTIFICATE: "Certificate",
	pkcs11.CKO_PUBLIC_KEY:  "Public key",
	pkcs11.CKO_PRIVATE_KEY: "Private key",
	pkcs11.CKO_SECRET_KEY:  "Secret key",
}

ObjectClassNames maps PKCS11 object class to string

Functions

func BytesToUlong deprecated

func BytesToUlong(bs []byte) uint

BytesToUlong decodes a native CK_ULONG attribute value, such as CKA_KEY_TYPE or CKA_CLASS. It returns CK_UNAVAILABLE_INFORMATION (^uint(0)) when bs is not exactly one CK_ULONG long, including a nil value for an attribute the token could not return.

Deprecated: BytesToUlong cannot report malformed input; check the length and decode the value with encoding/binary.NativeEndian instead.

func ConvertToPublic

func ConvertToPublic(priv crypto.PrivateKey) (crypto.PublicKey, error)

ConvertToPublic converts a private key interface to crypto.PublicKey type

func LoadProvider

func LoadProvider(cfg cryptoprov.TokenConfig) (cryptoprov.Provider, error)

LoadProvider provides loader for crypto11 provider

func UlongToBytes

func UlongToBytes(n uint) []byte

UlongToBytes encodes n as a native CK_ULONG attribute value (host byte order, ulongSize bytes). Where CK_ULONG is 32 bits, only the low 32 bits of n are kept.

Types

type KeyIdentifier

type KeyIdentifier interface {
	KeyID() string
	Label() string
}

KeyIdentifier interface provides key ID and label

type KeyPurpose

type KeyPurpose int

KeyPurpose declares the purpose for keys

const (
	// Undefined purpose of key
	Undefined KeyPurpose = 0
	// Signing specifies the purpose of key to be used in signing/verification operations
	Signing KeyPurpose = 1
	// Encryption specifies the purpose of key to be used in encryption/decryption operations
	Encryption KeyPurpose = 2
)

type Option added in v0.29.306

type Option func(*options)

Option configures Init and ConfigureFromFile.

func WithMaxSessions added in v0.29.306

func WithMaxSessions(n int) Option

WithMaxSessions limits the pooled sessions that one PKCS11Lib keeps open on each slot (default DefaultMaxSessions). When all of them are in use, an operation waits until one is returned. The login session opened by Init is not counted. n must be positive.

type PKCS11Lib

type PKCS11Lib struct {
	// Ctx is the shared module context. It is nil after Close.
	Ctx    *pkcs11.Ctx
	Config TokenConfig
	// Session is the login session on Slot, opened by Init and closed by
	// Close. It keeps the token logged in while pooled sessions are opened
	// and closed. It is replaced when the token has to be logged in again
	// after a logout or a reinsertion (XPKI-110), so do not cache, close or
	// use it concurrently with operations of this PKCS11Lib.
	Session pkcs11.SessionHandle
	Slot    *SlotTokenInfo
	// contains filtered or unexported fields
}

PKCS11Lib contains a reference to an open PKCS#11 slot and configuration.

Every PKCS11Lib opened on the same library path shares one loaded module: the first Init initializes it and the last Close finalizes it. Each PKCS11Lib owns its own session pools and login session. It is safe for concurrent use; after Close its operations return an error.

func ConfigureFromFile

func ConfigureFromFile(configLocation string, opts ...Option) (*PKCS11Lib, error)

ConfigureFromFile loads a token configuration with LoadTokenConfig and opens it with Init; opts and the returned PKCS11Lib are as for Init.

func Init

func Init(config TokenConfig, opts ...Option) (_ *PKCS11Lib, err error)

Init configures PKCS#11 from a TokenConfig, opens the token slot and logs in when the token requires it.

The library at config.Path() is loaded and initialized by the first PKCS11Lib that uses it and shared by later ones. On error Init releases everything it acquired. Call Close to release the returned PKCS11Lib.

func (*PKCS11Lib) Close

func (lib *PKCS11Lib) Close() error

Close releases the resources of lib. New operations fail at once, and Close waits for the operations in flight to return their sessions. It then closes the sessions of lib, including the login session, and releases the module; the last PKCS11Lib on a module calls C_Finalize (unless the module was initialized outside this package) and unloads it. Close is idempotent: every call, including concurrent ones, waits for the first to finish and returns its result.

Close must not be called from inside an operation of lib, which it would wait for forever. Sessions a caller opened with NewSession, and the *OnSession methods that use them, are not tracked: close those sessions and stop using them before Close.

func (*PKCS11Lib) CurrentSlotID

func (lib *PKCS11Lib) CurrentSlotID() uint

CurrentSlotID returns current slot ID

func (*PKCS11Lib) DestroyKeyPairOnSlot

func (lib *PKCS11Lib) DestroyKeyPairOnSlot(slotID uint, keyID string) error

DestroyKeyPairOnSlot destroys key pair

func (*PKCS11Lib) EnumKeys

func (lib *PKCS11Lib) EnumKeys(slotID uint, prefix string) ([]cryptoprov.KeyInfo, error)

EnumKeys returns lists of keys on the slot.

It uses its own read-only session rather than a pooled RW one, so a write-protected token can still be listed. Private keys are visible only to a logged-in session, and a logged-out token lists none without an error, so on the login slot the session state is checked first and the token is logged in again when needed (XPKI-110).

func (*PKCS11Lib) EnumTokens

func (lib *PKCS11Lib) EnumTokens(currentSlotOnly bool) ([]cryptoprov.TokenInfo, error)

EnumTokens enumerates tokens

func (*PKCS11Lib) ExportKey

func (lib *PKCS11Lib) ExportKey(keyID string) (string, []byte, error)

ExportKey returns PKCS#11 URI for specified key ID. It does not return key bytes.

func (*PKCS11Lib) FindKeyPair

func (lib *PKCS11Lib) FindKeyPair(keyID, label string) (crypto.PrivateKey, error)

FindKeyPair retrieves a previously created asymmetric key.

Either (but not both) of id and label may be nil, in which case they are ignored.

func (*PKCS11Lib) FindKeyPairOnSession

func (lib *PKCS11Lib) FindKeyPairOnSession(session pkcs11.SessionHandle, slot uint, keyID, label string) (crypto.PrivateKey, error)

FindKeyPairOnSession retrieves a previously created asymmetric key, using a specified session.

Either (but not both) of id and label may be nil, in which case they are ignored. session is owned by the caller; after Close it returns errClosed.

func (*PKCS11Lib) FindKeyPairOnSlot

func (lib *PKCS11Lib) FindKeyPairOnSlot(slot uint, keyID, label string) (crypto.PrivateKey, error)

FindKeyPairOnSlot retrieves a previously created asymmetric key, using a specified slot.

Either (but not both) of id and label may be nil, in which case they are ignored.

func (*PKCS11Lib) FindKeys

func (lib *PKCS11Lib) FindKeys(session pkcs11.SessionHandle, keylabel string, keyclass uint, keytype uint) ([]pkcs11.ObjectHandle, error)

FindKeys returns key objects on the slot matching label and key type. session is owned by the caller; after Close it returns errClosed.

func (*PKCS11Lib) GenRandom

func (lib *PKCS11Lib) GenRandom(data []byte) (n int, err error)

GenRandom fills data with random bytes generated via PKCS#11 using the default slot.

func (*PKCS11Lib) GenerateECDSAKey

func (lib *PKCS11Lib) GenerateECDSAKey(label string, curve elliptic.Curve) (crypto.PrivateKey, error)

GenerateECDSAKey generates ECDSA key pair

func (*PKCS11Lib) GenerateECDSAKeyPair

func (lib *PKCS11Lib) GenerateECDSAKeyPair(c elliptic.Curve) (*PKCS11PrivateKeyECDSA, error)

GenerateECDSAKeyPair creates an ECDSA private key using curve c.

The key will have a random label and ID.

Only a limited set of named elliptic curves are supported. The underlying PKCS#11 implementation may impose further restrictions.

func (*PKCS11Lib) GenerateECDSAKeyPairOnSession

func (lib *PKCS11Lib) GenerateECDSAKeyPairOnSession(session pkcs11.SessionHandle, slot uint, id []byte, label []byte, c elliptic.Curve) (*PKCS11PrivateKeyECDSA, error)

GenerateECDSAKeyPairOnSession creates an ECDSA private key using curve c, using a specified session.

label and/or id can be nil, in which case a random values will be generated.

Only a limited set of named elliptic curves are supported. The underlying PKCS#11 implementation may impose further restrictions. session is owned by the caller; after Close it returns errClosed.

func (*PKCS11Lib) GenerateECDSAKeyPairOnSlot

func (lib *PKCS11Lib) GenerateECDSAKeyPairOnSlot(slot uint, id []byte, label []byte, c elliptic.Curve) (*PKCS11PrivateKeyECDSA, error)

GenerateECDSAKeyPairOnSlot creates an ECDSA private key using curve c, on a specified slot.

label and/or id can be nil, in which case a random values will be generated.

Only a limited set of named elliptic curves are supported. The underlying PKCS#11 implementation may impose further restrictions.

func (*PKCS11Lib) GenerateECDSAKeyPairWithLabel

func (lib *PKCS11Lib) GenerateECDSAKeyPairWithLabel(label string, c elliptic.Curve) (*PKCS11PrivateKeyECDSA, error)

GenerateECDSAKeyPairWithLabel creates an ECDSA private key using curve c.

The key will have a random ID.

Only a limited set of named elliptic curves are supported. The underlying PKCS#11 implementation may impose further restrictions.

func (*PKCS11Lib) GenerateRSAKey

func (lib *PKCS11Lib) GenerateRSAKey(label string, bits int, purpose int) (crypto.PrivateKey, error)

GenerateRSAKey generates RSA key pair

func (*PKCS11Lib) GenerateRSAKeyPair

func (lib *PKCS11Lib) GenerateRSAKeyPair(bits int, purpose KeyPurpose) (*PKCS11PrivateKeyRSA, error)

GenerateRSAKeyPair creates an RSA private key of given length.

The key will have a random label and ID.

RSA private keys are generated with both sign and decrypt permissions, and a public exponent of 65537.

func (*PKCS11Lib) GenerateRSAKeyPairOnSession

func (lib *PKCS11Lib) GenerateRSAKeyPairOnSession(
	session pkcs11.SessionHandle, slot uint,
	id []byte,
	label []byte,
	bits int,
	purpose KeyPurpose,
) (*PKCS11PrivateKeyRSA, error)

GenerateRSAKeyPairOnSession creates an RSA private key of given length, on a specified session.

Either or both label and/or id can be nil, in which case a random values will be generated.

RSA private keys are generated with both sign and decrypt permissions, and a public exponent of 65537. session is owned by the caller; after Close it returns errClosed.

func (*PKCS11Lib) GenerateRSAKeyPairOnSlot

func (lib *PKCS11Lib) GenerateRSAKeyPairOnSlot(slot uint, id []byte, label []byte, bits int, purpose KeyPurpose) (*PKCS11PrivateKeyRSA, error)

GenerateRSAKeyPairOnSlot creates a RSA private key on a specified slot

Either or both label and/or id can be nil, in which case a random values will be generated.

func (*PKCS11Lib) GenerateRSAKeyPairWithLabel

func (lib *PKCS11Lib) GenerateRSAKeyPairWithLabel(label string, bits int, purpose KeyPurpose) (*PKCS11PrivateKeyRSA, error)

GenerateRSAKeyPairWithLabel creates an RSA private key of given length.

The key will have a random ID.

RSA private keys are generated with both sign and decrypt permissions, and a public exponent of 65537.

func (*PKCS11Lib) GetKey

func (lib *PKCS11Lib) GetKey(keyID string) (crypto.PrivateKey, error)

GetKey returns private key handle

func (*PKCS11Lib) Identify

func (lib *PKCS11Lib) Identify(object *PKCS11Object) (keyID, label string, err error)

Identify returns the ID and label for a PKCS#11 object.

Either of these values may be used to retrieve the key for later use. The object's Handle is used as given; IdentifyKey, given a private key of this package, also recovers from a handle invalidated by a logout.

func (*PKCS11Lib) IdentifyKey

func (lib *PKCS11Lib) IdentifyKey(priv crypto.PrivateKey) (keyID, label string, err error)

IdentifyKey returns the ID and label for a private key.

func (*PKCS11Lib) KeyInfo

func (lib *PKCS11Lib) KeyInfo(slotID uint, keyID string, includePublic bool) (*cryptoprov.KeyInfo, error)

KeyInfo retrieves info about key with the specified id

func (*PKCS11Lib) ListKeys

func (lib *PKCS11Lib) ListKeys(session pkcs11.SessionHandle, keyclass uint, keytype uint) ([]pkcs11.ObjectHandle, error)

ListKeys returns key objects on the slot matching the key class and type. session is owned by the caller; after Close it returns errClosed.

func (*PKCS11Lib) Manufacturer

func (lib *PKCS11Lib) Manufacturer() string

Manufacturer returns manufacturer for the calling library

func (*PKCS11Lib) Model

func (lib *PKCS11Lib) Model() string

Model returns model for the calling library

func (*PKCS11Lib) NewSession

func (lib *PKCS11Lib) NewSession(slot uint) (pkcs11.SessionHandle, error)

NewSession opens a new RW session on slot. The caller owns the session and must close it with Ctx.CloseSession before Close is called.

func (*PKCS11Lib) TokensInfo

func (lib *PKCS11Lib) TokensInfo() ([]*SlotTokenInfo, error)

TokensInfo returns list of tokens

type PKCS11Object

type PKCS11Object struct {
	// The PKCS#11 object handle at the time the object was found or
	// generated. A logout, or a token removal, invalidates the handles of
	// private objects; the keys this package returns remember their CKA_ID,
	// look their object up again and keep working, while Handle keeps the
	// original value (XPKI-110).
	Handle pkcs11.ObjectHandle

	// The PKCS#11 slot number.
	//
	// This is used internally to find a session handle that can
	// access this object.
	Slot uint
}

PKCS11Object contains a reference to a loaded PKCS#11 object.

type PKCS11PrivateKey

type PKCS11PrivateKey struct {
	PKCS11Object

	// The corresponding public key
	PubKey crypto.PublicKey
}

PKCS11PrivateKey contains a reference to a loaded PKCS#11 private key object.

func (PKCS11PrivateKey) Public

func (p PKCS11PrivateKey) Public() crypto.PublicKey

Public returns the public half of a private key.

This partially implements the go.crypto.Signer and go.crypto.Decrypter interfaces for PKCS11PrivateKey. (The remains of the implementation is in the key-specific types.)

type PKCS11PrivateKeyECDSA

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

PKCS11PrivateKeyECDSA contains a reference to a loaded PKCS#11 ECDSA private key object.

func (*PKCS11PrivateKeyECDSA) Public

func (priv *PKCS11PrivateKeyECDSA) Public() crypto.PublicKey

Public returns the public half of a private key.

This partially implements the go.crypto.Signer and go.crypto.Decrypter interfaces for PKCS11PrivateKey. (The remains of the implementation is in the key-specific types.)

func (*PKCS11PrivateKeyECDSA) Sign

func (priv *PKCS11PrivateKeyECDSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)

Sign signs a message using an ECDSA key.

This completes the implementation of crypto.Signer for PKCS11PrivateKeyECDSA.

PKCS#11 expects to pick its own random data where necessary for signatures, so the rand argument is ignored.

The return value is a DER-encoded byteblock.

type PKCS11PrivateKeyRSA

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

PKCS11PrivateKeyRSA contains a reference to a loaded PKCS#11 RSA private key object.

func (*PKCS11PrivateKeyRSA) Decrypt

func (priv *PKCS11PrivateKeyRSA) Decrypt(rand io.Reader, ciphertext []byte, options crypto.DecrypterOpts) (plaintext []byte, err error)

Decrypt decrypt a message using a RSA key.

This completes the implementation of crypto.Decrypter for PKCS11PrivateKeyRSA.

If options is nil or a *rsa.PKCS1v15DecryptOptions, PKCS#1 v1.5 decryption is performed; a non-zero SessionKeyLen is not supported. If options is a *rsa.OAEPOptions, OAEP decryption is performed.

The underlying PKCS#11 implementation may impose further restrictions.

func (*PKCS11PrivateKeyRSA) Public

func (priv *PKCS11PrivateKeyRSA) Public() crypto.PublicKey

Public returns the public half of a private key.

This partially implements the go.crypto.Signer and go.crypto.Decrypter interfaces for PKCS11PrivateKey. (The remains of the implementation is in the key-specific types.)

func (*PKCS11PrivateKeyRSA) Sign

func (priv *PKCS11PrivateKeyRSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error)

Sign signs a message using a RSA key.

This completes the implementation of crypto.Signer for PKCS11PrivateKeyRSA.

PKCS#11 expects to pick its own random data where necessary for signatures, so the rand argument is ignored.

For PSS, rsa.PSSSaltLengthAuto uses the largest salt the key allows, rsa.PSSSaltLengthEqualsHash uses the hash length, and a positive value is used as-is. For PKCS#1 v1.5 the hash must be one of SHA-1, SHA-224, SHA-256, SHA-384 or SHA-512; other hashes are rejected. The underlying PKCS#11 implementation may impose further restrictions.

func (*PKCS11PrivateKeyRSA) Validate

func (priv *PKCS11PrivateKeyRSA) Validate() error

Validate checks an RSA key.

Since the private key material is not normally available only very limited validation is possible. (The underlying PKCS#11 implementation may perform stricter checking.)

type SlotInfo

type SlotInfo pkcs11.SlotInfo

SlotInfo provides information about a slot.

type SlotTokenInfo

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

SlotTokenInfo provides info about Token on slot

func (*SlotTokenInfo) Description

func (s *SlotTokenInfo) Description() string

Description of the slot

func (*SlotTokenInfo) Label

func (s *SlotTokenInfo) Label() string

Label of the token

func (*SlotTokenInfo) Manufacturer

func (s *SlotTokenInfo) Manufacturer() string

Manufacturer of the token

func (*SlotTokenInfo) Model

func (s *SlotTokenInfo) Model() string

Model of the token

func (*SlotTokenInfo) SerialNumber

func (s *SlotTokenInfo) SerialNumber() string

SerialNumber of the token

func (*SlotTokenInfo) SlotID

func (s *SlotTokenInfo) SlotID() uint

SlotID is ID of the slot

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; empty matches any serial
	TokenSerial() string

	// Token label; empty matches any 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.

Init selects the token by the configured serial number and label: empty fields are ignored, so a token must match every nonempty one, and at least one of them is required. If several tokens match, the first slot wins.

Supply this to Init, or alternatively use ConfigureFromFile.

func LoadTokenConfig

func LoadTokenConfig(filename string) (TokenConfig, error)

LoadTokenConfig loads PKCS#11 token configuration

type TokenInfo

type TokenInfo pkcs11.TokenInfo

TokenInfo provides information about a token.

Jump to

Keyboard shortcuts

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