func (c *Conn) GetSession() ([]byte, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() // get1 increases the refcount of the session, so we have to free it. session := (*C.SSL_SESSION)(C.SSL_get1_session(c.ssl)) if session == nil { return nil, errors.New("failed to get session") } defer C.SSL_SESSION_free(session) // get the size of the encoding slen := C.i2d_SSL_SESSION(session, nil) buf := (*C.uchar)(C.malloc(C.size_t(slen))) defer C.free(unsafe.Pointer(buf)) // this modifies the value of buf (seriously), so we have to pass in a temp // var so that we can actually read the bytes from buf. tmp := buf slen2 := C.i2d_SSL_SESSION(session, &tmp) if slen != slen2 { return nil, errors.New("session had different lengths") } return C.GoBytes(unsafe.Pointer(buf), slen), nil }
func (c *Conn) setSession(session []byte) error { runtime.LockOSThread() defer runtime.UnlockOSThread() ptr := (*C.uchar)(&session[0]) s := C.d2i_SSL_SESSION(nil, &ptr, C.long(len(session))) if s == nil { return fmt.Errorf("unable to load session: %s", errorFromErrorQueue()) } defer C.SSL_SESSION_free(s) ret := C.SSL_set_session(c.ssl, s) if ret != 1 { return fmt.Errorf("unable to set session: %s", errorFromErrorQueue()) } return nil }