X Tutup
Skip to content

Commit 0834ca4

Browse files
authored
pkcs11helper: add a Session abstraction (letsencrypt#4989)
1 parent 09c060f commit 0834ca4

File tree

11 files changed

+197
-152
lines changed

11 files changed

+197
-152
lines changed

cmd/ceremony/cert.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -317,9 +317,7 @@ func (fr *failReader) Read([]byte) (int, error) {
317317
// PKCS#11 ECDSA signature format and the RFC 5480 one which is required
318318
// for X.509 certificates
319319
type x509Signer struct {
320-
ctx pkcs11helpers.PKCtx
321-
322-
session pkcs11.SessionHandle
320+
session *pkcs11helpers.Session
323321
objectHandle pkcs11.ObjectHandle
324322
keyType pkcs11helpers.KeyType
325323

@@ -330,7 +328,7 @@ type x509Signer struct {
330328
// is converted from the PKCS#11 format to the RFC 5480 format. For RSA keys a
331329
// conversion step is not needed.
332330
func (p *x509Signer) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
333-
signature, err := pkcs11helpers.Sign(p.ctx, p.session, p.objectHandle, p.keyType, digest, opts.HashFunc())
331+
signature, err := p.session.Sign(p.objectHandle, p.keyType, digest, opts.HashFunc())
334332
if err != nil {
335333
return nil, err
336334
}
@@ -359,18 +357,18 @@ func (p *x509Signer) Public() crypto.PublicKey {
359357
// having the actual public key object in order to retrieve the private key
360358
// handle. This is because we already have the key pair object ID, and as such
361359
// do not need to query the HSM to retrieve it.
362-
func newSigner(ctx pkcs11helpers.PKCtx, session pkcs11.SessionHandle, label string, id []byte) (crypto.Signer, error) {
360+
func newSigner(session *pkcs11helpers.Session, label string, id []byte) (crypto.Signer, error) {
363361
// Retrieve the private key handle that will later be used for the certificate
364362
// signing operation
365-
privateHandle, err := pkcs11helpers.FindObject(ctx, session, []*pkcs11.Attribute{
363+
privateHandle, err := session.FindObject([]*pkcs11.Attribute{
366364
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY),
367365
pkcs11.NewAttribute(pkcs11.CKA_LABEL, label),
368366
pkcs11.NewAttribute(pkcs11.CKA_ID, id),
369367
})
370368
if err != nil {
371369
return nil, fmt.Errorf("failed to retrieve private key handle: %s", err)
372370
}
373-
attrs, err := ctx.GetAttributeValue(session, privateHandle, []*pkcs11.Attribute{
371+
attrs, err := session.GetAttributeValue(privateHandle, []*pkcs11.Attribute{
374372
pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, nil)},
375373
)
376374
if err != nil {
@@ -382,7 +380,7 @@ func newSigner(ctx pkcs11helpers.PKCtx, session pkcs11.SessionHandle, label stri
382380

383381
// Retrieve the public key handle with the same CKA_ID as the private key
384382
// and construct a {rsa,ecdsa}.PublicKey for use in x509.CreateCertificate
385-
pubHandle, err := pkcs11helpers.FindObject(ctx, session, []*pkcs11.Attribute{
383+
pubHandle, err := session.FindObject([]*pkcs11.Attribute{
386384
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
387385
pkcs11.NewAttribute(pkcs11.CKA_LABEL, label),
388386
pkcs11.NewAttribute(pkcs11.CKA_ID, id),
@@ -397,14 +395,14 @@ func newSigner(ctx pkcs11helpers.PKCtx, session pkcs11.SessionHandle, label stri
397395
// 0x00000000, CKK_RSA
398396
case bytes.Equal(attrs[0].Value, []byte{0, 0, 0, 0, 0, 0, 0, 0}):
399397
keyType = pkcs11helpers.RSAKey
400-
pub, err = pkcs11helpers.GetRSAPublicKey(ctx, session, pubHandle)
398+
pub, err = session.GetRSAPublicKey(pubHandle)
401399
if err != nil {
402400
return nil, fmt.Errorf("failed to retrieve public key: %s", err)
403401
}
404402
// 0x00000003, CKK_ECDSA
405403
case bytes.Equal(attrs[0].Value, []byte{3, 0, 0, 0, 0, 0, 0, 0}):
406404
keyType = pkcs11helpers.ECDSAKey
407-
pub, err = pkcs11helpers.GetECDSAPublicKey(ctx, session, pubHandle)
405+
pub, err = session.GetECDSAPublicKey(pubHandle)
408406
if err != nil {
409407
return nil, fmt.Errorf("failed to retrieve public key: %s", err)
410408
}
@@ -413,7 +411,6 @@ func newSigner(ctx pkcs11helpers.PKCtx, session pkcs11.SessionHandle, label stri
413411
}
414412

415413
return &x509Signer{
416-
ctx: ctx,
417414
session: session,
418415
objectHandle: privateHandle,
419416
keyType: keyType,

cmd/ceremony/cert_test.go

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
)
2121

2222
func TestX509Signer(t *testing.T) {
23-
ctx := pkcs11helpers.MockCtx{}
23+
s, ctx := pkcs11helpers.NewSessionWithMock()
2424

2525
// test that x509Signer.Sign properly converts the PKCS#11 format signature to
2626
// the RFC 5480 format signature
@@ -51,7 +51,7 @@ func TestX509Signer(t *testing.T) {
5151
return append(rBytes, sBytes...), nil
5252
}
5353
digest := sha256.Sum256([]byte("hello"))
54-
signer := &x509Signer{ctx: ctx, keyType: pkcs11helpers.ECDSAKey, pub: tk.Public()}
54+
signer := &x509Signer{session: s, keyType: pkcs11helpers.ECDSAKey, pub: tk.Public()}
5555
signature, err := signer.Sign(nil, digest[:], crypto.SHA256)
5656
test.AssertNotError(t, err, "x509Signer.Sign failed")
5757

@@ -78,9 +78,9 @@ func TestParseOID(t *testing.T) {
7878
}
7979

8080
func TestMakeTemplate(t *testing.T) {
81-
ctx := pkcs11helpers.MockCtx{}
81+
s, ctx := pkcs11helpers.NewSessionWithMock()
8282
profile := &certProfile{}
83-
randReader := newRandReader(&ctx, 0)
83+
randReader := newRandReader(s)
8484

8585
pubKey, err := hex.DecodeString("3059301306072a8648ce3d020106082a8648ce3d03010703420004b06745ef0375c9c54057098f077964e18d3bed0aacd54545b16eab8c539b5768cc1cea93ba56af1e22a7a01c33048c8885ed17c9c55ede70649b707072689f5e")
8686
test.AssertNotError(t, err, "failed to decode test public key")
@@ -157,14 +157,13 @@ func TestMakeTemplate(t *testing.T) {
157157
}
158158

159159
func TestMakeTemplateOCSP(t *testing.T) {
160-
ctx := pkcs11helpers.MockCtx{
161-
GenerateRandomFunc: func(_ pkcs11.SessionHandle, length int) ([]byte, error) {
162-
r := make([]byte, length)
163-
_, err := rand.Read(r)
164-
return r, err
165-
},
160+
s, ctx := pkcs11helpers.NewSessionWithMock()
161+
ctx.GenerateRandomFunc = func(_ pkcs11.SessionHandle, length int) ([]byte, error) {
162+
r := make([]byte, length)
163+
_, err := rand.Read(r)
164+
return r, err
166165
}
167-
randReader := newRandReader(&ctx, 0)
166+
randReader := newRandReader(s)
168167
profile := &certProfile{
169168
SignatureAlgorithm: "SHA256WithRSA",
170169
CommonName: "common name",
@@ -206,14 +205,13 @@ func TestMakeTemplateOCSP(t *testing.T) {
206205
}
207206

208207
func TestMakeTemplateCRL(t *testing.T) {
209-
ctx := pkcs11helpers.MockCtx{
210-
GenerateRandomFunc: func(_ pkcs11.SessionHandle, length int) ([]byte, error) {
211-
r := make([]byte, length)
212-
_, err := rand.Read(r)
213-
return r, err
214-
},
208+
s, ctx := pkcs11helpers.NewSessionWithMock()
209+
ctx.GenerateRandomFunc = func(_ pkcs11.SessionHandle, length int) ([]byte, error) {
210+
r := make([]byte, length)
211+
_, err := rand.Read(r)
212+
return r, err
215213
}
216-
randReader := newRandReader(&ctx, 0)
214+
randReader := newRandReader(s)
217215
profile := &certProfile{
218216
SignatureAlgorithm: "SHA256WithRSA",
219217
CommonName: "common name",
@@ -462,13 +460,13 @@ func TestVerifyProfile(t *testing.T) {
462460
}
463461

464462
func TestGetKey(t *testing.T) {
465-
ctx := pkcs11helpers.MockCtx{}
463+
s, ctx := pkcs11helpers.NewSessionWithMock()
466464

467465
// test newSigner fails when pkcs11helpers.FindObject for private key handle fails
468466
ctx.FindObjectsInitFunc = func(pkcs11.SessionHandle, []*pkcs11.Attribute) error {
469467
return errors.New("broken")
470468
}
471-
_, err := newSigner(ctx, 0, "label", []byte{255, 255})
469+
_, err := newSigner(s, "label", []byte{255, 255})
472470
test.AssertError(t, err, "newSigner didn't fail when pkcs11helpers.FindObject for private key handle failed")
473471

474472
// test newSigner fails when GetAttributeValue fails
@@ -484,14 +482,14 @@ func TestGetKey(t *testing.T) {
484482
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
485483
return nil, errors.New("broken")
486484
}
487-
_, err = newSigner(ctx, 0, "label", []byte{255, 255})
485+
_, err = newSigner(s, "label", []byte{255, 255})
488486
test.AssertError(t, err, "newSigner didn't fail when GetAttributeValue for private key type failed")
489487

490488
// test newSigner fails when GetAttributeValue returns no attributes
491489
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
492490
return nil, nil
493491
}
494-
_, err = newSigner(ctx, 0, "label", []byte{255, 255})
492+
_, err = newSigner(s, "label", []byte{255, 255})
495493
test.AssertError(t, err, "newSigner didn't fail when GetAttributeValue for private key type returned no attributes")
496494

497495
// test newSigner fails when pkcs11helpers.FindObject for public key handle fails
@@ -504,7 +502,7 @@ func TestGetKey(t *testing.T) {
504502
}
505503
return nil
506504
}
507-
_, err = newSigner(ctx, 0, "label", []byte{255, 255})
505+
_, err = newSigner(s, "label", []byte{255, 255})
508506
test.AssertError(t, err, "newSigner didn't fail when pkcs11helpers.FindObject for public key handle failed")
509507

510508
// test newSigner fails when pkcs11helpers.FindObject for private key returns unknown CKA_KEY_TYPE
@@ -514,21 +512,21 @@ func TestGetKey(t *testing.T) {
514512
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
515513
return []*pkcs11.Attribute{pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, []byte{2, 0, 0, 0, 0, 0, 0, 0})}, nil
516514
}
517-
_, err = newSigner(ctx, 0, "label", []byte{255, 255})
515+
_, err = newSigner(s, "label", []byte{255, 255})
518516
test.AssertError(t, err, "newSigner didn't fail when GetAttributeValue for private key returned unknown key type")
519517

520518
// test newSigner fails when GetRSAPublicKey fails
521519
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
522520
return []*pkcs11.Attribute{pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, []byte{0, 0, 0, 0, 0, 0, 0, 0})}, nil
523521
}
524-
_, err = newSigner(ctx, 0, "label", []byte{255, 255})
522+
_, err = newSigner(s, "label", []byte{255, 255})
525523
test.AssertError(t, err, "newSigner didn't fail when GetRSAPublicKey fails")
526524

527525
// test newSigner fails when GetECDSAPublicKey fails
528526
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
529527
return []*pkcs11.Attribute{pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, []byte{3, 0, 0, 0, 0, 0, 0, 0})}, nil
530528
}
531-
_, err = newSigner(ctx, 0, "label", []byte{255, 255})
529+
_, err = newSigner(s, "label", []byte{255, 255})
532530
test.AssertError(t, err, "newSigner didn't fail when GetECDSAPublicKey fails")
533531

534532
// test newSigner works when everything... works
@@ -548,6 +546,6 @@ func TestGetKey(t *testing.T) {
548546
}
549547
return returns, nil
550548
}
551-
_, err = newSigner(ctx, 0, "label", []byte{255, 255})
549+
_, err = newSigner(s, "label", []byte{255, 255})
552550
test.AssertNotError(t, err, "newSigner failed when everything worked properly")
553551
}

cmd/ceremony/ecdsa.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,11 @@ func ecArgs(label string, curve elliptic.Curve, keyID []byte) generateArgs {
7676
// handle, and constructs an ecdsa.PublicKey. It also checks that the key is of
7777
// the correct curve type.
7878
func ecPub(
79-
ctx pkcs11helpers.PKCtx,
80-
session pkcs11.SessionHandle,
79+
session *pkcs11helpers.Session,
8180
object pkcs11.ObjectHandle,
8281
expectedCurve elliptic.Curve,
8382
) (*ecdsa.PublicKey, error) {
84-
pubKey, err := pkcs11helpers.GetECDSAPublicKey(ctx, session, object)
83+
pubKey, err := session.GetECDSAPublicKey(object)
8584
if err != nil {
8685
return nil, err
8786
}
@@ -97,9 +96,9 @@ func ecPub(
9796
// private key on the device, specified by the provided object handle, by signing
9897
// a nonce generated on the device and verifying the returned signature using the
9998
// public key.
100-
func ecVerify(ctx pkcs11helpers.PKCtx, session pkcs11.SessionHandle, object pkcs11.ObjectHandle, pub *ecdsa.PublicKey) error {
99+
func ecVerify(session *pkcs11helpers.Session, object pkcs11.ObjectHandle, pub *ecdsa.PublicKey) error {
101100
nonce := make([]byte, 4)
102-
_, err := newRandReader(ctx, session).Read(nonce)
101+
_, err := newRandReader(session).Read(nonce)
103102
if err != nil {
104103
return fmt.Errorf("failed to construct nonce: %s", err)
105104
}
@@ -108,7 +107,7 @@ func ecVerify(ctx pkcs11helpers.PKCtx, session pkcs11.SessionHandle, object pkcs
108107
hashFunc.Write(nonce)
109108
digest := hashFunc.Sum(nil)
110109
log.Printf("\tMessage %s hash: %X\n", hashToString[curveToHash[pub.Curve]], digest)
111-
signature, err := pkcs11helpers.Sign(ctx, session, object, pkcs11helpers.ECDSAKey, digest, curveToHash[pub.Curve])
110+
signature, err := session.Sign(object, pkcs11helpers.ECDSAKey, digest, curveToHash[pub.Curve])
112111
if err != nil {
113112
return err
114113
}
@@ -126,31 +125,31 @@ func ecVerify(ctx pkcs11helpers.PKCtx, session pkcs11.SessionHandle, object pkcs
126125
// specified by curveStr and with the provided label. It returns the public
127126
// part of the generated key pair as a ecdsa.PublicKey and the random key ID
128127
// that the HSM uses to identify the key pair.
129-
func ecGenerate(ctx pkcs11helpers.PKCtx, session pkcs11.SessionHandle, label, curveStr string) (*ecdsa.PublicKey, []byte, error) {
128+
func ecGenerate(session *pkcs11helpers.Session, label, curveStr string) (*ecdsa.PublicKey, []byte, error) {
130129
curve, present := stringToCurve[curveStr]
131130
if !present {
132131
return nil, nil, fmt.Errorf("curve %q not supported", curveStr)
133132
}
134133
keyID := make([]byte, 4)
135-
_, err := newRandReader(ctx, session).Read(keyID)
134+
_, err := newRandReader(session).Read(keyID)
136135
if err != nil {
137136
return nil, nil, err
138137
}
139138
log.Printf("Generating ECDSA key with curve %s and ID %x\n", curveStr, keyID)
140139
args := ecArgs(label, curve, keyID)
141-
pub, priv, err := ctx.GenerateKeyPair(session, args.mechanism, args.publicAttrs, args.privateAttrs)
140+
pub, priv, err := session.GenerateKeyPair(args.mechanism, args.publicAttrs, args.privateAttrs)
142141
if err != nil {
143142
return nil, nil, err
144143
}
145144
log.Println("Key generated")
146145
log.Println("Extracting public key")
147-
pk, err := ecPub(ctx, session, pub, curve)
146+
pk, err := ecPub(session, pub, curve)
148147
if err != nil {
149148
return nil, nil, err
150149
}
151150
log.Println("Extracted public key")
152151
log.Println("Verifying public key")
153-
err = ecVerify(ctx, session, priv, pk)
152+
err = ecVerify(session, priv, pk)
154153
if err != nil {
155154
return nil, nil, err
156155
}

0 commit comments

Comments
 (0)
X Tutup