# package main
import (
"bytes"
"crypto/sha256"
"encoding/binary"
"fmt"
"log"
"github.com/miekg/pkcs11"
)
const (
pin = "87654321"
)
var ()
func main() {
// Init PKCS11
p := pkcs11.New("/opt/utimaco/lib/libcs_pkcs11_R3.so")
err := p.Initialize()
if err != nil {
panic(err)
}
defer p.Destroy()
defer p.Finalize()
slots, err := p.GetSlotList(true)
if err != nil {
panic(err)
}
session, err := p.OpenSession(slots[0],
pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
if err != nil {
panic(err)
}
defer p.CloseSession(session)
err = p.Login(session, pkcs11.CKU_USER, pin)
if err != nil {
panic(err)
}
defer p.Logout(session)
info, err := p.GetInfo()
if err != nil {
panic(err)
}
fmt.Printf("CryptokiVersion.Major %v", info.CryptokiVersion.Major)
fmt.Println()
buf := new(bytes.Buffer)
buf = new(bytes.Buffer)
var num uint16 = 1
num = 1
err = binary.Write(buf, binary.LittleEndian, num)
if err != nil {
log.Fatalf("binary.Write failed: %v", err)
}
pubID := buf.Bytes()
buf = new(bytes.Buffer)
num = 2
err = binary.Write(buf, binary.LittleEndian, num)
if err != nil {
log.Fatalf("binary.Write failed: %v", err)
}
privID := buf.Bytes()
publicKeyTemplate := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_ECDSA),
pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true),
pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true),
pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true),
pkcs11.NewAttribute(pkcs11.CKA_WRAP, false),
pkcs11.NewAttribute(pkcs11.CKA_LABEL, "pub1"),
pkcs11.NewAttribute(pkcs11.CKA_ID, pubID),
pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, []byte{0x06, 0x08,
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}),
}
privateKeyTemplate := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY),
pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_ECDSA),
pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
pkcs11.NewAttribute(pkcs11.CKA_SIGN, true),
pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, true),
pkcs11.NewAttribute(pkcs11.CKA_LABEL, "priv1"),
pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true),
pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true),
pkcs11.NewAttribute(pkcs11.CKA_WRAP_WITH_TRUSTED, false),
pkcs11.NewAttribute(pkcs11.CKA_UNWRAP, false),
pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, false),
pkcs11.NewAttribute(pkcs11.CKA_ID, privID),
}
pbk, pvk, err := p.GenerateKeyPair(session,
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA_KEY_PAIR_GEN, nil)},
publicKeyTemplate, privateKeyTemplate)
_ = pvk
_ = pbk
if err != nil {
log.Fatalf("failed to generate exportable keypair: %s\n", err)
}
// Signing
msg := []byte("foo")
digest := sha256.Sum256(msg)
err = p.SignInit(session,
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA_SHA1, nil)}, pvk)
sig, err := p.Sign(session, msg)
// Verification
err = p.VerifyInit(session,
[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA_SHA1, nil)}, pbk)
err = p.Verify(session, digest[:], sig)
}