gitee.com/lh-her-team/common@v1.5.1/crypto/sdf/sdf.go (about) 1 package sdf 2 3 import ( 4 "fmt" 5 "log" 6 "os" 7 "strconv" 8 "time" 9 10 "gitee.com/lh-her-team/common/crypto/sdf/base" 11 "github.com/pkg/errors" 12 ) 13 14 const ( 15 defaultSessionSize = 10 16 ) 17 18 type SDFHandle struct { 19 ctx *base.Ctx 20 deviceHandle base.SessionHandle 21 sessions chan base.SessionHandle 22 sessionCacheSize int 23 } 24 25 // New returns a HSM SDFHandle to provide go-sdf functionalities. 26 func New(lib string, sessionCacheSize int) (*SDFHandle, error) { 27 ctx := base.New(lib) 28 if ctx == nil { 29 libEnv := os.Getenv("HSM_LIB") 30 log.Printf("lib[%s] invalid, use HSM_LIB[%s] from env\n", lib, libEnv) 31 ctx = base.New(libEnv) 32 if ctx == nil { 33 return nil, fmt.Errorf("[SDF] error: fail to initialize [%s]", libEnv) 34 } 35 } 36 if sessionCacheSize <= 0 { 37 sessionSizeStr := os.Getenv("HSM_SESSION_CACHE_SIZE") 38 sessionSize, err := strconv.Atoi(sessionSizeStr) 39 if err == nil && sessionSize > 0 { 40 log.Printf("sessionCacheSize[%d] invalid, use HSM_SESSION_CACHE_SIZE[%s] from env\n", 41 sessionCacheSize, sessionSizeStr) 42 sessionCacheSize = sessionSize 43 } else { 44 log.Printf("sessionCacheSize[%d] and HSM_SESSION_CACHE_SIZE[%s] invalid, use default size[%d]\n", 45 sessionCacheSize, sessionSizeStr, defaultSessionSize) 46 sessionCacheSize = defaultSessionSize 47 } 48 } 49 var err error 50 var deviceHandle base.SessionHandle 51 for i := 0; i < 3; i++ { 52 deviceHandle, err = ctx.SDFOpenDevice() 53 if err != nil { 54 continue 55 } 56 break 57 } 58 if err != nil { 59 return nil, fmt.Errorf("[SDF] error: fail to open device after 3 times [%v]", err) 60 } 61 sessions := make(chan base.SessionHandle, sessionCacheSize) 62 handle := &SDFHandle{ 63 ctx: ctx, 64 deviceHandle: deviceHandle, 65 sessions: sessions, 66 sessionCacheSize: sessionCacheSize, 67 } 68 return handle, nil 69 } 70 71 func (h *SDFHandle) getSession() (base.SessionHandle, error) { 72 var session base.SessionHandle 73 select { 74 case session = <-h.sessions: 75 return session, nil 76 default: 77 var err error 78 for i := 0; i < 3; i++ { 79 session, err = h.ctx.SDFOpenSession(h.deviceHandle) 80 if err == nil { 81 return session, nil 82 } 83 time.Sleep(time.Millisecond * 100) 84 } 85 return nil, errors.WithMessage(err, "failed to create new session after 3 times attempt") 86 } 87 } 88 89 func (h *SDFHandle) returnSession(err error, session base.SessionHandle) { 90 if err != nil { 91 _ = h.ctx.SDFCloseSession(session) 92 } 93 select { 94 case h.sessions <- session: 95 return 96 default: 97 _ = h.ctx.SDFCloseSession(session) 98 return 99 } 100 } 101 102 func (h *SDFHandle) Close() error { 103 //close channel to avoid creating new session 104 close(h.sessions) 105 //close all sessions 106 for session := range h.sessions { 107 err := h.ctx.SDFCloseSession(session) 108 if err != nil { 109 return err 110 } 111 } 112 //close device 113 return h.ctx.SDFCloseDevice(h.deviceHandle) 114 }