conn.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. // Copyright (C) 2017. See AUTHORS.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package openssl
  15. // #include "shim.h"
  16. import "C"
  17. import (
  18. "errors"
  19. "fmt"
  20. "io"
  21. "net"
  22. "runtime"
  23. "sync"
  24. "time"
  25. "unsafe"
  26. "github.com/spacemonkeygo/openssl/utils"
  27. )
  28. var (
  29. zeroReturn = errors.New("zero return")
  30. wantRead = errors.New("want read")
  31. wantWrite = errors.New("want write")
  32. tryAgain = errors.New("try again")
  33. )
  34. type Conn struct {
  35. *SSL
  36. conn net.Conn
  37. ctx *Ctx // for gc
  38. into_ssl *readBio
  39. from_ssl *writeBio
  40. is_shutdown bool
  41. mtx sync.Mutex
  42. want_read_future *utils.Future
  43. }
  44. type VerifyResult int
  45. const (
  46. Ok VerifyResult = C.X509_V_OK
  47. UnableToGetIssuerCert VerifyResult = C.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
  48. UnableToGetCrl VerifyResult = C.X509_V_ERR_UNABLE_TO_GET_CRL
  49. UnableToDecryptCertSignature VerifyResult = C.X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE
  50. UnableToDecryptCrlSignature VerifyResult = C.X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE
  51. UnableToDecodeIssuerPublicKey VerifyResult = C.X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY
  52. CertSignatureFailure VerifyResult = C.X509_V_ERR_CERT_SIGNATURE_FAILURE
  53. CrlSignatureFailure VerifyResult = C.X509_V_ERR_CRL_SIGNATURE_FAILURE
  54. CertNotYetValid VerifyResult = C.X509_V_ERR_CERT_NOT_YET_VALID
  55. CertHasExpired VerifyResult = C.X509_V_ERR_CERT_HAS_EXPIRED
  56. CrlNotYetValid VerifyResult = C.X509_V_ERR_CRL_NOT_YET_VALID
  57. CrlHasExpired VerifyResult = C.X509_V_ERR_CRL_HAS_EXPIRED
  58. ErrorInCertNotBeforeField VerifyResult = C.X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
  59. ErrorInCertNotAfterField VerifyResult = C.X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
  60. ErrorInCrlLastUpdateField VerifyResult = C.X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
  61. ErrorInCrlNextUpdateField VerifyResult = C.X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
  62. OutOfMem VerifyResult = C.X509_V_ERR_OUT_OF_MEM
  63. DepthZeroSelfSignedCert VerifyResult = C.X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
  64. SelfSignedCertInChain VerifyResult = C.X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
  65. UnableToGetIssuerCertLocally VerifyResult = C.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
  66. UnableToVerifyLeafSignature VerifyResult = C.X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
  67. CertChainTooLong VerifyResult = C.X509_V_ERR_CERT_CHAIN_TOO_LONG
  68. CertRevoked VerifyResult = C.X509_V_ERR_CERT_REVOKED
  69. InvalidCa VerifyResult = C.X509_V_ERR_INVALID_CA
  70. PathLengthExceeded VerifyResult = C.X509_V_ERR_PATH_LENGTH_EXCEEDED
  71. InvalidPurpose VerifyResult = C.X509_V_ERR_INVALID_PURPOSE
  72. CertUntrusted VerifyResult = C.X509_V_ERR_CERT_UNTRUSTED
  73. CertRejected VerifyResult = C.X509_V_ERR_CERT_REJECTED
  74. SubjectIssuerMismatch VerifyResult = C.X509_V_ERR_SUBJECT_ISSUER_MISMATCH
  75. AkidSkidMismatch VerifyResult = C.X509_V_ERR_AKID_SKID_MISMATCH
  76. AkidIssuerSerialMismatch VerifyResult = C.X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH
  77. KeyusageNoCertsign VerifyResult = C.X509_V_ERR_KEYUSAGE_NO_CERTSIGN
  78. UnableToGetCrlIssuer VerifyResult = C.X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER
  79. UnhandledCriticalExtension VerifyResult = C.X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION
  80. KeyusageNoCrlSign VerifyResult = C.X509_V_ERR_KEYUSAGE_NO_CRL_SIGN
  81. UnhandledCriticalCrlExtension VerifyResult = C.X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION
  82. InvalidNonCa VerifyResult = C.X509_V_ERR_INVALID_NON_CA
  83. ProxyPathLengthExceeded VerifyResult = C.X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED
  84. KeyusageNoDigitalSignature VerifyResult = C.X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE
  85. ProxyCertificatesNotAllowed VerifyResult = C.X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED
  86. InvalidExtension VerifyResult = C.X509_V_ERR_INVALID_EXTENSION
  87. InvalidPolicyExtension VerifyResult = C.X509_V_ERR_INVALID_POLICY_EXTENSION
  88. NoExplicitPolicy VerifyResult = C.X509_V_ERR_NO_EXPLICIT_POLICY
  89. UnnestedResource VerifyResult = C.X509_V_ERR_UNNESTED_RESOURCE
  90. ApplicationVerification VerifyResult = C.X509_V_ERR_APPLICATION_VERIFICATION
  91. )
  92. func newSSL(ctx *C.SSL_CTX) (*C.SSL, error) {
  93. runtime.LockOSThread()
  94. defer runtime.UnlockOSThread()
  95. ssl := C.SSL_new(ctx)
  96. if ssl == nil {
  97. return nil, errorFromErrorQueue()
  98. }
  99. return ssl, nil
  100. }
  101. func newConn(conn net.Conn, ctx *Ctx) (*Conn, error) {
  102. ssl, err := newSSL(ctx.ctx)
  103. if err != nil {
  104. return nil, err
  105. }
  106. into_ssl := &readBio{}
  107. from_ssl := &writeBio{}
  108. if ctx.GetMode()&ReleaseBuffers > 0 {
  109. into_ssl.release_buffers = true
  110. from_ssl.release_buffers = true
  111. }
  112. into_ssl_cbio := into_ssl.MakeCBIO()
  113. from_ssl_cbio := from_ssl.MakeCBIO()
  114. if into_ssl_cbio == nil || from_ssl_cbio == nil {
  115. // these frees are null safe
  116. C.BIO_free(into_ssl_cbio)
  117. C.BIO_free(from_ssl_cbio)
  118. C.SSL_free(ssl)
  119. return nil, errors.New("failed to allocate memory BIO")
  120. }
  121. // the ssl object takes ownership of these objects now
  122. C.SSL_set_bio(ssl, into_ssl_cbio, from_ssl_cbio)
  123. s := &SSL{ssl: ssl}
  124. C.SSL_set_ex_data(s.ssl, get_ssl_idx(), unsafe.Pointer(s))
  125. c := &Conn{
  126. SSL: s,
  127. conn: conn,
  128. ctx: ctx,
  129. into_ssl: into_ssl,
  130. from_ssl: from_ssl}
  131. runtime.SetFinalizer(c, func(c *Conn) {
  132. c.into_ssl.Disconnect(into_ssl_cbio)
  133. c.from_ssl.Disconnect(from_ssl_cbio)
  134. C.SSL_free(c.ssl)
  135. })
  136. return c, nil
  137. }
  138. // Client wraps an existing stream connection and puts it in the connect state
  139. // for any subsequent handshakes.
  140. //
  141. // IMPORTANT NOTE: if you use this method instead of Dial to construct an SSL
  142. // connection, you are responsible for verifying the peer's hostname.
  143. // Otherwise, you are vulnerable to MITM attacks.
  144. //
  145. // Client also does not set up SNI for you like Dial does.
  146. //
  147. // Client connections probably won't work for you unless you set a verify
  148. // location or add some certs to the certificate store of the client context
  149. // you're using. This library is not nice enough to use the system certificate
  150. // store by default for you yet.
  151. func Client(conn net.Conn, ctx *Ctx) (*Conn, error) {
  152. c, err := newConn(conn, ctx)
  153. if err != nil {
  154. return nil, err
  155. }
  156. C.SSL_set_connect_state(c.ssl)
  157. return c, nil
  158. }
  159. // Server wraps an existing stream connection and puts it in the accept state
  160. // for any subsequent handshakes.
  161. func Server(conn net.Conn, ctx *Ctx) (*Conn, error) {
  162. c, err := newConn(conn, ctx)
  163. if err != nil {
  164. return nil, err
  165. }
  166. C.SSL_set_accept_state(c.ssl)
  167. return c, nil
  168. }
  169. func (c *Conn) GetCtx() *Ctx { return c.ctx }
  170. func (c *Conn) CurrentCipher() (string, error) {
  171. p := C.X_SSL_get_cipher_name(c.ssl)
  172. if p == nil {
  173. return "", errors.New("Session not established")
  174. }
  175. return C.GoString(p), nil
  176. }
  177. func (c *Conn) fillInputBuffer() error {
  178. for {
  179. n, err := c.into_ssl.ReadFromOnce(c.conn)
  180. if n == 0 && err == nil {
  181. continue
  182. }
  183. if err == io.EOF {
  184. c.into_ssl.MarkEOF()
  185. return c.Close()
  186. }
  187. return err
  188. }
  189. }
  190. func (c *Conn) flushOutputBuffer() error {
  191. _, err := c.from_ssl.WriteTo(c.conn)
  192. return err
  193. }
  194. func (c *Conn) getErrorHandler(rv C.int, errno error) func() error {
  195. errcode := C.SSL_get_error(c.ssl, rv)
  196. switch errcode {
  197. case C.SSL_ERROR_ZERO_RETURN:
  198. return func() error {
  199. c.Close()
  200. return io.ErrUnexpectedEOF
  201. }
  202. case C.SSL_ERROR_WANT_READ:
  203. go c.flushOutputBuffer()
  204. if c.want_read_future != nil {
  205. want_read_future := c.want_read_future
  206. return func() error {
  207. _, err := want_read_future.Get()
  208. return err
  209. }
  210. }
  211. c.want_read_future = utils.NewFuture()
  212. want_read_future := c.want_read_future
  213. return func() (err error) {
  214. defer func() {
  215. c.mtx.Lock()
  216. c.want_read_future = nil
  217. c.mtx.Unlock()
  218. want_read_future.Set(nil, err)
  219. }()
  220. err = c.fillInputBuffer()
  221. if err != nil {
  222. return err
  223. }
  224. return tryAgain
  225. }
  226. case C.SSL_ERROR_WANT_WRITE:
  227. return func() error {
  228. err := c.flushOutputBuffer()
  229. if err != nil {
  230. return err
  231. }
  232. return tryAgain
  233. }
  234. case C.SSL_ERROR_SYSCALL:
  235. var err error
  236. if C.ERR_peek_error() == 0 {
  237. switch rv {
  238. case 0:
  239. err = errors.New("protocol-violating EOF")
  240. case -1:
  241. err = errno
  242. default:
  243. err = errorFromErrorQueue()
  244. }
  245. } else {
  246. err = errorFromErrorQueue()
  247. }
  248. return func() error { return err }
  249. default:
  250. err := errorFromErrorQueue()
  251. return func() error { return err }
  252. }
  253. }
  254. func (c *Conn) handleError(errcb func() error) error {
  255. if errcb != nil {
  256. return errcb()
  257. }
  258. return nil
  259. }
  260. func (c *Conn) handshake() func() error {
  261. c.mtx.Lock()
  262. defer c.mtx.Unlock()
  263. if c.is_shutdown {
  264. return func() error { return io.ErrUnexpectedEOF }
  265. }
  266. runtime.LockOSThread()
  267. defer runtime.UnlockOSThread()
  268. rv, errno := C.SSL_do_handshake(c.ssl)
  269. if rv > 0 {
  270. return nil
  271. }
  272. return c.getErrorHandler(rv, errno)
  273. }
  274. // Handshake performs an SSL handshake. If a handshake is not manually
  275. // triggered, it will run before the first I/O on the encrypted stream.
  276. func (c *Conn) Handshake() error {
  277. err := tryAgain
  278. for err == tryAgain {
  279. err = c.handleError(c.handshake())
  280. }
  281. go c.flushOutputBuffer()
  282. return err
  283. }
  284. // PeerCertificate returns the Certificate of the peer with which you're
  285. // communicating. Only valid after a handshake.
  286. func (c *Conn) PeerCertificate() (*Certificate, error) {
  287. c.mtx.Lock()
  288. defer c.mtx.Unlock()
  289. if c.is_shutdown {
  290. return nil, errors.New("connection closed")
  291. }
  292. x := C.SSL_get_peer_certificate(c.ssl)
  293. if x == nil {
  294. return nil, errors.New("no peer certificate found")
  295. }
  296. cert := &Certificate{x: x}
  297. runtime.SetFinalizer(cert, func(cert *Certificate) {
  298. C.X509_free(cert.x)
  299. })
  300. return cert, nil
  301. }
  302. // loadCertificateStack loads up a stack of x509 certificates and returns them,
  303. // handling memory ownership.
  304. func (c *Conn) loadCertificateStack(sk *C.struct_stack_st_X509) (
  305. rv []*Certificate) {
  306. sk_num := int(C.X_sk_X509_num(sk))
  307. rv = make([]*Certificate, 0, sk_num)
  308. for i := 0; i < sk_num; i++ {
  309. x := C.X_sk_X509_value(sk, C.int(i))
  310. // ref holds on to the underlying connection memory so we don't need to
  311. // worry about incrementing refcounts manually or freeing the X509
  312. rv = append(rv, &Certificate{x: x, ref: c})
  313. }
  314. return rv
  315. }
  316. // PeerCertificateChain returns the certificate chain of the peer. If called on
  317. // the client side, the stack also contains the peer's certificate; if called
  318. // on the server side, the peer's certificate must be obtained separately using
  319. // PeerCertificate.
  320. func (c *Conn) PeerCertificateChain() (rv []*Certificate, err error) {
  321. c.mtx.Lock()
  322. defer c.mtx.Unlock()
  323. if c.is_shutdown {
  324. return nil, errors.New("connection closed")
  325. }
  326. sk := C.SSL_get_peer_cert_chain(c.ssl)
  327. if sk == nil {
  328. return nil, errors.New("no peer certificates found")
  329. }
  330. return c.loadCertificateStack(sk), nil
  331. }
  332. type ConnectionState struct {
  333. Certificate *Certificate
  334. CertificateError error
  335. CertificateChain []*Certificate
  336. CertificateChainError error
  337. SessionReused bool
  338. }
  339. func (c *Conn) ConnectionState() (rv ConnectionState) {
  340. rv.Certificate, rv.CertificateError = c.PeerCertificate()
  341. rv.CertificateChain, rv.CertificateChainError = c.PeerCertificateChain()
  342. rv.SessionReused = c.SessionReused()
  343. return
  344. }
  345. func (c *Conn) shutdown() func() error {
  346. c.mtx.Lock()
  347. defer c.mtx.Unlock()
  348. runtime.LockOSThread()
  349. defer runtime.UnlockOSThread()
  350. rv, errno := C.SSL_shutdown(c.ssl)
  351. if rv > 0 {
  352. return nil
  353. }
  354. if rv == 0 {
  355. // The OpenSSL docs say that in this case, the shutdown is not
  356. // finished, and we should call SSL_shutdown() a second time, if a
  357. // bidirectional shutdown is going to be performed. Further, the
  358. // output of SSL_get_error may be misleading, as an erroneous
  359. // SSL_ERROR_SYSCALL may be flagged even though no error occurred.
  360. // So, TODO: revisit bidrectional shutdown, possibly trying again.
  361. // Note: some broken clients won't engage in bidirectional shutdown
  362. // without tickling them to close by sending a TCP_FIN packet, or
  363. // shutting down the write-side of the connection.
  364. return nil
  365. } else {
  366. return c.getErrorHandler(rv, errno)
  367. }
  368. }
  369. func (c *Conn) shutdownLoop() error {
  370. err := tryAgain
  371. shutdown_tries := 0
  372. for err == tryAgain {
  373. shutdown_tries = shutdown_tries + 1
  374. err = c.handleError(c.shutdown())
  375. if err == nil {
  376. return c.flushOutputBuffer()
  377. }
  378. if err == tryAgain && shutdown_tries >= 2 {
  379. return errors.New("shutdown requested a third time?")
  380. }
  381. }
  382. if err == io.ErrUnexpectedEOF {
  383. err = nil
  384. }
  385. return err
  386. }
  387. // Close shuts down the SSL connection and closes the underlying wrapped
  388. // connection.
  389. func (c *Conn) Close() error {
  390. c.mtx.Lock()
  391. if c.is_shutdown {
  392. c.mtx.Unlock()
  393. return nil
  394. }
  395. c.is_shutdown = true
  396. c.mtx.Unlock()
  397. var errs utils.ErrorGroup
  398. errs.Add(c.shutdownLoop())
  399. errs.Add(c.conn.Close())
  400. return errs.Finalize()
  401. }
  402. func (c *Conn) read(b []byte) (int, func() error) {
  403. if len(b) == 0 {
  404. return 0, nil
  405. }
  406. c.mtx.Lock()
  407. defer c.mtx.Unlock()
  408. if c.is_shutdown {
  409. return 0, func() error { return io.EOF }
  410. }
  411. runtime.LockOSThread()
  412. defer runtime.UnlockOSThread()
  413. rv, errno := C.SSL_read(c.ssl, unsafe.Pointer(&b[0]), C.int(len(b)))
  414. if rv > 0 {
  415. return int(rv), nil
  416. }
  417. return 0, c.getErrorHandler(rv, errno)
  418. }
  419. // Read reads up to len(b) bytes into b. It returns the number of bytes read
  420. // and an error if applicable. io.EOF is returned when the caller can expect
  421. // to see no more data.
  422. func (c *Conn) Read(b []byte) (n int, err error) {
  423. if len(b) == 0 {
  424. return 0, nil
  425. }
  426. err = tryAgain
  427. for err == tryAgain {
  428. n, errcb := c.read(b)
  429. err = c.handleError(errcb)
  430. if err == nil {
  431. go c.flushOutputBuffer()
  432. return n, nil
  433. }
  434. if err == io.ErrUnexpectedEOF {
  435. err = io.EOF
  436. }
  437. }
  438. return 0, err
  439. }
  440. func (c *Conn) write(b []byte) (int, func() error) {
  441. if len(b) == 0 {
  442. return 0, nil
  443. }
  444. c.mtx.Lock()
  445. defer c.mtx.Unlock()
  446. if c.is_shutdown {
  447. err := errors.New("connection closed")
  448. return 0, func() error { return err }
  449. }
  450. runtime.LockOSThread()
  451. defer runtime.UnlockOSThread()
  452. rv, errno := C.SSL_write(c.ssl, unsafe.Pointer(&b[0]), C.int(len(b)))
  453. if rv > 0 {
  454. return int(rv), nil
  455. }
  456. return 0, c.getErrorHandler(rv, errno)
  457. }
  458. // Write will encrypt the contents of b and write it to the underlying stream.
  459. // Performance will be vastly improved if the size of b is a multiple of
  460. // SSLRecordSize.
  461. func (c *Conn) Write(b []byte) (written int, err error) {
  462. if len(b) == 0 {
  463. return 0, nil
  464. }
  465. err = tryAgain
  466. for err == tryAgain {
  467. n, errcb := c.write(b)
  468. err = c.handleError(errcb)
  469. if err == nil {
  470. return n, c.flushOutputBuffer()
  471. }
  472. }
  473. return 0, err
  474. }
  475. // VerifyHostname pulls the PeerCertificate and calls VerifyHostname on the
  476. // certificate.
  477. func (c *Conn) VerifyHostname(host string) error {
  478. cert, err := c.PeerCertificate()
  479. if err != nil {
  480. return err
  481. }
  482. return cert.VerifyHostname(host)
  483. }
  484. // LocalAddr returns the underlying connection's local address
  485. func (c *Conn) LocalAddr() net.Addr {
  486. return c.conn.LocalAddr()
  487. }
  488. // RemoteAddr returns the underlying connection's remote address
  489. func (c *Conn) RemoteAddr() net.Addr {
  490. return c.conn.RemoteAddr()
  491. }
  492. // SetDeadline calls SetDeadline on the underlying connection.
  493. func (c *Conn) SetDeadline(t time.Time) error {
  494. return c.conn.SetDeadline(t)
  495. }
  496. // SetReadDeadline calls SetReadDeadline on the underlying connection.
  497. func (c *Conn) SetReadDeadline(t time.Time) error {
  498. return c.conn.SetReadDeadline(t)
  499. }
  500. // SetWriteDeadline calls SetWriteDeadline on the underlying connection.
  501. func (c *Conn) SetWriteDeadline(t time.Time) error {
  502. return c.conn.SetWriteDeadline(t)
  503. }
  504. func (c *Conn) UnderlyingConn() net.Conn {
  505. return c.conn
  506. }
  507. func (c *Conn) SetTlsExtHostName(name string) error {
  508. cname := C.CString(name)
  509. defer C.free(unsafe.Pointer(cname))
  510. runtime.LockOSThread()
  511. defer runtime.UnlockOSThread()
  512. if C.X_SSL_set_tlsext_host_name(c.ssl, cname) == 0 {
  513. return errorFromErrorQueue()
  514. }
  515. return nil
  516. }
  517. func (c *Conn) VerifyResult() VerifyResult {
  518. return VerifyResult(C.SSL_get_verify_result(c.ssl))
  519. }
  520. func (c *Conn) SessionReused() bool {
  521. return C.X_SSL_session_reused(c.ssl) == 1
  522. }
  523. func (c *Conn) GetSession() ([]byte, error) {
  524. runtime.LockOSThread()
  525. defer runtime.UnlockOSThread()
  526. // get1 increases the refcount of the session, so we have to free it.
  527. session := (*C.SSL_SESSION)(C.SSL_get1_session(c.ssl))
  528. if session == nil {
  529. return nil, errors.New("failed to get session")
  530. }
  531. defer C.SSL_SESSION_free(session)
  532. // get the size of the encoding
  533. slen := C.i2d_SSL_SESSION(session, nil)
  534. buf := (*C.uchar)(C.malloc(C.size_t(slen)))
  535. defer C.free(unsafe.Pointer(buf))
  536. // this modifies the value of buf (seriously), so we have to pass in a temp
  537. // var so that we can actually read the bytes from buf.
  538. tmp := buf
  539. slen2 := C.i2d_SSL_SESSION(session, &tmp)
  540. if slen != slen2 {
  541. return nil, errors.New("session had different lengths")
  542. }
  543. return C.GoBytes(unsafe.Pointer(buf), slen), nil
  544. }
  545. func (c *Conn) setSession(session []byte) error {
  546. runtime.LockOSThread()
  547. defer runtime.UnlockOSThread()
  548. ptr := (*C.uchar)(&session[0])
  549. s := C.d2i_SSL_SESSION(nil, &ptr, C.long(len(session)))
  550. if s == nil {
  551. return fmt.Errorf("unable to load session: %s", errorFromErrorQueue())
  552. }
  553. defer C.SSL_SESSION_free(s)
  554. ret := C.SSL_set_session(c.ssl, s)
  555. if ret != 1 {
  556. return fmt.Errorf("unable to set session: %s", errorFromErrorQueue())
  557. }
  558. return nil
  559. }