/* +build cgo */ package gmssl /* #include #include #include #include #include #include #include */ import "C" import ( "errors" "runtime" "unsafe" ) func GetEngineNames() []string { engines := []string{} C.ENGINE_load_builtin_engines() eng := C.ENGINE_get_first() for { if eng == nil { break } engines = append(engines, C.GoString(C.ENGINE_get_id(eng))) eng = C.ENGINE_get_next(eng) } C.ENGINE_free(eng) return engines } type Engine struct { engine *C.ENGINE; } func NewEngineByName(name string) (*Engine, error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) eng := C.ENGINE_by_id(cname) if eng == nil { return nil, GetErrors() } ret := &Engine{eng} runtime.SetFinalizer(ret, func(ret *Engine) { C.ENGINE_finish(ret.engine) C.ENGINE_free(ret.engine) }) if 1 != C.ENGINE_init(eng) { return nil, GetErrors() } return ret, nil } func (e *Engine) GetCommands() ([]string, error) { return []string{"SO_PATH"}, nil } func (e *Engine) RunCommand(name, arg string) error { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) carg := C.CString(arg) defer C.free(unsafe.Pointer(carg)) if 1 != C.ENGINE_ctrl_cmd_string(e.engine, cname, carg, 0) { return GetErrors() } return nil } func (e *Engine) LoadConfigFile(path string) error { return errors.New("Engine.LoadConfigFile() not implemented") } func (e *Engine) GetPrivateKey(id string, pass string) (*PrivateKey, error) { cid := C.CString(id) defer C.free(unsafe.Pointer(cid)) cpass := C.CString(pass) defer C.free(unsafe.Pointer(cpass)) sk := C.ENGINE_load_private_key(e.engine, cid, nil, unsafe.Pointer(cpass)) if sk == nil { return nil, GetErrors() } return &PrivateKey{sk}, nil } func (e *Engine) GetPublicKey(id string, pass string) (*PublicKey, error) { cid := C.CString(id) defer C.free(unsafe.Pointer(cid)) cpass := C.CString(pass) defer C.free(unsafe.Pointer(cpass)) pk := C.ENGINE_load_public_key(e.engine, cid, nil, unsafe.Pointer(cpass)) if pk == nil { return nil, GetErrors() } return &PublicKey{pk}, nil }