From 0c4557c6e33237f39737f94b69fc6154ea0f4587 Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Thu, 3 Nov 2022 07:53:44 +0000 Subject: [PATCH] p11: Add cast methods to Object Expecting the user to manually cast Objects to Keys is counterintuitive, and also blocks converting the Object and Key structs into interfaces (since the cast targets will not be exported). Adding an explicit method that does the casting allows us to abstract this from the user. Refs https://github.com/miekg/pkcs11/issues/144 --- p11/crypto.go | 16 ++++++++-------- p11/module.go | 2 +- p11/object.go | 15 +++++++++++++++ p11/secret_key.go | 10 +++++----- p11/session.go | 31 +++++++++++++++++-------------- 5 files changed, 46 insertions(+), 28 deletions(-) diff --git a/p11/crypto.go b/p11/crypto.go index 7b8e706..e08c9d2 100644 --- a/p11/crypto.go +++ b/p11/crypto.go @@ -2,16 +2,16 @@ package p11 import "github.com/miekg/pkcs11" -// PublicKey is an Object representing a public key. Since any object can be cast to a -// PublicKey, it is the user's responsibility to ensure that the object is -// actually a public key. For instance, if you use a FindObjects template that -// includes CKA_CLASS: CKO_PUBLIC_KEY, you can be confident the resulting object -// is a public key. +// PublicKey is an Object representing a public key. Since the PublicKey method +// can be called on any object, it is the user's responsibility to ensure that +// the object is actually a public key. For instance, if you use a FindObjects +// template that includes CKA_CLASS: CKO_PUBLIC_KEY, you can be confident the +// resulting object is a public key. type PublicKey Object -// PrivateKey is an Object representing a private key. Since any object can be cast to a -// PrivateKey, it is the user's responsibility to ensure that the object is -// actually a private key. +// PrivateKey is an Object representing a private key. Since the PrivateKey +// method can be called on any object, it is the user's responsibility to +// ensure that the object is actually a private key. type PrivateKey Object // Decrypt decrypts the input with a given mechanism. diff --git a/p11/module.go b/p11/module.go index 7d838e8..8522bba 100644 --- a/p11/module.go +++ b/p11/module.go @@ -51,7 +51,7 @@ // if err != nil { // return err // } -// privateKey := p11.PrivateKey(privateKeyObject) +// privateKey := privateKeyObject.PrivateKey() // signature, err := privateKey.Sign(..., []byte{"hello"}) // if err != nil { // return err diff --git a/p11/object.go b/p11/object.go index 1680935..51b904e 100644 --- a/p11/object.go +++ b/p11/object.go @@ -100,3 +100,18 @@ func (o Object) Destroy() error { defer s.Unlock() return s.ctx.DestroyObject(s.handle, o.objectHandle) } + +// PrivateKey returns this object as a PrivateKey. +func (o Object) PrivateKey() PrivateKey { + return PrivateKey(o) +} + +// PublicKey returns this object as a PublicKey. +func (o Object) PublicKey() PublicKey { + return PublicKey(o) +} + +// SecretKey returns this object as a SecretKey. +func (o Object) SecretKey() SecretKey { + return SecretKey(o) +} diff --git a/p11/secret_key.go b/p11/secret_key.go index c8bb24c..dff1f83 100644 --- a/p11/secret_key.go +++ b/p11/secret_key.go @@ -2,11 +2,11 @@ package p11 import "github.com/miekg/pkcs11" -// SecretKey is an Object representing a secret (symmetric) key. Since any object can be cast to a -// SecretKey, it is the user's responsibility to ensure that the object is -// actually a secret key. For instance, if you use a FindObjects template that -// includes CKA_CLASS: CKO_SECRET_KEY, you can be confident the resulting object -// is a secret key. +// SecretKey is an Object representing a secret (symmetric) key. Since the +// SecretKey method can be called on any object, it is the user's +// responsibility to ensure that the object is actually a secret key. For +// instance, if you use a FindObjects template that includes CKA_CLASS: +// CKO_SECRET_KEY, you can be confident the resulting object is a secret key. type SecretKey Object // Encrypt encrypts a plaintext with a given mechanism. diff --git a/p11/session.go b/p11/session.go index fd56525..76344d7 100644 --- a/p11/session.go +++ b/p11/session.go @@ -65,25 +65,25 @@ type sessionImpl struct { func (s *sessionImpl) FindPrivateKey(label string) (PrivateKey, error) { obj, err := s.findObjectWithClassAndLabel(pkcs11.CKO_PRIVATE_KEY, label) if err != nil { - return PrivateKey(obj), err + return obj.PrivateKey(), err } - return PrivateKey(obj), nil + return obj.PrivateKey(), nil } func (s *sessionImpl) FindPublicKey(label string) (PublicKey, error) { obj, err := s.findObjectWithClassAndLabel(pkcs11.CKO_PUBLIC_KEY, label) if err != nil { - return PublicKey(obj), err + return obj.PublicKey(), err } - return PublicKey(obj), nil + return obj.PublicKey(), nil } func (s *sessionImpl) FindSecretKey(label string) (SecretKey, error) { obj, err := s.findObjectWithClassAndLabel(pkcs11.CKO_SECRET_KEY, label) if err != nil { - return SecretKey(obj), err + return obj.SecretKey(), err } - return SecretKey(obj), nil + return obj.SecretKey(), nil } func (s *sessionImpl) findObjectWithClassAndLabel(class uint, label string) (Object, error) { @@ -219,14 +219,17 @@ func (s *sessionImpl) GenerateKeyPair(request GenerateKeyPairRequest) (*KeyPair, if err != nil { return nil, err } + + pubObj := Object{ + session: s, + objectHandle: pubHandle, + } + privObj := Object{ + session: s, + objectHandle: privHandle, + } return &KeyPair{ - Public: PublicKey(Object{ - session: s, - objectHandle: pubHandle, - }), - Private: PrivateKey(Object{ - session: s, - objectHandle: privHandle, - }), + Public: pubObj.PublicKey(), + Private: privObj.PrivateKey(), }, nil }