Documentation ¶
Overview ¶
Access cryptographic keys from PKCS#11 using Go crypto API.
For simple use:
1. Either write a configuration file (see ConfigureFromFile) or define a configuration in your application (see PKCS11Config and Configure). This will identify the PKCS#11 library and token to use, and contain the password (or "PIN" in PKCS#11 terminology) to use if the token requires login.
2. Create keys with GenerateDSAKeyPair, GenerateRSAKeyPair and GenerateECDSAKeyPair. The keys you get back implement the standard Go crypto.Signer interface (and crypto.Decrypter, for RSA). They are automatically persisted under random a randomly generated label and ID (use the Identify method to discover them).
3. Retrieve existing keys with FindKeyPair. The return value is a Go crypto.PrivateKey; it may be converted either to crypto.Signer or to *PKCS11PrivateKeyDSA, *PKCS11PrivateKeyECDSA or *PKCS11PrivateKeyRSA.
Sessions and concurrency:
Note that PKCS#11 session handles must not be used concurrently from multiple threads. Consumers of the Signer interface know nothing of this and expect to be able to sign from multiple threads without constraint. We address this as follows.
1. PKCS11Object captures both the object handle and the slot ID for an object.
2. For each slot we maintain a pool of read-write sessions. The pool expands dynamically up to an (undocumented) limit.
3. Each operation transiently takes a session from the pool. They have exclusive use of the session, meeting PKCS#11's concurrency requirements.
The details are, partially, exposed in the API; since the target use case is PKCS#11-unaware operation it may be that the API as it stands isn't good enough for PKCS#11-aware applications. Feedback welcome.
See also https://golang.org/pkg/crypto/
Index ¶
- Variables
- func Configure(config *PKCS11Config) (*pkcs11.Ctx, error)
- func ConfigureFromFile(configLocation string) (*pkcs11.Ctx, error)
- func FindKeyPair(id []byte, label []byte) (crypto.PrivateKey, error)
- func FindKeyPairOnSession(session pkcs11.SessionHandle, slot uint, id []byte, label []byte) (crypto.PrivateKey, error)
- func FindKeyPairOnSlot(slot uint, id []byte, label []byte) (crypto.PrivateKey, error)
- type PKCS11Config
- type PKCS11Object
- type PKCS11PrivateKey
- type PKCS11PrivateKeyDSA
- func GenerateDSAKeyPair(params *dsa.Parameters) (*PKCS11PrivateKeyDSA, error)
- func GenerateDSAKeyPairOnSession(session pkcs11.SessionHandle, slot uint, id []byte, label []byte, ...) (*PKCS11PrivateKeyDSA, error)
- func GenerateDSAKeyPairOnSlot(slot uint, id []byte, label []byte, params *dsa.Parameters) (*PKCS11PrivateKeyDSA, error)
- type PKCS11PrivateKeyECDSA
- func GenerateECDSAKeyPair(c elliptic.Curve) (*PKCS11PrivateKeyECDSA, error)
- func GenerateECDSAKeyPairOnSession(session pkcs11.SessionHandle, slot uint, id []byte, label []byte, ...) (*PKCS11PrivateKeyECDSA, error)
- func GenerateECDSAKeyPairOnSlot(slot uint, id []byte, label []byte, c elliptic.Curve) (*PKCS11PrivateKeyECDSA, error)
- type PKCS11PrivateKeyRSA
- func GenerateRSAKeyPair(bits int) (*PKCS11PrivateKeyRSA, error)
- func GenerateRSAKeyPairOnSession(session pkcs11.SessionHandle, slot uint, id []byte, label []byte, bits int) (*PKCS11PrivateKeyRSA, error)
- func GenerateRSAKeyPairOnSlot(slot uint, id []byte, label []byte, bits int) (*PKCS11PrivateKeyRSA, error)
- func (decrypter *PKCS11PrivateKeyRSA) Decrypt(rand io.Reader, ciphertext []byte, options crypto.DecrypterOpts) (plaintext []byte, err error)
- func (signer *PKCS11PrivateKeyRSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error)
- func (priv *PKCS11PrivateKeyRSA) Validate() error
- type PKCS11RandReader
Constants ¶
This section is empty.
Variables ¶
var ErrCannotGetRandomData = errors.New("crypto11: cannot get random data from PKCS#11")
ErrCannotGetRandomData is returned when the PKCS#11 library fails to return enough random data
var ErrCannotOpenPKCS11 = errors.New("crypto11: could not open PKCS#11")
ErrCannotOpenPKCS11 is returned when the PKCS#11 library cannot be opened
var ErrKeyNotFound = errors.New("crypto11: could not find PKCS#11 key")
ErrKeyNotFound represents the failure to find the requested PKCS#11 key
var ErrMalformedDER = errors.New("crypto11: malformed DER message")
ErrMalformedDER represents a failure to decode an ASN.1-encoded message
var ErrMalformedPoint = errors.New("crypto11/ecdsa: malformed elliptic curve point")
ErrMalformedPoint is returned when crypto.elliptic.Unmarshal cannot decode a point.
var ErrMalformedRSAKey = errors.New("crypto11/rsa: malformed RSA key")
ErrMalformedRSAKey is returned when an RSA key is not in a suitable form.
Currently this means that the public exponent is either bigger than 32 bits, or less than 2.
var ErrMalformedSignature = errors.New("crypto11xo: malformed signature")
ErrMalformedDER represents a failure to decode a signature. This means the PKCS#11 library has returned an empty or odd-length byte string.
var ErrNotConfigured = errors.New("crypto11: PKCS#11 not yet configured")
ErrNotConfigured is returned when the PKCS#11 library is not configured
var ErrTokenNotFound = errors.New("crypto11: could not find PKCS#11 token")
ErrTokenNotFound represents the failure to find the requested PKCS#11 token
var ErrUnrecognizedRSAOptions = errors.New("crypto11/rsa: unrecognized RSA options type")
ErrUnrecognizedRSAOptions is returned when unrecognized options structures are pased to Sign or Decrypt.
var ErrUnsupportedEllipticCurve = errors.New("crypto11/ecdsa: unsupported elliptic curve")
ErrUnsupportedEllipticCurve is returned when an elliptic curve unsupported by crypto11 is specified. Note that the error behavior for an elliptic curve unsupported by the underlying PKCS#11 implementation will be different.
var ErrUnsupportedKeyType = errors.New("crypto11: unrecognized key type")
ErrUnsupportedKeyType is returned when the PKCS#11 library returns a key type that isn't supported
var ErrUnsupportedRSAOptions = errors.New("crypto11/rsa: unsupported RSA option value")
ErrUnsupportedRSAOptions is returned when an unsupported RSA option is requested.
Currently this means a nontrivial SessionKeyLen when decrypting; or an unsupported hash function; or crypto.rsa.PSSSaltLengthAuto was requested.
Functions ¶
func Configure ¶
func Configure(config *PKCS11Config) (*pkcs11.Ctx, error)
Configure configures PKCS#11 from a PKCS11Config.
The PKCS#11 library context is returned, allowing a PKCS#11-aware application to make use of it. Non-aware appliations may ignore it.
Unsually, these values may be present even if the error is non-nil. This corresponds to the case that the library has already been configured. Note that it is NOT reconfigured so if you supply a different configuration the second time, it will be ignored in favor of the first configuration.
If config is nil, and the library has already been configured, the context from the first configuration is returned (and the error will be nil in this case).
func ConfigureFromFile ¶
ConfigureFromFile configures PKCS#11 from a name configuration file.
Configuration files are a JSON representation of the PKCSConfig object. The return value is as for Configure().
Note that if CRYPTO11_CONFIG_PATH is set in the environment, configuration will be read from that file, overriding any later runtime configuration.
func FindKeyPair ¶
func FindKeyPair(id []byte, label []byte) (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 FindKeyPairOnSession ¶
func FindKeyPairOnSession(session pkcs11.SessionHandle, slot uint, id []byte, label []byte) (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.
func FindKeyPairOnSlot ¶
FindKeyPairOnSession 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.
Types ¶
type PKCS11Config ¶
type PKCS11Config struct { // Full path to PKCS#11 library Path string // Token serial number TokenSerial string // Token label TokenLabel string // User PIN (password) Pin string }
PKCS11Config holds PKCS#11 configuration information.
A token may be identified either by serial number or label. If both are specified then the first match wins.
Supply this to Configure(), or alternatively use ConfigureFromFile().
type PKCS11Object ¶
type PKCS11Object struct { // The PKCS#11 object handle. 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 (signer 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 PKCS11PrivateKeyDSA ¶
type PKCS11PrivateKeyDSA struct {
PKCS11PrivateKey
}
PKCS11PrivateKeyDSA contains a reference to a loaded PKCS#11 DSA private key object.
func GenerateDSAKeyPair ¶
func GenerateDSAKeyPair(params *dsa.Parameters) (*PKCS11PrivateKeyDSA, error)
GenerateDSAKeyPair creates a DSA private key on the default slot
The key will have a random label and ID.
func GenerateDSAKeyPairOnSession ¶
func GenerateDSAKeyPairOnSession(session pkcs11.SessionHandle, slot uint, id []byte, label []byte, params *dsa.Parameters) (*PKCS11PrivateKeyDSA, error)
GenerateDSAKeyPairOnSession creates a DSA private key using a specified session
Either or both label and/or id can be nil, in which case a random values will be generated.
func GenerateDSAKeyPairOnSlot ¶
func GenerateDSAKeyPairOnSlot(slot uint, id []byte, label []byte, params *dsa.Parameters) (*PKCS11PrivateKeyDSA, error)
GenerateDSAKeyPairOnSession creates a DSA 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 (*PKCS11PrivateKeyDSA) Sign ¶
func (signer *PKCS11PrivateKeyDSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error)
Sign signs a message using a DSA key.
This completes the implemention of crypto.Signer for PKCS11PrivateKeyDSA.
PKCS#11 expects to pick its own random data for signatures, so the rand argument is ignored.
The return value is a DER-encoded byteblock.
type PKCS11PrivateKeyECDSA ¶
type PKCS11PrivateKeyECDSA struct {
PKCS11PrivateKey
}
PKCS11PrivateKeyECDSA contains a reference to a loaded PKCS#11 ECDSA private key object.
func GenerateECDSAKeyPair ¶
func 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 GenerateECDSAKeyPairOnSession ¶
func 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.
func GenerateECDSAKeyPairOnSlot ¶
func GenerateECDSAKeyPairOnSlot(slot uint, id []byte, label []byte, c elliptic.Curve) (*PKCS11PrivateKeyECDSA, error)
GenerateECDSAKeyPairOnSession 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 (*PKCS11PrivateKeyECDSA) Sign ¶
func (signer *PKCS11PrivateKeyECDSA) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)
Sign signs a message using an ECDSA key.
This completes the implemention 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 {
PKCS11PrivateKey
}
PKCS11PrivateKeyRSA contains a reference to a loaded PKCS#11 RSA private key object.
func GenerateRSAKeyPair ¶
func GenerateRSAKeyPair(bits int) (*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 GenerateRSAKeyPairOnSession ¶
func GenerateRSAKeyPairOnSession(session pkcs11.SessionHandle, slot uint, id []byte, label []byte, bits int) (*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.
func GenerateRSAKeyPairOnSlot ¶
func GenerateRSAKeyPairOnSlot(slot uint, id []byte, label []byte, bits int) (*PKCS11PrivateKeyRSA, error)
GenerateRSAKeyPairOnSession 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 (*PKCS11PrivateKeyRSA) Decrypt ¶
func (decrypter *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 implemention of crypto.Decrypter for PKCS11PrivateKeyRSA.
Note that the SessionKeyLen option (for PKCS#1v1.5 decryption) is not supported.
The underlying PKCS#11 implementation may impose further restrictions.
func (*PKCS11PrivateKeyRSA) Sign ¶
func (signer *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 implemention of crypto.Signer for PKCS11PrivateKeyRSA.
PKCS#11 expects to pick its own random data where necessary for signatures, so the rand argument is ignored.
Note that (at present) the crypto.rsa.PSSSaltLengthAuto option is not supported. The caller must either use crypto.rsa.PSSSaltLengthEqualsHash (recommended) or pass an explicit salt length. Moreover 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.)