use slot ids in the cfssl pkcs11 api

It was using TokenLabels solely to select slots but those can have duplicates
on the same HSM. Instead, use slot IDs with them.
This commit is contained in:
Jacob Hoffman-Andrews 2015-09-11 18:30:18 -04:00 committed by Jeff Hodges
parent d55e0e0d8d
commit 43217216c7
6 changed files with 70 additions and 48 deletions

View File

@ -8,6 +8,7 @@ import (
"crypto"
"crypto/rsa"
"errors"
"fmt"
"io"
"math/big"
@ -34,9 +35,13 @@ type PKCS11Key struct {
// The PKCS#11 library to use
module *pkcs11.Ctx
// The name of the slot to be used.
// The slot id of the token to be used. Both this and tokenLabel must match to
// be used.
slotID int
// The label of the token to be used.
// We will automatically search for this in the slot list.
slotDescription string
tokenLabel string
// The PIN to be used to log in to the device
pin string
@ -49,7 +54,7 @@ type PKCS11Key struct {
}
// New instantiates a new handle to a PKCS #11-backed key.
func New(module, slot, pin, privLabel string) (ps *PKCS11Key, err error) {
func New(module, tokenLabel, pin, privLabel string, slotID int) (ps *PKCS11Key, err error) {
// Set up a new pkcs11 object and initialize it
p := pkcs11.New(module)
if p == nil {
@ -63,9 +68,10 @@ func New(module, slot, pin, privLabel string) (ps *PKCS11Key, err error) {
// Initialize a partial key
ps = &PKCS11Key{
module: p,
slotDescription: slot,
pin: pin,
module: p,
slotID: slotID,
tokenLabel: tokenLabel,
pin: pin,
}
// Look up the private key
@ -159,35 +165,38 @@ func (ps *PKCS11Key) Destroy() {
}
func (ps *PKCS11Key) openSession() (session pkcs11.SessionHandle, err error) {
// Find slot by description
slots, err := ps.module.GetSlotList(true)
// Check if there is a PCKS11 token with slots. It has side-effects that
// allow the rest of the code here to work.
_, err = ps.module.GetSlotList(true)
if err != nil {
return
}
for _, slot := range slots {
slotInfo, err := ps.module.GetSlotInfo(slot)
if err != nil {
continue
}
if slotInfo.SlotDescription == ps.slotDescription {
// Open session
session, err = ps.module.OpenSession(slot, pkcs11.CKF_SERIAL_SESSION)
if err != nil {
return session, err
}
// Login
if err = ps.module.Login(session, pkcs11.CKU_USER, ps.pin); err != nil {
return session, err
}
return session, err
}
slotID := uint(ps.slotID)
// Look up slot by id
tokenInfo, err := ps.module.GetTokenInfo(slotID)
if err != nil {
return
}
err = errors.New("slot not found")
return
// Check that token label matches.
if tokenInfo.Label != ps.tokenLabel {
err = fmt.Errorf("Token label in slot %d was '%s', expected '%s'",
slotID, tokenInfo.Label, ps.tokenLabel)
return
}
// Open session
session, err = ps.module.OpenSession(slotID, pkcs11.CKF_SERIAL_SESSION)
if err != nil {
return session, err
}
// Login
if err = ps.module.Login(session, pkcs11.CKU_USER, ps.pin); err != nil {
return session, err
}
return session, err
}
func (ps *PKCS11Key) closeSession(session pkcs11.SessionHandle) {

View File

@ -157,8 +157,16 @@ func loadKey(keyConfig cmd.KeyConfig) (priv crypto.Signer, err error) {
}
pkcs11Config := keyConfig.PKCS11
if pkcs11Config.Module == "" ||
pkcs11Config.TokenLabel == "" ||
pkcs11Config.PIN == "" ||
pkcs11Config.PrivateKeyLabel == "" ||
pkcs11Config.SlotID == nil {
err = fmt.Errorf("Missing a field in pkcs11Config %#v", pkcs11Config)
return
}
priv, err = pkcs11key.New(pkcs11Config.Module,
pkcs11Config.Token, pkcs11Config.PIN, pkcs11Config.Label)
pkcs11Config.TokenLabel, pkcs11Config.PIN, pkcs11Config.PrivateKeyLabel, *pkcs11Config.SlotID)
return
}

View File

@ -226,10 +226,11 @@ type KeyConfig struct {
// PKCS11Config defines how to load a module for an HSM.
type PKCS11Config struct {
Module string
Token string
PIN string
Label string
Module string
TokenLabel string
SlotID *int
PIN string
PrivateKeyLabel string
}
// TLSConfig reprents certificates and a key for authenticated TLS.

View File

@ -22,10 +22,11 @@ import (
// PKCS11Config defines how to load a module for an HSM.
// XXX(rlb@ipv.sx) Copied from certificate-authority.go
type PKCS11Config struct {
Module string
Token string
PIN string
Label string
Module string
TokenLabel string
PrivateKeyLabel string
PIN string
SlotID float64
}
func readFiles(c *cli.Context) (issuer, responder, target *x509.Certificate, template ocsp.Response, pkcs11 PKCS11Config, err error) {
@ -158,7 +159,7 @@ func main() {
cmd.FailOnError(err, "Failed to read files")
// Instantiate the private key from PKCS11
priv, err := pkcs11key.New(pkcs11.Module, pkcs11.Token, pkcs11.PIN, pkcs11.Label)
priv, err := pkcs11key.New(pkcs11.Module, pkcs11.TokenLabel, pkcs11.PIN, pkcs11.PrivateKeyLabel, int(pkcs11.SlotID))
cmd.FailOnError(err, "Failed to load PKCS#11 key")
// Populate the remaining fields in the template

View File

@ -52,16 +52,18 @@ func toPEM(cert *x509.Certificate) []byte {
func main() {
// Instantiate the PKCS11 key
var pkcs11 struct {
Module string
Token string
PIN string
Label string
Module string
TokenLabel string
PIN string
PrivateKeyLabel string
SlotID float64
}
pkcs11Bytes, err := ioutil.ReadFile(pkcs11FileName)
panicOnError(err)
err = json.Unmarshal(pkcs11Bytes, &pkcs11)
panicOnError(err)
p11key, err := pkcs11key.New(pkcs11.Module, pkcs11.Token, pkcs11.PIN, pkcs11.Label)
slotID := int(pkcs11.SlotID)
p11key, err := pkcs11key.New(pkcs11.Module, pkcs11.TokenLabel, pkcs11.PIN, pkcs11.PrivateKeyLabel, slotID)
panicOnError(err)
// All of the certificates start and end at the same time

View File

@ -1,6 +1,7 @@
{
"Module": "/Library/OpenSC/lib/opensc-pkcs11.so",
"Token": "Yubico Yubikey NEO CCID",
"Label": "PIV AUTH key",
"PIN": "123456"
"Module": "/usr/local/Cellar/opensc/0.14.0_1/lib/opensc-pkcs11.so",
"TokenLabel": "PIV_II (PIV Card Holder pin)",
"SlotID": 1,
"PrivateKeyLabel": "SIGN key",
"PIN": "163246"
}