Skip to content

Commit 5135601

Browse files
fix: allow concurrent sign operations and serialize if not possible
1 parent 1906bae commit 5135601

File tree

6 files changed

+42
-13
lines changed

6 files changed

+42
-13
lines changed

cmd/signing-server/main.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ type Config struct {
7878
HSMKeyLabel string
7979
HSMKeyId string
8080

81-
HSMContext sign.HSMOptions
81+
HSMContext *sign.HSMOptions
8282

8383
// calculated by program
8484
Logger *zap.Logger
@@ -105,6 +105,7 @@ func (c *Config) SetupHSM() error {
105105
TokenLabel: c.HSMTokenLabel,
106106
Slot: slot,
107107
Pin: c.HSMPass,
108+
Logger: c.Logger,
108109
}
109110

110111
ctx, err := crypto11.NewSession(config)
@@ -516,7 +517,7 @@ func RunSigner(cfg *Config, args []string, responseBuilders map[string]encoding.
516517

517518
hashfunc, ok := sign.GetHashFunction(cfg.Hash)
518519
if !ok {
519-
return fmt.Errorf("unknown hash algorith %q", cfg.Hash)
520+
return fmt.Errorf("unknown hash algorithm %q", cfg.Hash)
520521
}
521522

522523
var data []byte

pkg/crypto11/rsa.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ func (s *Session) SignPSS(key pkcs11.ObjectHandle, digest []byte, opts *rsa.PSSO
121121
ulongToBytes(mgf),
122122
ulongToBytes(sLen))
123123
mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_PSS, parameters)}
124+
if s.serialized {
125+
s.mu.Lock()
126+
defer s.mu.Unlock()
127+
}
124128
if err = s.Ctx.SignInit(s.Handle, mech, key); err != nil {
125129
return nil, err
126130
}
@@ -142,6 +146,10 @@ func (s *Session) SignPKCS1v15(key pkcs11.ObjectHandle, digest []byte, hash cryp
142146
copy(T[0:len(oid)], oid)
143147
copy(T[len(oid):], digest)
144148
mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS, nil)}
149+
if s.serialized {
150+
s.mu.Lock()
151+
defer s.mu.Unlock()
152+
}
145153
err = s.Ctx.SignInit(s.Handle, mech, key)
146154
if err == nil {
147155
signature, err = s.Ctx.Sign(s.Handle, T)

pkg/crypto11/session.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ package crypto11
55
import (
66
"encoding/hex"
77
"fmt"
8+
"strings"
9+
"sync"
810

911
"github.com/miekg/pkcs11"
1012
"github.com/pkg/errors"
13+
"go.uber.org/zap"
1114
)
1215

1316
// errTokenNotFound represents the failure to find the requested PKCS#11 token
@@ -18,6 +21,9 @@ var errTokenNotFound = errors.New("could not find PKCS#11 token")
1821
type Session struct {
1922
Ctx *pkcs11.Ctx
2023
Handle pkcs11.SessionHandle
24+
25+
mu sync.Mutex // protects the session if serialized
26+
serialized bool
2127
}
2228

2329
// Config describes the attributes required to access
@@ -34,6 +40,9 @@ type Config struct {
3440
Slot *int
3541
// Pin is the password used to access the described slot.
3642
Pin string
43+
44+
// Logger is an optional logger to use for logging.
45+
Logger *zap.Logger
3746
}
3847

3948
// NewSession provides a session object for working with HSM signing
@@ -60,7 +69,13 @@ func NewSession(cfg *Config) (*Session, error) {
6069
return nil, fmt.Errorf("lookup HSM slots: %w", err)
6170
}
6271

63-
session, err := p.OpenSession(slot, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
72+
var serializedSession bool
73+
session, err := p.OpenSession(slot, 0)
74+
if err != nil && strings.Contains(err.Error(), fmt.Sprintf("0x%X", pkcs11.CKR_SESSION_PARALLEL_NOT_SUPPORTED)) {
75+
session, err = p.OpenSession(slot, pkcs11.CKF_SERIAL_SESSION)
76+
serializedSession = true
77+
cfg.Logger.Warn("opening session in serialized mode as parallel sessions are unsupported", zap.Error(err))
78+
}
6479
if err != nil {
6580
return nil, fmt.Errorf("open HSM session: %w", err)
6681
}
@@ -73,8 +88,9 @@ func NewSession(cfg *Config) (*Session, error) {
7388
}
7489

7590
return &Session{
76-
Ctx: p,
77-
Handle: session,
91+
Ctx: p,
92+
Handle: session,
93+
serialized: serializedSession,
7894
}, nil
7995
}
8096

@@ -134,6 +150,10 @@ func (s *Session) FindPrivateKey(keyId, keyLabel string) (pkcs11.ObjectHandle, e
134150
}
135151
attrs = append(attrs, pkcs11.NewAttribute(pkcs11.CKA_ID, id))
136152
}
153+
if s.serialized {
154+
s.mu.Lock()
155+
defer s.mu.Unlock()
156+
}
137157
if err := s.Ctx.FindObjectsInit(s.Handle, attrs); err != nil {
138158
return 0, fmt.Errorf("HSM get private key handle %q: %w", keyId, err)
139159
}

pkg/handler/sign/handler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ type HSMOptions struct {
1919
Key pkcs11.ObjectHandle
2020
}
2121

22-
func NewHSMOptions(session *crypto11.Session, key pkcs11.ObjectHandle) HSMOptions {
23-
return HSMOptions{
22+
func NewHSMOptions(session *crypto11.Session, key pkcs11.ObjectHandle) *HSMOptions {
23+
return &HSMOptions{
2424
Session: session,
2525
Key: key,
2626
}

pkg/handler/sign/hsm_pkcs1_1_5/handler.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ const (
2222

2323
var mechanism = pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS, nil)
2424

25-
func New(opt sign.HSMOptions) sign.SignHandler {
26-
return &Handler{opt}
25+
func New(opt *sign.HSMOptions) sign.SignHandler {
26+
return &Handler{options: opt}
2727
}
2828

2929
type Handler struct {
30-
options sign.HSMOptions
30+
options *sign.HSMOptions
3131
}
3232

3333
func (h *Handler) Name() string {

pkg/handler/sign/hsm_pss/handler.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ const (
2323

2424
var mechanism = pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_PSS, nil)
2525

26-
func New(opt sign.HSMOptions) sign.SignHandler {
27-
return &Handler{opt}
26+
func New(opt *sign.HSMOptions) sign.SignHandler {
27+
return &Handler{options: opt}
2828
}
2929

3030
type Handler struct {
31-
options sign.HSMOptions
31+
options *sign.HSMOptions
3232
}
3333

3434
func (h *Handler) Name() string {

0 commit comments

Comments
 (0)