Merge master

This commit is contained in:
Richard Barnes 2015-09-13 20:56:59 -04:00
commit 2fccc3e2a5
8 changed files with 72 additions and 50 deletions

View File

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

View File

@ -226,10 +226,11 @@ type KeyConfig struct {
// PKCS11Config defines how to load a module for an HSM. // PKCS11Config defines how to load a module for an HSM.
type PKCS11Config struct { type PKCS11Config struct {
Module string Module string
Token string TokenLabel string
PIN string SlotID *int
Label string PIN string
PrivateKeyLabel string
} }
// TLSConfig reprents certificates and a key for authenticated TLS. // 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. // PKCS11Config defines how to load a module for an HSM.
// XXX(rlb@ipv.sx) Copied from certificate-authority.go // XXX(rlb@ipv.sx) Copied from certificate-authority.go
type PKCS11Config struct { type PKCS11Config struct {
Module string Module string
Token string TokenLabel string
PIN string PrivateKeyLabel string
Label string PIN string
SlotID float64
} }
func readFiles(c *cli.Context) (issuer, responder, target *x509.Certificate, template ocsp.Response, pkcs11 PKCS11Config, err error) { 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") cmd.FailOnError(err, "Failed to read files")
// Instantiate the private key from PKCS11 // 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") cmd.FailOnError(err, "Failed to load PKCS#11 key")
// Populate the remaining fields in the template // Populate the remaining fields in the template

View File

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

View File

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

View File

@ -258,7 +258,7 @@ func assertAuthzEqual(t *testing.T, a1, a2 core.Authorization) {
if a1.Expires == nil && a2.Expires == nil { if a1.Expires == nil && a2.Expires == nil {
return return
} else if a1.Expires == nil || a2.Expires == nil { } else if a1.Expires == nil || a2.Expires == nil {
t.Errorf("one and only one of authorization's Expires was nil; ret %s, DB %s", a1, a2) t.Errorf("one and only one of authorization's Expires was nil; ret %+v, DB %+v", a1, a2)
} else { } else {
test.Assert(t, a1.Expires.Equal(*a2.Expires), "ret != DB: Expires") test.Assert(t, a1.Expires.Equal(*a2.Expires), "ret != DB: Expires")
} }

View File

@ -433,7 +433,7 @@ func TestMarkCertificateRevoked(t *testing.T) {
test.AssertNotError(t, err, "Failed to fetch certificate status") test.AssertNotError(t, err, "Failed to fetch certificate status")
if code != afterStatus.RevokedReason { if code != afterStatus.RevokedReason {
t.Errorf("RevokedReasons, expected %s, got %s", code, afterStatus.RevokedReason) t.Errorf("RevokedReasons, expected %d, got %d", code, afterStatus.RevokedReason)
} }
if !fc.Now().Equal(afterStatus.RevokedDate) { if !fc.Now().Equal(afterStatus.RevokedDate) {
t.Errorf("RevokedData, expected %s, got %s", fc.Now(), afterStatus.RevokedDate) t.Errorf("RevokedData, expected %s, got %s", fc.Now(), afterStatus.RevokedDate)