diff --git a/kms/pkcs11/pkcs11.go b/kms/pkcs11/pkcs11.go index 64c1e72a..25b3d447 100644 --- a/kms/pkcs11/pkcs11.go +++ b/kms/pkcs11/pkcs11.go @@ -11,6 +11,7 @@ import ( "fmt" "math/big" "strconv" + "sync" "github.com/ThalesIgnite/crypto11" "github.com/pkg/errors" @@ -43,7 +44,8 @@ var p11Configure = func(config *crypto11.Config) (P11, error) { // PKCS11 is the implementation of a KMS using the PKCS #11 standard. type PKCS11 struct { - p11 P11 + p11 P11 + closed sync.Once } // New returns a new PKCS11 KMS. @@ -232,8 +234,11 @@ func (k *PKCS11) DeleteCertificate(uri string) error { } // Close releases the connection to the PKCS#11 module. -func (k *PKCS11) Close() error { - return errors.Wrap(k.p11.Close(), "error closing pkcs#11 context") +func (k *PKCS11) Close() (err error) { + k.closed.Do(func() { + err = errors.Wrap(k.p11.Close(), "error closing pkcs#11 context") + }) + return } func toByte(s string) []byte { diff --git a/kms/pkcs11/pkcs11_test.go b/kms/pkcs11/pkcs11_test.go index a74fb3fe..77277366 100644 --- a/kms/pkcs11/pkcs11_test.go +++ b/kms/pkcs11/pkcs11_test.go @@ -709,3 +709,21 @@ func TestPKCS11_DeleteCertificate(t *testing.T) { }) } } + +func TestPKCS11_Close(t *testing.T) { + k := mustPKCS11(t) + tests := []struct { + name string + wantErr bool + }{ + {"ok", false}, + {"second", false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := k.Close(); (err != nil) != tt.wantErr { + t.Errorf("PKCS11.Close() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/kms/pkcs11/yubihsm2_test.go b/kms/pkcs11/yubihsm2_test.go index 7d508872..54885070 100644 --- a/kms/pkcs11/yubihsm2_test.go +++ b/kms/pkcs11/yubihsm2_test.go @@ -37,7 +37,7 @@ func mustPKCS11(t TBTesting) *PKCS11 { Pin: "0001password", }) if err != nil { - t.Fatalf("failed to configure yubiHSM2 on %s: %v", runtime.GOOS, err) + t.Fatalf("failed to configure YubiHSM2 on %s: %v", runtime.GOOS, err) } k := &PKCS11{