Skip to content

Commit

Permalink
Replace loadLib with initialize method
Browse files Browse the repository at this point in the history
Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
Signed-off-by: Gari Singh <gari.r.singh@gmail.com>
  • Loading branch information
sykesm committed Aug 22, 2020
1 parent 8a63732 commit 86a5c64
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 115 deletions.
176 changes: 75 additions & 101 deletions bccsp/pkcs11/pkcs11.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ var (
sessionCacheSize = 10
)

type impl struct {
bccsp.BCCSP

slot uint
pin string
ctx *pkcs11.Ctx
sessions chan pkcs11.SessionHandle

conf *config
softVerify bool
immutable bool
}

// New WithParams returns a new instance of the software-based BCCSP
// set at the passed security level, hash family and KeyStore.
func New(opts PKCS11Opts, keyStore bccsp.KeyStore) (bccsp.BCCSP, error) {
Expand All @@ -42,55 +55,58 @@ func New(opts PKCS11Opts, keyStore bccsp.KeyStore) (bccsp.BCCSP, error) {
return nil, errors.Wrapf(err, "Failed initializing configuration")
}

// Check KeyStore
if keyStore == nil {
return nil, errors.New("Invalid bccsp.KeyStore instance. It must be different from nil")
}

swCSP, err := sw.NewWithParams(opts.SecLevel, opts.HashFamily, keyStore)
if err != nil {
return nil, errors.Wrapf(err, "Failed initializing fallback SW BCCSP")
}

lib := opts.Library
pin := opts.Pin
label := opts.Label
ctx, slot, session, err := loadLib(lib, pin, label)
if err != nil {
return nil, errors.Wrapf(err, "Failed initializing PKCS11 library %s %s",
lib, label)
}

sessions := make(chan pkcs11.SessionHandle, sessionCacheSize)
csp := &impl{
BCCSP: swCSP,
conf: conf,
ctx: ctx,
sessions: sessions,
slot: slot,
pin: pin,
lib: lib,
sessions: make(chan pkcs11.SessionHandle, sessionCacheSize),
softVerify: opts.SoftVerify,
immutable: opts.Immutable,
}
csp.returnSession(*session)
return csp, nil

return csp.initialize(opts)
}

type impl struct {
bccsp.BCCSP
func (csp *impl) initialize(opts PKCS11Opts) (*impl, error) {
if opts.Library == "" {
return nil, fmt.Errorf("pkcs11: library path not provided")
}

conf *config
ctx := pkcs11.New(opts.Library)
if ctx == nil {
return nil, fmt.Errorf("pkcs11: instantiation failed for %s", opts.Library)
}

ctx *pkcs11.Ctx
sessions chan pkcs11.SessionHandle
slot uint
pin string
ctx.Initialize()
slots, err := ctx.GetSlotList(true)
if err != nil {
return nil, errors.Wrap(err, "pkcs11: get slot list")
}

lib string
softVerify bool
//Immutable flag makes object immutable
immutable bool
for _, s := range slots {
info, err := ctx.GetTokenInfo(s)
if err != nil || opts.Label != info.Label {
continue
}

csp.ctx = ctx
csp.slot = s
csp.pin = opts.Pin

session, err := createSession(ctx, s, opts.Pin)
if err != nil {
return nil, err
}

csp.returnSession(session)
return csp, nil
}

return nil, errors.Errorf("pkcs11: could not find token with label %s", opts.Label)
}

// KeyGen generates a key using opts.
Expand Down Expand Up @@ -242,74 +258,6 @@ func (csp *impl) Decrypt(k bccsp.Key, ciphertext []byte, opts bccsp.DecrypterOpt
return csp.BCCSP.Decrypt(k, ciphertext, opts)
}

// FindPKCS11Lib IS ONLY USED FOR TESTING
// This is a convenience function. Useful to self-configure, for tests where
// usual configuration is not available.
func FindPKCS11Lib() (lib, pin, label string) {
if lib = os.Getenv("PKCS11_LIB"); lib == "" {
possibilities := []string{
"/usr/lib/softhsm/libsofthsm2.so", //Debian
"/usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so", //Ubuntu
}
for _, path := range possibilities {
if _, err := os.Stat(path); !os.IsNotExist(err) {
lib = path
break
}
}
}
if pin = os.Getenv("PKCS11_PIN"); pin == "" {
pin = "98765432"
}
if label = os.Getenv("PKCS11_LABEL"); label == "" {
label = "ForFabric"
}

return lib, pin, label
}

func loadLib(lib, pin, label string) (*pkcs11.Ctx, uint, *pkcs11.SessionHandle, error) {
var slot uint
logger.Debugf("Loading pkcs11 library [%s]\n", lib)
if lib == "" {
return nil, slot, nil, fmt.Errorf("No PKCS11 library default")
}

ctx := pkcs11.New(lib)
if ctx == nil {
return nil, slot, nil, fmt.Errorf("Instantiate failed [%s]", lib)
}

ctx.Initialize()
slots, err := ctx.GetSlotList(true)
if err != nil {
return nil, slot, nil, fmt.Errorf("Could not get Slot List [%s]", err)
}
found := false
for _, s := range slots {
info, errToken := ctx.GetTokenInfo(s)
if errToken != nil {
continue
}
logger.Debugf("Looking for %s, found label %s\n", label, info.Label)
if label == info.Label {
found = true
slot = s
break
}
}
if !found {
return nil, slot, nil, fmt.Errorf("could not find token with label %s", label)
}

session, err := createSession(ctx, slot, pin)
if err != nil {
return nil, slot, nil, err
}

return ctx, slot, &session, nil
}

func (csp *impl) getSession() (session pkcs11.SessionHandle, err error) {
for {
select {
Expand Down Expand Up @@ -793,3 +741,29 @@ func nextIDCtr() *big.Int {
idMutex.Unlock()
return idCtr
}

// FindPKCS11Lib IS ONLY USED FOR TESTING
// This is a convenience function. Useful to self-configure, for tests where
// usual configuration is not available.
func FindPKCS11Lib() (lib, pin, label string) {
if lib = os.Getenv("PKCS11_LIB"); lib == "" {
possibilities := []string{
"/usr/lib/softhsm/libsofthsm2.so", //Debian
"/usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so", //Ubuntu
}
for _, path := range possibilities {
if _, err := os.Stat(path); !os.IsNotExist(err) {
lib = path
break
}
}
}
if pin = os.Getenv("PKCS11_PIN"); pin == "" {
pin = "98765432"
}
if label = os.Getenv("PKCS11_LABEL"); label == "" {
label = "ForFabric"
}

return lib, pin, label
}
28 changes: 14 additions & 14 deletions bccsp/pkcs11/pkcs11_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func TestNew(t *testing.T) {
opts.Library = ""
_, err = New(opts, currentKS)
require.Error(t, err)
require.Contains(t, err.Error(), "Failed initializing PKCS11 library")
require.Contains(t, err.Error(), "pkcs11: library path not provided")
}

func TestFindPKCS11LibEnvVars(t *testing.T) {
Expand Down Expand Up @@ -1252,29 +1252,29 @@ func TestKeyGenFailures(t *testing.T) {
assert.Contains(t, err.Error(), "Invalid Opts parameter. It must not be nil")
}

func TestLoadLib(t *testing.T) {
func TestInitialize(t *testing.T) {
// Setup PKCS11 library and provide initial set of values
lib, pin, label := FindPKCS11Lib()

// Test for no specified PKCS11 library
_, _, _, err := loadLib("", pin, label)
assert.Error(t, err)
assert.Contains(t, err.Error(), "No PKCS11 library default")
_, err := (&impl{}).initialize(PKCS11Opts{Library: "", Pin: pin, Label: label})
require.Error(t, err)
require.Contains(t, err.Error(), "pkcs11: library path not provided")

// Test for invalid PKCS11 library
_, _, _, err = loadLib("badLib", pin, label)
assert.Error(t, err)
assert.Contains(t, err.Error(), "Instantiate failed")
_, err = (&impl{}).initialize(PKCS11Opts{Library: "badLib", Pin: pin, Label: label})
require.Error(t, err)
require.Contains(t, err.Error(), "pkcs11: instantiation failed for badLib")

// Test for invalid label
_, _, _, err = loadLib(lib, pin, "badLabel")
assert.Error(t, err)
assert.Contains(t, err.Error(), "could not find token with label")
_, err = (&impl{}).initialize(PKCS11Opts{Library: lib, Pin: pin, Label: "badLabel"})
require.Error(t, err)
require.Contains(t, err.Error(), "could not find token with label")

// Test for no pin
_, _, _, err = loadLib(lib, "", label)
assert.Error(t, err)
assert.Contains(t, err.Error(), "Login failed: pkcs11")
_, err = (&impl{}).initialize(PKCS11Opts{Library: lib, Pin: "", Label: label})
require.Error(t, err)
require.Contains(t, err.Error(), "Login failed: pkcs11")
}

func TestNamedCurveFromOID(t *testing.T) {
Expand Down

0 comments on commit 86a5c64

Please sign in to comment.