Documentation ¶
Overview ¶
Package p11 wraps `miekg/pkcs11` to make it easier to use and more idiomatic to Go, as compared with the more straightforward C wrapper that `miekg/pkcs11` presents. All types are safe to use concurrently.
To use, first you open a module (a dynamically loaded library) by providing its path on your filesystem. This module is typically provided by the maker of your HSM, smartcard, or other cryptographic hardware, or sometimes by your operating system. Common module filenames are opensc-pkcs11.so, libykcs11.so, and libsofthsm2.so (you'll have to find the exact location).
Once you've opened a Module, you can list the slots available with that module. Each slot may or may not contain a token. For instance, if you have a smartcard reader, that's a slot; if there's a smartcard in it, that's the token. Using this package, you can iterate through slots and check their information, and the information about tokens in them.
Once you've found the slot with the token you want to use, you can open a Session with that token using OpenSession. Almost all operations require a session. Sessions use a sync.Mutex to ensure only one operation is active on them at a given time, as required by PKCS#11. If you want to get full performance out of a multi-core HSM, you will need to create multiple sessions.
Once you've got a session, you can login to it. This is not necessary if you only want to access non-sensitive data, like certificates and public keys. However, to use any secret keys on a token, you'll need to login.
Many operations, like FindObjects, return Objects. These represent pieces of data that exist on the token, referring to them by a numeric handle. With objects representing private keys, you can perform operations like signing and decrypting; with public keys and certificates you can extract their values.
To summarize, a typical workflow might look like:
module, err := p11.OpenModule("/path/to/module.so") if err != nil { return err } slots, err := module.Slots() if err != nil { return err } // ... find the appropriate slot, then ... session, err := slots[0].OpenSession() if err != nil { return err } privateKeyObject, err := session.FindObject(...) if err != nil { return err } privateKey := p11.PrivateKey(privateKeyObject) signature, err := privateKey.Sign(..., []byte{"hello"}) if err != nil { return err }
Index ¶
- Variables
- type GenerateKeyPairRequest
- type KeyPair
- type Mechanism
- type Module
- type Object
- func (o Object) Attribute(attributeType uint) ([]byte, error)
- func (o Object) Copy(template []*pkcs11.Attribute) (Object, error)
- func (o Object) Destroy() error
- func (o Object) Label() (string, error)
- func (o Object) Set(attributeType uint, value []byte) error
- func (o Object) Value() ([]byte, error)
- type PrivateKey
- type PublicKey
- type SecretKey
- type Session
- type Slot
- func (s Slot) CloseAllSessions() error
- func (s Slot) ID() uint
- func (s Slot) Info() (pkcs11.SlotInfo, error)
- func (s Slot) InitToken(securityOfficerPIN string, tokenLabel string) error
- func (s Slot) Mechanisms() ([]Mechanism, error)
- func (s Slot) OpenSession() (Session, error)
- func (s Slot) OpenSessionWithFlags(flags uint) (Session, error)
- func (s Slot) OpenWriteSession() (Session, error)
- func (s Slot) TokenInfo() (pkcs11.TokenInfo, error)
Constants ¶
This section is empty.
Variables ¶
var ErrAttributeNotFound = errors.New("attribute not found")
ErrAttributeNotFound is returned by Attrbibute() if the searched attribute isn't found.
var ErrNoObjectsFound = errors.New("no objects found")
ErrNoObjectsFound is returned by FindObject() and FindObjects() if no objects are found.
var ErrTooManyAttributesFound = errors.New("too many attributes found")
ErrTooManyAttributesFound is returned by Attrbibute() if the search returned multiple attributes.
var ErrTooManyObjectsFound = errors.New("too many objects matching template")
ErrTooManyObjectsFound is returned by FindObject() if multiple objects are found.
Functions ¶
This section is empty.
Types ¶
type GenerateKeyPairRequest ¶
type GenerateKeyPairRequest struct { Mechanism pkcs11.Mechanism PublicKeyAttributes []*pkcs11.Attribute PrivateKeyAttributes []*pkcs11.Attribute }
GenerateKeyPairRequest contains the fields used to generate a key pair.
type KeyPair ¶
type KeyPair struct { Public PublicKey Private PrivateKey }
KeyPair contains two Objects: one for a public key and one for a private key. It represents these as PublicKey and PrivateKey types so they can by used for appropriate cryptographic operations.
type Mechanism ¶
type Mechanism struct {
// contains filtered or unexported fields
}
Mechanism represents a cipher, signature algorithm, hash function, or other function that a token can perform.
type Module ¶
type Module struct {
// contains filtered or unexported fields
}
Module represents a PKCS#11 module, and can be used to create Sessions.
func OpenModule ¶
OpenModule loads a PKCS#11 module (a .so file or dynamically loaded library). It's an error to load a PKCS#11 module multiple times, so this package will return a previously loaded Module for the same path if possible. Note that there is no facility to unload a module ("finalize" in PKCS#11 parlance). In general, modules will be unloaded at the end of the process. The only place where you are likely to need to explicitly unload a module is if you fork your process. If you need to fork, you may want to use the lower-level `pkcs11` package.
func (Module) Destroy ¶ added in v1.1.0
func (m Module) Destroy()
Destroy unloads the module/library.
type Object ¶
type Object struct {
// contains filtered or unexported fields
}
Object represents a handle to a PKCS#11 object. It is attached to the session used to find it. Once that session is closed, operations on the Object will fail. Operations may also depend on the logged-in state of the application.
func (Object) Attribute ¶
Attribute gets exactly one attribute from a PKCS#11 object, returning an error if the attribute is not found, or if multiple attributes are returned. On success, it will return the value of that attribute as a slice of bytes. For attributes not present (i.e. CKR_ATTRIBUTE_TYPE_INVALID), Attribute returns a nil slice and nil error.
func (Object) Copy ¶
Copy makes a copy of this object, with the attributes in template applied on top of it, if possible.
type PrivateKey ¶
type PrivateKey Object
PrivateKey is an Object representing a private key. Since any object can be cast to a PrivateKey, it is the user's responsibility to ensure that the object is actually a private key.
type PublicKey ¶
type PublicKey Object
PublicKey is an Object representing a public key. Since any object can be cast to a PublicKey, it is the user's responsibility to ensure that the object is actually a public key. For instance, if you use a FindObjects template that includes CKA_CLASS: CKO_PUBLIC_KEY, you can be confident the resulting object is a public key.
type SecretKey ¶
type SecretKey Object
SecretKey is an Object representing a secret (symmetric) key. Since any object can be cast to a SecretKey, it is the user's responsibility to ensure that the object is actually a secret key. For instance, if you use a FindObjects template that includes CKA_CLASS: CKO_SECRET_KEY, you can be confident the resulting object is a secret key.
type Session ¶
type Session interface { // Login logs into the token as a regular user. Note: According to PKCS#11, // logged-in state is a property of an application, rather than a session, but // you can only log in via a session. Keep this in mind when using multiple // sessions on the same token. Logging in to a token in any session will log // in all sessions on that token, and logging out will do the same. This is // particularly relevant for private keys with CKA_ALWAYS_AUTHENTICATE set // (like Yubikeys in PIV mode). See // https://github.com/letsencrypt/pkcs11key/blob/master/key.go for an example // of managing login state with a mutex. Login(pin string) error // LoginSecurityOfficer logs into the token as the security officer. LoginSecurityOfficer(pin string) error // LoginAs logs into the token with the given user type. LoginAs(userType uint, pin string) error // Logout logs out all sessions from the token (see Login). Logout() error // Close closes the session. Close() error // CreateObject creates an object on the token with the given attributes. CreateObject(template []*pkcs11.Attribute) (Object, error) // FindObject finds a single object in the token that matches the attributes in // the template. It returns error if there is not exactly one result, or if // there was an error during the find calls. FindObject(template []*pkcs11.Attribute) (Object, error) // FindObjects finds any objects in the token matching the template. FindObjects(template []*pkcs11.Attribute) ([]Object, error) // GenerateKeyPair generates a public/private key pair. It takes // GenerateKeyPairRequest instead of individual arguments so that attributes for // public and private keys can't be accidentally switched around. GenerateKeyPair(request GenerateKeyPairRequest) (*KeyPair, error) // GenerateRandom returns random bytes generated by the token. GenerateRandom(length int) ([]byte, error) // InitPIN initialize's the normal user's PIN. InitPIN(pin string) error // SetPIN modifies the PIN of the logged-in user. "old" should contain the // current PIN, and "new" should contain the new PIN to be set. SetPIN(old, new string) error }
Session represents a PKCS#11 session.
type Slot ¶
type Slot struct {
// contains filtered or unexported fields
}
Slot represents a slot that may hold a token.
func (Slot) CloseAllSessions ¶
CloseAllSessions closes all sessions on this slot.
func (Slot) InitToken ¶
InitToken initializes the token in this slot, setting its label to tokenLabel. If the token was not previously initialized, its security officer PIN is set to the provided string. If the token is already initialized, the provided PIN will be checked against the existing security officer PIN, and the token will only be reinitialized if there is a match.
According to PKCS#11: "When a token is initialized, all objects that can be destroyed are destroyed (i.e., all except for 'indestructible' objects such as keys built into the token). Also, access by the normal user is disabled until the SO sets the normal user’s PIN."
func (Slot) Mechanisms ¶
Mechanisms returns a list of Mechanisms available on the token in this slot.
func (Slot) OpenSession ¶
OpenSession opens a read-only session with the token in this slot.
func (Slot) OpenSessionWithFlags ¶ added in v1.1.0
OpenSessionWithFlags opens a serial session using the given flags with the token in this slot. CKF_SERIAL_SESSION is always mandatory (per PKCS#11) for legacy reasons and is internally added before opening a session.
func (Slot) OpenWriteSession ¶
OpenWriteSession opens a read-write session with the token in this slot.