Skip to content

Commit

Permalink
p11: Add cast methods to Object
Browse files Browse the repository at this point in the history
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 miekg#144
  • Loading branch information
Jeremy Rand committed Nov 3, 2022
1 parent 8bb176f commit 0c4557c
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 28 deletions.
16 changes: 8 additions & 8 deletions p11/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion p11/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions p11/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
10 changes: 5 additions & 5 deletions p11/secret_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
31 changes: 17 additions & 14 deletions p11/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
}

0 comments on commit 0c4557c

Please sign in to comment.