I'm trying to generate an EC-Keypair with PKCS#11 on SoftHSM2 with github.com/miekg/pkcs11
I got curve-parameters from here:
https://github.com/ANSSI-FR/libecc/blob/master/src/curves/known/ec_params_secp256r1.h
But I'm still getting CKR_GENERAL_ERROR
, here is my function to sign:
func sign() {
lib := "/usr/lib/softhsm/libsofthsm2.so"
p := pkcs11.New(lib)
if p == nil {
fmt.Printf("Lib not found ", lib)
return
}
p.Initialize()
defer p.Destroy()
defer p.Finalize()
slots, _ := p.GetSlotList(true)
session, _ := p.OpenSession(slots[0], pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
defer p.CloseSession(session)
p.Login(session, pkcs11.CKU_USER, "xxx")
defer p.Logout(session)
// pkcs11.CKK_ECDSA = 0x00000003
// pkcs11.CKK_EC = 0x00000003
// pkcs11.CKK_X9_42_DH = 0x00000004
// pkcs11.CKK_SEED = 0x0000002F
// pkcs11.CKC_X_509 = 0x00000000
//pkcs11.CKA_OBJECT_ID = 0x00000012
//pkcs11.CKA_NEVER_EXTRACTABLE = 0x00000164
// CKA_EC_PARAMS = 0x00000180
// CKA_EC_POINT = 0x00000181
publicKeyTemplate := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_EC),
//pkcs11.NewAttribute(pkcs11.CKA_OBJECT_ID, 1),
pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, []byte{
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}),//[]byte{0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01}),
//pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, 3),
//pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, true),
pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
//pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true),
//pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, []byte{3}),
//pkcs11.NewAttribute(pkcs11.CKA_MODULUS_BITS, 1024),
//pkcs11.NewAttribute(pkcs11.CKA_LABEL, "Null"),
}
privateKeyTemplate := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY),
pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_EC),
//pkcs11.NewAttribute(pkcs11.CKA_OBJECT_ID, 2),
pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, []byte{
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}),
//pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, 3),
//pkcs11.NewAttribute(pkcs11.CKA_NEVER_EXTRACTABLE, true),
pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true),
pkcs11.NewAttribute(pkcs11.CKA_SIGN, true),
pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true),
//pkcs11.NewAttribute(pkcs11.CKA_LABEL, "Null"),
}
_, priv, err := p.GenerateKeyPair(session,
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_EC_KEY_PAIR_GEN, nil)}, //pkcs11.CKM_EC_KEY_PAIR_GEN
publicKeyTemplate, privateKeyTemplate)
if err != nil {
panic(err)
}
p.SignInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA_SHA1, nil)}, priv)
// Sign something with the private key.
data := []byte("Lets sign this data")
_, err = p.Sign(session, data)
if err != nil {
panic(err)
}
fmt.Printf("It works!")
}
While I agree that this code sample lacks quality and more information would be helpful it mainly seems that mainly the templates are wrong:
Mechanism CKM_EC_KEY_PAIR_GEN
only needs the curve OID in CKA_EC_PARAMS
(the commmented part is right, the actual code is wrong) in the public key template only. CKA_CLASS
and CKA_KEY_TYPE
are set automatically for both keys as well as CKA_EC_PARAMS
for the private key (see https://docs.oasis-open.org/pkcs11/pkcs11-curr/v3.0/os/pkcs11-curr-v3.0-os.html#_Toc30061186).
You can add CKA_TOKEN
, CKA_LABEL
or CKA_ID
(note: CKA_OBJECT_ID
is only defined for a data object, not a key).
Start with this, not more. Then add usage restrictions (CKA_SIGN
etc) as needed.
User contributions licensed under CC BY-SA 3.0