Ejemplo n.º 1
0
// 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
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
0
func init() {
	for _, loc := range possiblePkcs11Libs {
		_, err := os.Stat(loc)
		if err == nil {
			p := pkcs11.New(loc)
			if p != nil {
				pkcs11Lib = loc
				return
			}
		}
	}
}
Ejemplo n.º 5
0
// 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
}
Ejemplo n.º 6
0
// 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
}
Ejemplo n.º 7
0
// 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
}
Ejemplo n.º 8
0
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)
	}
}
Ejemplo n.º 9
0
func defaultLoader(module string) IPKCS11Ctx {
	return pkcs11.New(module)
}