From 0437106e52528df060266e34fc10cc98d8fc6b76 Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Thu, 13 Oct 2022 09:18:01 +0000 Subject: [PATCH] cMechanism: Accept single *Mechanism Fixes https://github.com/miekg/pkcs11/issues/55 --- p11/crypto.go | 10 +++++----- p11/secret_key.go | 4 ++-- p11/session.go | 2 +- p11/slot.go | 2 +- parallel_test.go | 2 +- params_test.go | 12 ++++++------ pkcs11.go | 28 ++++++++++++++-------------- pkcs11_test.go | 22 +++++++++++----------- types.go | 6 +----- 9 files changed, 42 insertions(+), 46 deletions(-) diff --git a/p11/crypto.go b/p11/crypto.go index e08c9d2..a171d82 100644 --- a/p11/crypto.go +++ b/p11/crypto.go @@ -19,7 +19,7 @@ func (priv PrivateKey) Decrypt(mechanism pkcs11.Mechanism, ciphertext []byte) ([ s := priv.session s.Lock() defer s.Unlock() - err := s.ctx.DecryptInit(s.handle, []*pkcs11.Mechanism{&mechanism}, priv.objectHandle) + err := s.ctx.DecryptInit(s.handle, &mechanism, priv.objectHandle) if err != nil { return nil, err } @@ -35,7 +35,7 @@ func (priv PrivateKey) Sign(mechanism pkcs11.Mechanism, message []byte) ([]byte, s := priv.session s.Lock() defer s.Unlock() - err := s.ctx.SignInit(s.handle, []*pkcs11.Mechanism{&mechanism}, priv.objectHandle) + err := s.ctx.SignInit(s.handle, &mechanism, priv.objectHandle) if err != nil { return nil, err } @@ -50,7 +50,7 @@ func (priv PrivateKey) deriveInner(mechanism pkcs11.Mechanism, attributes []*pkc s := priv.session s.Lock() defer s.Unlock() - objectHandle, err := s.ctx.DeriveKey(s.handle, []*pkcs11.Mechanism{&mechanism}, priv.objectHandle, attributes) + objectHandle, err := s.ctx.DeriveKey(s.handle, &mechanism, priv.objectHandle, attributes) if err != nil { return nil, err } @@ -82,7 +82,7 @@ func (pub PublicKey) Verify(mechanism pkcs11.Mechanism, message, signature []byt s := pub.session s.Lock() defer s.Unlock() - err := s.ctx.VerifyInit(s.handle, []*pkcs11.Mechanism{&mechanism}, pub.objectHandle) + err := s.ctx.VerifyInit(s.handle, &mechanism, pub.objectHandle) if err != nil { return err } @@ -98,7 +98,7 @@ func (pub PublicKey) Encrypt(mechanism pkcs11.Mechanism, plaintext []byte) ([]by s := pub.session s.Lock() defer s.Unlock() - err := s.ctx.EncryptInit(s.handle, []*pkcs11.Mechanism{&mechanism}, pub.objectHandle) + err := s.ctx.EncryptInit(s.handle, &mechanism, pub.objectHandle) if err != nil { return nil, err } diff --git a/p11/secret_key.go b/p11/secret_key.go index dff1f83..98fa188 100644 --- a/p11/secret_key.go +++ b/p11/secret_key.go @@ -14,7 +14,7 @@ func (secret SecretKey) Encrypt(mechanism pkcs11.Mechanism, plaintext []byte) ([ s := secret.session s.Lock() defer s.Unlock() - err := s.ctx.EncryptInit(s.handle, []*pkcs11.Mechanism{&mechanism}, secret.objectHandle) + err := s.ctx.EncryptInit(s.handle, &mechanism, secret.objectHandle) if err != nil { return nil, err } @@ -30,7 +30,7 @@ func (secret SecretKey) Decrypt(mechanism pkcs11.Mechanism, ciphertext []byte) ( s := secret.session s.Lock() defer s.Unlock() - err := s.ctx.DecryptInit(s.handle, []*pkcs11.Mechanism{&mechanism}, secret.objectHandle) + err := s.ctx.DecryptInit(s.handle, &mechanism, secret.objectHandle) if err != nil { return nil, err } diff --git a/p11/session.go b/p11/session.go index 353d43c..ba0ec90 100644 --- a/p11/session.go +++ b/p11/session.go @@ -213,7 +213,7 @@ func (s *sessionImpl) GenerateKeyPair(request GenerateKeyPairRequest) (*KeyPair, s.Lock() defer s.Unlock() pubHandle, privHandle, err := s.ctx.GenerateKeyPair(s.handle, - []*pkcs11.Mechanism{&request.Mechanism}, + &request.Mechanism, request.PublicKeyAttributes, request.PrivateKeyAttributes) if err != nil { diff --git a/p11/slot.go b/p11/slot.go index c4175c4..ff12414 100644 --- a/p11/slot.go +++ b/p11/slot.go @@ -103,5 +103,5 @@ func (m *Mechanism) Parameter() []byte { // Info returns information about this mechanism. func (m *Mechanism) Info() (pkcs11.MechanismInfo, error) { - return m.slot.ctx.GetMechanismInfo(m.slot.id, []*pkcs11.Mechanism{m.mechanism}) + return m.slot.ctx.GetMechanismInfo(m.slot.id, m.mechanism) } diff --git a/parallel_test.go b/parallel_test.go index ea080db..72fafe4 100644 --- a/parallel_test.go +++ b/parallel_test.go @@ -134,7 +134,7 @@ func makeSigner(context *Ctx) (*signer, error) { } func (s *signer) sign(input []byte) ([]byte, error) { - mechanism := []*Mechanism{NewMechanism(CKM_RSA_PKCS, nil)} + mechanism := NewMechanism(CKM_RSA_PKCS, nil) if err := s.context.SignInit(s.session, mechanism, s.privateKey); err != nil { log.Fatalf("SignInit: %s", err) } diff --git a/params_test.go b/params_test.go index b760b86..b895300 100644 --- a/params_test.go +++ b/params_test.go @@ -16,7 +16,7 @@ func needMech(t *testing.T, p *Ctx, sh SessionHandle, mech uint) { if err != nil { t.Fatal("GetSlotList:", err) } - _, err = p.GetMechanismInfo(slots[0], []*Mechanism{NewMechanism(mech, nil)}) + _, err = p.GetMechanismInfo(slots[0], NewMechanism(mech, nil)) if err == nil { return } @@ -67,7 +67,7 @@ func TestPSSParams(t *testing.T) { sum := []byte("1234567890abcdef1234567890abcdef") params := NewPSSParams(CKM_SHA256, CKG_MGF1_SHA256, 32) - mech := []*Mechanism{NewMechanism(CKM_RSA_PKCS_PSS, params)} + mech := NewMechanism(CKM_RSA_PKCS_PSS, params) if err := p.SignInit(sh, mech, priv); err != nil { t.Fatal("SignInit:", err) } @@ -92,7 +92,7 @@ func TestOAEPParams(t *testing.T) { msg := []byte("1234567890abcdef1234567890abcdef") params := NewOAEPParams(CKM_SHA_1, CKG_MGF1_SHA1, CKZ_DATA_SPECIFIED, nil) - mech := []*Mechanism{NewMechanism(CKM_RSA_PKCS_OAEP, params)} + mech := NewMechanism(CKM_RSA_PKCS_OAEP, params) if err := p.EncryptInit(sh, mech, pub); err != nil { t.Fatal("EncryptInit:", err) } @@ -118,7 +118,7 @@ func TestGCMParams(t *testing.T) { defer finishSession(p, sh) needMech(t, p, sh, CKM_AES_GCM) - key, err := p.GenerateKey(sh, []*Mechanism{NewMechanism(CKM_AES_KEY_GEN, nil)}, []*Attribute{ + key, err := p.GenerateKey(sh, NewMechanism(CKM_AES_KEY_GEN, nil), []*Attribute{ NewAttribute(CKA_TOKEN, false), NewAttribute(CKA_DECRYPT, true), NewAttribute(CKA_ENCRYPT, true), @@ -132,7 +132,7 @@ func TestGCMParams(t *testing.T) { msg := []byte("1234567890abcdef1234567890abcdef") params := NewGCMParams(iv, nil, 128) defer params.Free() - if err := p.EncryptInit(sh, []*Mechanism{NewMechanism(CKM_AES_GCM, params)}, key); err != nil { + if err := p.EncryptInit(sh, NewMechanism(CKM_AES_GCM, params), key); err != nil { t.Fatal("EncryptInit:", err) } ciphertext, err := p.Encrypt(sh, msg) @@ -144,7 +144,7 @@ func TestGCMParams(t *testing.T) { params = NewGCMParams(iv, nil, 128) defer params.Free() - if err := p.DecryptInit(sh, []*Mechanism{NewMechanism(CKM_AES_GCM, params)}, key); err != nil { + if err := p.DecryptInit(sh, NewMechanism(CKM_AES_GCM, params), key); err != nil { t.Fatal("DecryptInit:", err) } msg2, err := p.Decrypt(sh, ciphertext) diff --git a/pkcs11.go b/pkcs11.go index f6a23af..cfd9c90 100644 --- a/pkcs11.go +++ b/pkcs11.go @@ -911,9 +911,9 @@ func (c *Ctx) GetMechanismList(slotID uint) ([]*Mechanism, error) { // GetMechanismInfo obtains information about a particular // mechanism possibly supported by a token. -func (c *Ctx) GetMechanismInfo(slotID uint, m []*Mechanism) (MechanismInfo, error) { +func (c *Ctx) GetMechanismInfo(slotID uint, m *Mechanism) (MechanismInfo, error) { var cm C.CK_MECHANISM_INFO - e := C.GetMechanismInfo(c.ctx, C.CK_ULONG(slotID), C.CK_MECHANISM_TYPE(m[0].Mechanism), + e := C.GetMechanismInfo(c.ctx, C.CK_ULONG(slotID), C.CK_MECHANISM_TYPE(m.Mechanism), C.CK_MECHANISM_INFO_PTR(&cm)) mi := MechanismInfo{ MinKeySize: uint(cm.ulMinKeySize), @@ -1147,7 +1147,7 @@ func (c *Ctx) FindObjectsFinal(sh SessionHandle) error { } // EncryptInit initializes an encryption operation. -func (c *Ctx) EncryptInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error { +func (c *Ctx) EncryptInit(sh SessionHandle, m *Mechanism, o ObjectHandle) error { arena, mech := cMechanism(m) defer arena.Free() e := C.EncryptInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o)) @@ -1200,7 +1200,7 @@ func (c *Ctx) EncryptFinal(sh SessionHandle) ([]byte, error) { } // DecryptInit initializes a decryption operation. -func (c *Ctx) DecryptInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error { +func (c *Ctx) DecryptInit(sh SessionHandle, m *Mechanism, o ObjectHandle) error { arena, mech := cMechanism(m) defer arena.Free() e := C.DecryptInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o)) @@ -1253,7 +1253,7 @@ func (c *Ctx) DecryptFinal(sh SessionHandle) ([]byte, error) { } // DigestInit initializes a message-digesting operation. -func (c *Ctx) DigestInit(sh SessionHandle, m []*Mechanism) error { +func (c *Ctx) DigestInit(sh SessionHandle, m *Mechanism) error { arena, mech := cMechanism(m) defer arena.Free() e := C.DigestInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech) @@ -1313,7 +1313,7 @@ func (c *Ctx) DigestFinal(sh SessionHandle) ([]byte, error) { // SignInit initializes a signature (private key encryption) // operation, where the signature is (will be) an appendix to // the data, and plaintext cannot be recovered from the signature. -func (c *Ctx) SignInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error { +func (c *Ctx) SignInit(sh SessionHandle, m *Mechanism, o ObjectHandle) error { arena, mech := cMechanism(m) defer arena.Free() e := C.SignInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o)) @@ -1360,7 +1360,7 @@ func (c *Ctx) SignFinal(sh SessionHandle) ([]byte, error) { } // SignRecoverInit initializes a signature operation, where the data can be recovered from the signature. -func (c *Ctx) SignRecoverInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error { +func (c *Ctx) SignRecoverInit(sh SessionHandle, m *Mechanism, key ObjectHandle) error { arena, mech := cMechanism(m) defer arena.Free() e := C.SignRecoverInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(key)) @@ -1385,7 +1385,7 @@ func (c *Ctx) SignRecover(sh SessionHandle, data []byte) ([]byte, error) { // VerifyInit initializes a verification operation, where the // signature is an appendix to the data, and plaintext cannot // be recovered from the signature (e.g. DSA). -func (c *Ctx) VerifyInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error { +func (c *Ctx) VerifyInit(sh SessionHandle, m *Mechanism, key ObjectHandle) error { arena, mech := cMechanism(m) defer arena.Free() e := C.VerifyInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(key)) @@ -1417,7 +1417,7 @@ func (c *Ctx) VerifyFinal(sh SessionHandle, signature []byte) error { // VerifyRecoverInit initializes a signature verification // operation, where the data is recovered from the signature. -func (c *Ctx) VerifyRecoverInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error { +func (c *Ctx) VerifyRecoverInit(sh SessionHandle, m *Mechanism, key ObjectHandle) error { arena, mech := cMechanism(m) defer arena.Free() e := C.VerifyRecoverInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(key)) @@ -1501,7 +1501,7 @@ func (c *Ctx) DecryptVerifyUpdate(sh SessionHandle, cipher []byte) ([]byte, erro } // GenerateKey generates a secret key, creating a new key object. -func (c *Ctx) GenerateKey(sh SessionHandle, m []*Mechanism, temp []*Attribute) (ObjectHandle, error) { +func (c *Ctx) GenerateKey(sh SessionHandle, m *Mechanism, temp []*Attribute) (ObjectHandle, error) { var key C.CK_OBJECT_HANDLE attrarena, t, tcount := cAttributeList(temp) defer attrarena.Free() @@ -1516,7 +1516,7 @@ func (c *Ctx) GenerateKey(sh SessionHandle, m []*Mechanism, temp []*Attribute) ( } // GenerateKeyPair generates a public-key/private-key pair creating new key objects. -func (c *Ctx) GenerateKeyPair(sh SessionHandle, m []*Mechanism, public, private []*Attribute) (ObjectHandle, ObjectHandle, error) { +func (c *Ctx) GenerateKeyPair(sh SessionHandle, m *Mechanism, public, private []*Attribute) (ObjectHandle, ObjectHandle, error) { var ( pubkey C.CK_OBJECT_HANDLE privkey C.CK_OBJECT_HANDLE @@ -1536,7 +1536,7 @@ func (c *Ctx) GenerateKeyPair(sh SessionHandle, m []*Mechanism, public, private } // WrapKey wraps (i.e., encrypts) a key. -func (c *Ctx) WrapKey(sh SessionHandle, m []*Mechanism, wrappingkey, key ObjectHandle) ([]byte, error) { +func (c *Ctx) WrapKey(sh SessionHandle, m *Mechanism, wrappingkey, key ObjectHandle) ([]byte, error) { var ( wrappedkey C.CK_BYTE_PTR wrappedkeylen C.CK_ULONG @@ -1553,7 +1553,7 @@ func (c *Ctx) WrapKey(sh SessionHandle, m []*Mechanism, wrappingkey, key ObjectH } // UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. -func (c *Ctx) UnwrapKey(sh SessionHandle, m []*Mechanism, unwrappingkey ObjectHandle, wrappedkey []byte, a []*Attribute) (ObjectHandle, error) { +func (c *Ctx) UnwrapKey(sh SessionHandle, m *Mechanism, unwrappingkey ObjectHandle, wrappedkey []byte, a []*Attribute) (ObjectHandle, error) { var key C.CK_OBJECT_HANDLE attrarena, ac, aclen := cAttributeList(a) defer attrarena.Free() @@ -1564,7 +1564,7 @@ func (c *Ctx) UnwrapKey(sh SessionHandle, m []*Mechanism, unwrappingkey ObjectHa } // DeriveKey derives a key from a base key, creating a new key object. -func (c *Ctx) DeriveKey(sh SessionHandle, m []*Mechanism, basekey ObjectHandle, a []*Attribute) (ObjectHandle, error) { +func (c *Ctx) DeriveKey(sh SessionHandle, m *Mechanism, basekey ObjectHandle, a []*Attribute) (ObjectHandle, error) { var key C.CK_OBJECT_HANDLE attrarena, ac, aclen := cAttributeList(a) defer attrarena.Free() diff --git a/pkcs11_test.go b/pkcs11_test.go index 92f3149..4a26a5c 100644 --- a/pkcs11_test.go +++ b/pkcs11_test.go @@ -178,7 +178,7 @@ func TestDigest(t *testing.T) { } func testDigest(t *testing.T, p *Ctx, session SessionHandle, input []byte, expected string) { - e := p.DigestInit(session, []*Mechanism{NewMechanism(CKM_SHA_1, nil)}) + e := p.DigestInit(session, NewMechanism(CKM_SHA_1, nil)) if e != nil { t.Fatalf("DigestInit: %s\n", e) } @@ -211,7 +211,7 @@ func TestDigestUpdate(t *testing.T) { } func testDigestUpdate(t *testing.T, p *Ctx, session SessionHandle, inputs [][]byte, expected string) { - if e := p.DigestInit(session, []*Mechanism{NewMechanism(CKM_SHA_1, nil)}); e != nil { + if e := p.DigestInit(session, NewMechanism(CKM_SHA_1, nil)); e != nil { t.Fatalf("DigestInit: %s\n", e) } for _, input := range inputs { @@ -274,7 +274,7 @@ func generateRSAKeyPair(t *testing.T, p *Ctx, session SessionHandle, tokenLabel NewAttribute(CKA_EXTRACTABLE, true), } pbk, pvk, e := p.GenerateKeyPair(session, - []*Mechanism{NewMechanism(CKM_RSA_PKCS_KEY_PAIR_GEN, nil)}, + NewMechanism(CKM_RSA_PKCS_KEY_PAIR_GEN, nil), publicKeyTemplate, privateKeyTemplate) if e != nil { t.Fatalf("failed to generate keypair: %s\n", e) @@ -299,7 +299,7 @@ func TestSign(t *testing.T) { tokenLabel := "TestSign" _, pvk := generateRSAKeyPair(t, p, session, tokenLabel, false) - p.SignInit(session, []*Mechanism{NewMechanism(CKM_SHA1_RSA_PKCS, nil)}, pvk) + p.SignInit(session, NewMechanism(CKM_SHA1_RSA_PKCS, nil), pvk) _, e := p.Sign(session, []byte("Sign me!")) if e != nil { t.Fatalf("failed to sign: %s\n", e) @@ -374,7 +374,7 @@ func TestSymmetricEncryption(t *testing.T) { NewAttribute(CKA_VALUE_LEN, 16), } key, err := p.GenerateKey(session, - []*Mechanism{NewMechanism(CKM_AES_KEY_GEN, nil)}, + NewMechanism(CKM_AES_KEY_GEN, nil), keyTemplate) if err != nil { t.Fatalf("failed to generate keypair: %s\n", err) @@ -415,14 +415,14 @@ func TestSymmetricEncryption(t *testing.T) { func testEncrypt(t *testing.T, p *Ctx, session SessionHandle, key ObjectHandle, mech uint, plaintext []byte, iv []byte) { var err error - if err = p.EncryptInit(session, []*Mechanism{NewMechanism(mech, iv)}, key); err != nil { + if err = p.EncryptInit(session, NewMechanism(mech, iv), key); err != nil { t.Fatalf("EncryptInit: %s\n", err) } var ciphertext []byte if ciphertext, err = p.Encrypt(session, plaintext); err != nil { t.Fatalf("Encrypt: %s\n", err) } - if err = p.DecryptInit(session, []*Mechanism{NewMechanism(mech, iv)}, key); err != nil { + if err = p.DecryptInit(session, NewMechanism(mech, iv), key); err != nil { t.Fatalf("DecryptInit: %s\n", err) } var decrypted []byte @@ -436,7 +436,7 @@ func testEncrypt(t *testing.T, p *Ctx, session SessionHandle, key ObjectHandle, func testEncryptUpdate(t *testing.T, p *Ctx, session SessionHandle, key ObjectHandle, mech uint, plaintexts [][]byte, iv []byte) { var err error - if err = p.EncryptInit(session, []*Mechanism{NewMechanism(mech, iv)}, key); err != nil { + if err = p.EncryptInit(session, NewMechanism(mech, iv), key); err != nil { t.Fatalf("EncryptInit: %s\n", err) } var ciphertexts [][]byte @@ -452,7 +452,7 @@ func testEncryptUpdate(t *testing.T, p *Ctx, session SessionHandle, key ObjectHa t.Fatalf("EncryptFinal: %s\n", err) } ciphertexts = append(ciphertexts, output) - if err = p.DecryptInit(session, []*Mechanism{NewMechanism(mech, iv)}, key); err != nil { + if err = p.DecryptInit(session, NewMechanism(mech, iv), key); err != nil { t.Fatalf("DecryptInit: %s\n", err) } var decrypted []byte @@ -511,12 +511,12 @@ func ExampleCtx_Sign() { NewAttribute(CKA_LABEL, "ExampleSign"), } _, priv, err := p.GenerateKeyPair(session, - []*Mechanism{NewMechanism(CKM_RSA_PKCS_KEY_PAIR_GEN, nil)}, + NewMechanism(CKM_RSA_PKCS_KEY_PAIR_GEN, nil), publicKeyTemplate, privateKeyTemplate) if err != nil { log.Fatal(err) } - p.SignInit(session, []*Mechanism{NewMechanism(CKM_SHA1_RSA_PKCS, nil)}, priv) + p.SignInit(session, NewMechanism(CKM_SHA1_RSA_PKCS, nil), priv) // Sign something with the private key. data := []byte("Lets sign this data") diff --git a/types.go b/types.go index 700dd96..f73b710 100644 --- a/types.go +++ b/types.go @@ -273,11 +273,7 @@ func NewMechanism(mech uint, x interface{}) *Mechanism { return m } -func cMechanism(mechList []*Mechanism) (arena, *C.CK_MECHANISM) { - if len(mechList) != 1 { - panic("expected exactly one mechanism") - } - mech := mechList[0] +func cMechanism(mech *Mechanism) (arena, *C.CK_MECHANISM) { cmech := &C.CK_MECHANISM{mechanism: C.CK_MECHANISM_TYPE(mech.Mechanism)} // params that contain pointers are allocated here param := mech.Parameter