/* +build cgo */ package gmssl /* #include #include #include #include #include #include char *get_errors() { char *ret; BIO *bio; char *data; long len; if (!(bio = BIO_new(BIO_s_mem()))) { return (char *)NULL; } ERR_print_errors(bio); len = BIO_get_mem_data(bio, &data); ret = OPENSSL_strdup(data); BIO_free(bio); return ret; } EVP_PKEY *load_private_key_from_engine(ENGINE *e, const char *key_id, const char *pass) { return (EVP_PKEY *)NULL; } */ 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 GetEngineByName(name string) (*Engine, error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) eng := C.ENGINE_by_id(cname) if eng == nil { cerrors := C.get_errors() return nil, errors.New(C.GoString(cerrors)) } 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) { cerrors := C.get_errors() return nil, errors.New(C.GoString(cerrors)) } return ret, 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) { cerrors := C.get_errors() return errors.New(C.GoString(cerrors)) } 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.load_private_key_from_engine(e.engine, cid, cpass) if sk == nil { cerrors := C.get_errors() return nil, errors.New(C.GoString(cerrors)) } return &PrivateKey{sk}, nil } func (e *Engine) GetPublicKey(id string) ( *PublicKey, error) { cid := C.CString(id) defer C.free(unsafe.Pointer(cid)) //pk := C.ENGINE_load_public_key(e.engine, cid, C.NULL, C.NULL) //if pk == nil { // cerrors := C.get_errors() // return nil, errors.New(C.GoString(cerrors)) //} //return &PublicKey{pk}, nil return nil, nil }