// SetupHSMEnv is a method that depends on the existences func SetupHSMEnv(libraryPath, pin string) (*pkcs11.Ctx, pkcs11.SessionHandle) { p := pkcs11.New(libraryPath) if p == nil { log.Fatalf("Failed to init library") } if err := p.Initialize(); err != nil { log.Fatalf("Initialize error %s\n", err.Error()) } slots, err := p.GetSlotList(true) if err != nil { log.Fatalf("Failed to list HSM slots %s", err) } // Check to see if we got any slots from the HSM. if len(slots) < 1 { log.Fatalln("No HSM Slots found") } // CKF_SERIAL_SESSION: TRUE if cryptographic functions are performed in serial with the application; FALSE if the functions may be performed in parallel with the application. // CKF_RW_SESSION: TRUE if the session is read/write; FALSE if the session is read-only session, err := p.OpenSession(slots[0], pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION) if err != nil { log.Fatalf("Failed to Start Session with HSM %s", err) } if err = p.Login(session, pkcs11.CKU_USER, pin); err != nil { log.Fatalf("User PIN %s\n", err.Error()) } return p, session }
func SetupHSMEnv(t *testing.T) (*pkcs11.Ctx, pkcs11.SessionHandle) { var libPath = "/usr/local/lib/softhsm/libsofthsm2.so" if _, err := os.Stat(libPath); err != nil { t.Skipf("Skipping test. Library path: %s does not exist", libPath) } p := pkcs11.New(libPath) if p == nil { t.Fatalf("Failed to init library") } if err := p.Initialize(); err != nil { t.Fatalf("Initialize error %s\n", err.Error()) } slots, err := p.GetSlotList(true) if err != nil { t.Fatalf("Failed to list HSM slots %s", err) } session, err := p.OpenSession(slots[0], pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION) if err != nil { t.Fatalf("Failed to Start Session with HSM %s", err) } if err = p.Login(session, pkcs11.CKU_USER, "1234"); err != nil { t.Fatalf("User PIN %s\n", err.Error()) } return p, session }
func initPKCS11Context(modulePath string) (*pkcs11.Ctx, error) { context := pkcs11.New(modulePath) if context == nil { return nil, fmt.Errorf("unable to load PKCS#11 module") } err := context.Initialize() return context, err }
func init() { for _, loc := range possiblePkcs11Libs { _, err := os.Stat(loc) if err == nil { p := pkcs11.New(loc) if p != nil { pkcs11Lib = loc return } } } }
// initialize loads the given PKCS#11 module (shared library) if it is not // already loaded. It's an error to load a PKCS#11 module multiple times, so we // maintain a map of loaded modules. Note that there is no facility yet to // unload a module ("finalize" in PKCS#11 parlance). In general, modules will // be unloaded at the end of the process. The only place where you are likely // to need to explicitly unload a module is if you fork your process after a // Key has already been created, and the child process also needs to use // that module. func initialize(modulePath string) (ctx, error) { modulesMu.Lock() defer modulesMu.Unlock() module, ok := modules[modulePath] if ok { return module, nil } newModule := pkcs11.New(modulePath) if newModule == nil { return nil, fmt.Errorf("unable to load PKCS#11 module from %q", modulePath) } err := newModule.Initialize() if err != nil { return nil, err } modules[modulePath] = ctx(newModule) return ctx(newModule), nil }
// initialize loads the given PKCS#11 module (shared library) if it is not // already loaded. It's an error to load a PKCS#11 module multiple times, so we // maintain a map of loaded modules. Note that there is no facility yet to // unload a module ("finalize" in PKCS#11 parlance). In general, modules will // be unloaded at the end of the process. The only place where you are likely // to need to explicitly unload a module is if you fork your process after a // Key has already been created, and the child process also needs to use // that module. func initialize(modulePath string) (*pkcs11.Ctx, error) { modulesMu.Lock() defer modulesMu.Unlock() module, ok := modules[modulePath] if ok { return module, nil } module = pkcs11.New(modulePath) if module == nil { return nil, fmt.Errorf("unable to load PKCS#11 module") } err := module.Initialize() if err != nil { return nil, err } modules[modulePath] = module return module, nil }
// New instantiates a new handle to a PKCS #11-backed key. func New(module, slot, pin, privLabel string) (ps *PKCS11Key, err error) { // Set up a new pkcs11 object and initialize it p := pkcs11.New(module) if p == nil { err = errors.New("unable to load PKCS#11 module") return } if err = p.Initialize(); err != nil { return } // Initialize a partial key ps = &PKCS11Key{ module: p, slotDescription: slot, pin: pin, } // Look up the private key session, err := ps.openSession() if err != nil { ps.Destroy() return } defer ps.closeSession(session) template := []*pkcs11.Attribute{ pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY), pkcs11.NewAttribute(pkcs11.CKA_LABEL, privLabel), } if err = p.FindObjectsInit(session, template); err != nil { ps.Destroy() return } objs, _, err := p.FindObjects(session, 2) if err != nil { ps.Destroy() return } if err = p.FindObjectsFinal(session); err != nil { ps.Destroy() return } if len(objs) == 0 { err = errors.New("private key not found") ps.Destroy() return } ps.privateKeyHandle = objs[0] // Populate the pubic key from the private key // TODO: Add support for non-RSA keys, switching on CKA_KEY_TYPE template = []*pkcs11.Attribute{ pkcs11.NewAttribute(pkcs11.CKA_MODULUS, nil), pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, nil), } attr, err := p.GetAttributeValue(session, ps.privateKeyHandle, template) if err != nil { ps.Destroy() return } n := big.NewInt(0) e := int(0) gotModulus, gotExponent := false, false for _, a := range attr { if a.Type == pkcs11.CKA_MODULUS { n.SetBytes(a.Value) gotModulus = true } else if a.Type == pkcs11.CKA_PUBLIC_EXPONENT { bigE := big.NewInt(0) bigE.SetBytes(a.Value) e = int(bigE.Int64()) gotExponent = true } } if !gotModulus || !gotExponent { ps.Destroy() return } ps.publicKey = rsa.PublicKey{ N: n, E: e, } return }
func generate_pkcs11keypair() { config := configure() p := pkcs11.New(config.module) if p == nil { fmt.Printf("Could not initialize pkcs11 with module %s, exiting.\n", config.module) os.Exit(1) } p.Initialize() defer p.Destroy() defer p.Finalize() var used_slot uint = 0 slots, _ := p.GetSlotList(true) for _, slot_id := range slots { if slot_id == config.slot_id { used_slot = config.slot_id } } fmt.Printf("Wanted slot id %v ", config.slot_id) fmt.Printf("and got slot id %v.\n", used_slot) session, err := p.OpenSession(used_slot, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION) if err != nil { fmt.Printf("Could not open session. Error: %v\n", err) os.Exit(1) } defer p.CloseSession(session) p.Login(session, pkcs11.CKU_USER, config.user_pin) defer p.Logout(session) info, err := p.GetInfo() if err != nil { fmt.Printf("GetInfo failed: %v\n", err) os.Exit(1) } else { fmt.Printf("HSM Info:\nManufacturer ID %v\nFlags: %v\nLibrary Description: %v\nLibrary Version: %v.\n", info.ManufacturerID, info.Flags, info.LibraryDescription, info.LibraryVersion) } // var pub_exponent int = 0x010001 publicKeyTemplate := []*pkcs11.Attribute{ pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKO_PUBLIC_KEY), pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), pkcs11.NewAttribute(pkcs11.CKA_MODULUS_BITS, config.rsa_size), pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, []byte{3}), pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true), pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, true), pkcs11.NewAttribute(pkcs11.CKA_WRAP, true), pkcs11.NewAttribute(pkcs11.CKA_LABEL, config.key_label), pkcs11.NewAttribute(pkcs11.CKA_ID, config.key_id), pkcs11.NewAttribute(pkcs11.CKA_SUBJECT, "/CN=Harald Wagener"), } privateKeyTemplate := []*pkcs11.Attribute{ pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKO_PRIVATE_KEY), pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true), pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true), pkcs11.NewAttribute(pkcs11.CKA_SIGN, true), pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, true), pkcs11.NewAttribute(pkcs11.CKA_UNWRAP, true), pkcs11.NewAttribute(pkcs11.CKA_LABEL, config.key_label), pkcs11.NewAttribute(pkcs11.CKA_ID, config.key_id), pkcs11.NewAttribute(pkcs11.CKA_SUBJECT, "/CN=Harald Wagener"), } pub, priv, err := p.GenerateKeyPair(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_KEY_PAIR_GEN, nil)}, publicKeyTemplate, privateKeyTemplate) if err != nil { fmt.Printf("Error generating key pair: %v\n", err) os.Exit(1) } else { fmt.Printf("Key pair generated:\nPublic Key: %v\nPrivate Key: %v\n", pub, priv) os.Exit(0) } }
func defaultLoader(module string) IPKCS11Ctx { return pkcs11.New(module) }