p11

package
v1.1.1 Latest Latest
Warning

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

Go to latest
Published: Jan 5, 2022 License: BSD-3-Clause Imports: 4 Imported by: 15

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

Constants

This section is empty.

Variables

View Source
var ErrAttributeNotFound = errors.New("attribute not found")

ErrAttributeNotFound is returned by Attrbibute() if the searched attribute isn't found.

View Source
var ErrNoObjectsFound = errors.New("no objects found")

ErrNoObjectsFound is returned by FindObject() and FindObjects() if no objects are found.

View Source
var ErrTooManyAttributesFound = errors.New("too many attributes found")

ErrTooManyAttributesFound is returned by Attrbibute() if the search returned multiple attributes.

View Source
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.

func (*Mechanism) Info

func (m *Mechanism) Info() (pkcs11.MechanismInfo, error)

Info returns information about this mechanism.

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

func OpenModule(path string) (Module, error)

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.

func (Module) Info

func (m Module) Info() (pkcs11.Info, error)

Info returns general information about the module.

func (Module) Slots

func (m Module) Slots() ([]Slot, error)

Slots returns all available Slots that have a token present.

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

func (o Object) Attribute(attributeType uint) ([]byte, error)

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

func (o Object) Copy(template []*pkcs11.Attribute) (Object, error)

Copy makes a copy of this object, with the attributes in template applied on top of it, if possible.

func (Object) Destroy

func (o Object) Destroy() error

Destroy destroys this object.

func (Object) Label

func (o Object) Label() (string, error)

Label returns the label of an object.

func (Object) Set

func (o Object) Set(attributeType uint, value []byte) error

Set sets exactly one attribute on this object.

func (Object) Value

func (o Object) Value() ([]byte, error)

Value returns an object's CKA_VALUE attribute, as bytes.

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.

func (PrivateKey) Decrypt

func (priv PrivateKey) Decrypt(mechanism pkcs11.Mechanism, ciphertext []byte) ([]byte, error)

Decrypt decrypts the input with a given mechanism.

func (PrivateKey) Sign

func (priv PrivateKey) Sign(mechanism pkcs11.Mechanism, message []byte) ([]byte, error)

Sign signs the input with a given mechanism.

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.

func (PublicKey) Encrypt

func (pub PublicKey) Encrypt(mechanism pkcs11.Mechanism, plaintext []byte) ([]byte, error)

Encrypt encrypts a plaintext with a given mechanism.

func (PublicKey) Verify

func (pub PublicKey) Verify(mechanism pkcs11.Mechanism, message, signature []byte) error

Verify verifies a signature over a message with a given mechanism.

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.

func (SecretKey) Decrypt

func (secret SecretKey) Decrypt(mechanism pkcs11.Mechanism, ciphertext []byte) ([]byte, error)

Decrypt decrypts the input with a given mechanism.

func (SecretKey) Encrypt

func (secret SecretKey) Encrypt(mechanism pkcs11.Mechanism, plaintext []byte) ([]byte, error)

Encrypt encrypts a plaintext with a given mechanism.

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

func (s Slot) CloseAllSessions() error

CloseAllSessions closes all sessions on this slot.

func (Slot) ID

func (s Slot) ID() uint

ID returns the slot's ID.

func (Slot) Info

func (s Slot) Info() (pkcs11.SlotInfo, error)

Info returns information about the Slot.

func (Slot) InitToken

func (s Slot) InitToken(securityOfficerPIN string, tokenLabel string) error

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

func (s Slot) Mechanisms() ([]Mechanism, error)

Mechanisms returns a list of Mechanisms available on the token in this slot.

func (Slot) OpenSession

func (s Slot) OpenSession() (Session, error)

OpenSession opens a read-only session with the token in this slot.

func (Slot) OpenSessionWithFlags added in v1.1.0

func (s Slot) OpenSessionWithFlags(flags uint) (Session, error)

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

func (s Slot) OpenWriteSession() (Session, error)

OpenWriteSession opens a read-write session with the token in this slot.

func (Slot) TokenInfo

func (s Slot) TokenInfo() (pkcs11.TokenInfo, error)

TokenInfo returns information about the token in a Slot, if applicable.

Jump to

Keyboard shortcuts

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