2 * librb: a library used by ircd-ratbox and other things
3 * openssl.c: OpenSSL backend
5 * Copyright (C) 2007-2008 ircd-ratbox development team
6 * Copyright (C) 2007-2008 Aaron Sethman <androsyn@ratbox.org>
7 * Copyright (C) 2015-2016 Aaron Jones <aaronmdjones@gmail.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
26 #include <librb_config.h>
31 #include <commio-int.h>
32 #include <commio-ssl.h>
34 #include "openssl_ratbox.h"
38 RB_FD_TLS_DIRECTION_IN
= 0,
39 RB_FD_TLS_DIRECTION_OUT
= 1
40 } rb_fd_tls_direction
;
42 #define SSL_P(x) ((SSL *)((x)->ssl))
46 static SSL_CTX
*ssl_ctx
= NULL
;
55 static const char *rb_ssl_strerror(unsigned long);
56 static void rb_ssl_connect_realcb(rb_fde_t
*, int, struct ssl_connect
*);
61 * Internal OpenSSL-specific code
67 unsigned long err_saved
, err
= 0;
69 while((err_saved
= ERR_get_error()) != 0)
76 rb_ssl_init_fd(rb_fde_t
*const F
, const rb_fd_tls_direction dir
)
78 (void) rb_ssl_last_err();
80 F
->ssl
= SSL_new(ssl_ctx
);
84 rb_lib_log("%s: SSL_new: %s", __func__
, rb_ssl_strerror(rb_ssl_last_err()));
91 case RB_FD_TLS_DIRECTION_IN
:
92 SSL_set_accept_state(SSL_P(F
));
94 case RB_FD_TLS_DIRECTION_OUT
:
95 SSL_set_connect_state(SSL_P(F
));
99 SSL_set_fd(SSL_P(F
), rb_get_fd(F
));
103 rb_ssl_accept_common(rb_fde_t
*const F
, void *const data
__attribute__((unused
)))
105 lrb_assert(F
!= NULL
);
106 lrb_assert(F
->accept
!= NULL
);
107 lrb_assert(F
->accept
->callback
!= NULL
);
108 lrb_assert(F
->ssl
!= NULL
);
110 (void) rb_ssl_last_err();
112 int ret
= SSL_do_handshake(SSL_P(F
));
113 int err
= SSL_get_error(SSL_P(F
), ret
);
117 F
->handshake_count
++;
119 rb_settimeout(F
, 0, NULL
, NULL
);
120 rb_setselect(F
, RB_SELECT_READ
| RB_SELECT_WRITE
, NULL
, NULL
);
122 struct acceptdata
*const ad
= F
->accept
;
124 ad
->callback(F
, RB_OK
, (struct sockaddr
*)&ad
->S
, ad
->addrlen
, ad
->data
);
129 if(ret
== -1 && err
== SSL_ERROR_WANT_READ
)
131 rb_setselect(F
, RB_SELECT_READ
, rb_ssl_accept_common
, NULL
);
134 if(ret
== -1 && err
== SSL_ERROR_WANT_WRITE
)
136 rb_setselect(F
, RB_SELECT_WRITE
, rb_ssl_accept_common
, NULL
);
141 F
->ssl_errno
= (unsigned long) err
;
142 F
->accept
->callback(F
, RB_ERROR_SSL
, NULL
, 0, F
->accept
->data
);
146 rb_ssl_connect_common(rb_fde_t
*const F
, void *const data
)
148 lrb_assert(F
!= NULL
);
149 lrb_assert(F
->ssl
!= NULL
);
151 (void) rb_ssl_last_err();
153 int ret
= SSL_do_handshake(SSL_P(F
));
154 int err
= SSL_get_error(SSL_P(F
), ret
);
158 F
->handshake_count
++;
160 rb_settimeout(F
, 0, NULL
, NULL
);
161 rb_setselect(F
, RB_SELECT_READ
| RB_SELECT_WRITE
, NULL
, NULL
);
163 rb_ssl_connect_realcb(F
, RB_OK
, data
);
167 if(ret
== -1 && err
== SSL_ERROR_WANT_READ
)
169 rb_setselect(F
, RB_SELECT_READ
, rb_ssl_connect_common
, data
);
172 if(ret
== -1 && err
== SSL_ERROR_WANT_WRITE
)
174 rb_setselect(F
, RB_SELECT_WRITE
, rb_ssl_connect_common
, data
);
179 F
->ssl_errno
= (unsigned long) err
;
180 rb_ssl_connect_realcb(F
, RB_ERROR_SSL
, data
);
184 rb_ssl_strerror(const unsigned long err
)
186 static char errbuf
[512];
188 ERR_error_string_n(err
, errbuf
, sizeof errbuf
);
194 verify_accept_all_cb(const int preverify_ok
__attribute__((unused
)), X509_STORE_CTX
*const x509_ctx
__attribute__((unused
)))
200 rb_ssl_read_or_write(const int r_or_w
, rb_fde_t
*const F
, void *const rbuf
, const void *const wbuf
, const size_t count
)
205 (void) rb_ssl_last_err();
208 ret
= (ssize_t
) SSL_read(SSL_P(F
), rbuf
, (int)count
);
210 ret
= (ssize_t
) SSL_write(SSL_P(F
), wbuf
, (int)count
);
214 switch(SSL_get_error(SSL_P(F
), ret
))
216 case SSL_ERROR_WANT_READ
:
218 return RB_RW_SSL_NEED_READ
;
219 case SSL_ERROR_WANT_WRITE
:
221 return RB_RW_SSL_NEED_WRITE
;
222 case SSL_ERROR_ZERO_RETURN
:
224 case SSL_ERROR_SYSCALL
:
225 err
= rb_ssl_last_err();
229 return RB_RW_IO_ERROR
;
233 err
= rb_ssl_last_err();
240 errno
= EIO
; /* not great but... */
241 return RB_RW_SSL_ERROR
;
243 return RB_RW_IO_ERROR
;
249 make_certfp(X509
*const cert
, uint8_t certfp
[const RB_SSL_CERTFP_LEN
], const int method
)
251 unsigned int hashlen
= 0;
252 const EVP_MD
*md_type
= NULL
;
253 const ASN1_ITEM
*item
= NULL
;
258 case RB_SSL_CERTFP_METH_CERT_SHA1
:
259 hashlen
= RB_SSL_CERTFP_LEN_SHA1
;
260 md_type
= EVP_sha1();
261 item
= ASN1_ITEM_rptr(X509
);
264 case RB_SSL_CERTFP_METH_CERT_SHA256
:
265 hashlen
= RB_SSL_CERTFP_LEN_SHA256
;
266 md_type
= EVP_sha256();
267 item
= ASN1_ITEM_rptr(X509
);
270 case RB_SSL_CERTFP_METH_CERT_SHA512
:
271 hashlen
= RB_SSL_CERTFP_LEN_SHA512
;
272 md_type
= EVP_sha512();
273 item
= ASN1_ITEM_rptr(X509
);
276 case RB_SSL_CERTFP_METH_SPKI_SHA256
:
277 hashlen
= RB_SSL_CERTFP_LEN_SHA256
;
278 md_type
= EVP_sha256();
279 item
= ASN1_ITEM_rptr(X509_PUBKEY
);
280 data
= X509_get_X509_PUBKEY(cert
);
282 case RB_SSL_CERTFP_METH_SPKI_SHA512
:
283 hashlen
= RB_SSL_CERTFP_LEN_SHA512
;
284 md_type
= EVP_sha512();
285 item
= ASN1_ITEM_rptr(X509_PUBKEY
);
286 data
= X509_get_X509_PUBKEY(cert
);
292 if(ASN1_item_digest(item
, md_type
, data
, certfp
, &hashlen
) != 1)
294 rb_lib_log("%s: ASN1_item_digest: %s", __func__
, rb_ssl_strerror(rb_ssl_last_err()));
298 return (int) hashlen
;
304 * External OpenSSL-specific code
308 rb_ssl_shutdown(rb_fde_t
*const F
)
310 if(F
== NULL
|| F
->ssl
== NULL
)
313 (void) rb_ssl_last_err();
315 for(int i
= 0; i
< 4; i
++)
317 int ret
= SSL_shutdown(SSL_P(F
));
318 int err
= SSL_get_error(SSL_P(F
), ret
);
320 if(ret
>= 0 || (err
!= SSL_ERROR_WANT_READ
&& err
!= SSL_ERROR_WANT_WRITE
))
331 #ifndef LRB_SSL_NO_EXPLICIT_INIT
332 (void) SSL_library_init();
333 SSL_load_error_strings();
336 rb_lib_log("%s: OpenSSL backend initialised", __func__
);
341 rb_setup_ssl_server(const char *const certfile
, const char *keyfile
,
342 const char *const dhfile
, const char *cipherlist
)
346 rb_lib_log("%s: no certificate file specified", __func__
);
353 if(cipherlist
== NULL
)
354 cipherlist
= rb_default_ciphers
;
357 (void) rb_ssl_last_err();
359 #ifdef LRB_HAVE_TLS_METHOD_API
360 SSL_CTX
*const ssl_ctx_new
= SSL_CTX_new(TLS_method());
362 SSL_CTX
*const ssl_ctx_new
= SSL_CTX_new(SSLv23_method());
365 if(ssl_ctx_new
== NULL
)
367 rb_lib_log("%s: SSL_CTX_new: %s", __func__
, rb_ssl_strerror(rb_ssl_last_err()));
371 if(SSL_CTX_use_certificate_chain_file(ssl_ctx_new
, certfile
) != 1)
373 rb_lib_log("%s: SSL_CTX_use_certificate_chain_file ('%s'): %s", __func__
, certfile
,
374 rb_ssl_strerror(rb_ssl_last_err()));
376 SSL_CTX_free(ssl_ctx_new
);
380 if(SSL_CTX_use_PrivateKey_file(ssl_ctx_new
, keyfile
, SSL_FILETYPE_PEM
) != 1)
382 rb_lib_log("%s: SSL_CTX_use_PrivateKey_file ('%s'): %s", __func__
, keyfile
,
383 rb_ssl_strerror(rb_ssl_last_err()));
385 SSL_CTX_free(ssl_ctx_new
);
391 rb_lib_log("%s: no DH parameters file specified", __func__
);
395 BIO
*const dhf
= BIO_new_file(dhfile
, "r");
396 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
397 EVP_PKEY
*dhp
= NULL
;
404 rb_lib_log("%s: BIO_new_file ('%s'): %s", __func__
, dhfile
,
405 rb_ssl_strerror(rb_ssl_last_err()));
407 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
408 else if(PEM_read_bio_Parameters(dhf
, &dhp
) == NULL
)
410 rb_lib_log("%s: PEM_read_bio_Parameters ('%s'): %s", __func__
, dhfile
,
411 rb_ssl_strerror(rb_ssl_last_err()));
414 else if(PEM_read_bio_DHparams(dhf
, &dhp
, NULL
, NULL
) == NULL
)
416 rb_lib_log("%s: PEM_read_bio_DHparams ('%s'): %s", __func__
, dhfile
,
417 rb_ssl_strerror(rb_ssl_last_err()));
422 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
423 if(SSL_CTX_set0_tmp_dh_pkey(ssl_ctx_new
, dhp
) != 1)
425 rb_lib_log("%s: SSL_CTX_set0_tmp_dh_pkey ('%s'): %s", __func__
, dhfile
,
426 rb_ssl_strerror(rb_ssl_last_err()));
430 SSL_CTX_set_tmp_dh(ssl_ctx_new
, dhp
);
438 int ret_old
= SSL_CTX_set_cipher_list(ssl_ctx_new
, cipherlist
);
442 (void) rb_lib_log("%s: no valid old-style ciphersuites found "
443 "in ssl_cipher_list; will use defaults",
446 ret_old
= SSL_CTX_set_cipher_list(ssl_ctx_new
, rb_default_ciphers
);
449 #ifndef LRB_HAVE_TLS13
452 int ret_new
= SSL_CTX_set_ciphersuites(ssl_ctx_new
, cipherlist
);
456 (void) rb_lib_log("%s: no valid new-style ciphersuites found "
457 "in ssl_cipher_list; will use defaults",
460 ret_new
= SSL_CTX_set_ciphersuites(ssl_ctx_new
, rb_default_ciphers
);
464 if (ret_old
!= 1 && ret_new
!= 1)
466 rb_lib_log("%s: could not configure any ciphers", __func__
);
467 SSL_CTX_free(ssl_ctx_new
);
472 SSL_CTX_set_session_cache_mode(ssl_ctx_new
, SSL_SESS_CACHE_OFF
);
473 SSL_CTX_set_verify(ssl_ctx_new
, SSL_VERIFY_PEER
| SSL_VERIFY_CLIENT_ONCE
, verify_accept_all_cb
);
475 #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
476 (void) SSL_CTX_clear_options(ssl_ctx_new
, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
);
479 #ifndef LRB_HAVE_TLS_METHOD_API
480 (void) SSL_CTX_set_options(ssl_ctx_new
, SSL_OP_NO_SSLv2
| SSL_OP_NO_SSLv3
);
483 #ifdef SSL_OP_NO_TICKET
484 (void) SSL_CTX_set_options(ssl_ctx_new
, SSL_OP_NO_TICKET
);
487 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
488 (void) SSL_CTX_set_options(ssl_ctx_new
, SSL_OP_CIPHER_SERVER_PREFERENCE
);
491 #ifdef SSL_OP_SINGLE_DH_USE
492 (void) SSL_CTX_set_options(ssl_ctx_new
, SSL_OP_SINGLE_DH_USE
);
495 #ifdef SSL_OP_SINGLE_ECDH_USE
496 (void) SSL_CTX_set_options(ssl_ctx_new
, SSL_OP_SINGLE_ECDH_USE
);
499 #ifdef LRB_HAVE_TLS_ECDH_AUTO
500 (void) SSL_CTX_set_ecdh_auto(ssl_ctx_new
, 1);
503 #ifdef LRB_HAVE_TLS_SET_CURVES
504 (void) SSL_CTX_set1_curves_list(ssl_ctx_new
, rb_default_curves
);
506 # if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && !defined(OPENSSL_NO_ECDH) && defined(NID_secp384r1)
507 EC_KEY
*const ec_key
= EC_KEY_new_by_curve_name(NID_secp384r1
);
510 SSL_CTX_set_tmp_ecdh(ssl_ctx_new
, ec_key
);
514 rb_lib_log("%s: EC_KEY_new_by_curve_name failed; will not enable ECDHE- ciphers", __func__
);
516 rb_lib_log("%s: OpenSSL built without ECDH support; will not enable ECDHE- ciphers", __func__
);
522 SSL_CTX_free(ssl_ctx
);
524 ssl_ctx
= ssl_ctx_new
;
527 rb_lib_log("%s: TLS configuration successful", __func__
);
532 rb_init_prng(const char *const path
, prng_seed_t seed_type
)
534 (void) rb_ssl_last_err();
536 if(seed_type
== RB_PRNG_FILE
&& RAND_load_file(path
, -1) < 0)
537 rb_lib_log("%s: RAND_load_file: %s", __func__
, rb_ssl_strerror(rb_ssl_last_err()));
539 if(RAND_status() != 1)
541 rb_lib_log("%s: RAND_status: %s", __func__
, rb_ssl_strerror(rb_ssl_last_err()));
545 rb_lib_log("%s: PRNG initialised", __func__
);
550 rb_get_random(void *const buf
, const size_t length
)
552 (void) rb_ssl_last_err();
554 if(RAND_bytes(buf
, (int) length
) != 1)
556 rb_lib_log("%s: RAND_bytes: %s", __func__
, rb_ssl_strerror(rb_ssl_last_err()));
564 rb_get_ssl_strerror(rb_fde_t
*const F
)
566 return rb_ssl_strerror(F
->ssl_errno
);
570 rb_get_ssl_certfp(rb_fde_t
*const F
, uint8_t certfp
[const RB_SSL_CERTFP_LEN
], const int method
)
572 if(F
== NULL
|| F
->ssl
== NULL
)
575 X509
*const peer_cert
= SSL_get_peer_certificate(SSL_P(F
));
576 if(peer_cert
== NULL
)
581 switch(SSL_get_verify_result(SSL_P(F
)))
584 case X509_V_ERR_CERT_HAS_EXPIRED
:
585 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
:
586 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
:
587 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
:
588 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
:
589 case X509_V_ERR_CERT_UNTRUSTED
:
590 len
= make_certfp(peer_cert
, certfp
, method
);
593 X509_free(peer_cert
);
599 rb_get_ssl_certfp_file(const char *const filename
, uint8_t certfp
[const RB_SSL_CERTFP_LEN
], const int method
)
601 FILE *const fp
= fopen(filename
, "r");
605 X509
*const cert
= PEM_read_X509(fp
, NULL
, NULL
, NULL
);
612 int len
= make_certfp(cert
, certfp
, method
);
621 rb_get_ssl_info(char *const buf
, const size_t len
)
623 #ifdef LRB_SSL_FULL_VERSION_INFO
624 if(LRB_SSL_VNUM_RUNTIME
== LRB_SSL_VNUM_COMPILETIME
)
625 (void) snprintf(buf
, len
, "OpenSSL: compiled 0x%lx, library %s",
626 LRB_SSL_VNUM_COMPILETIME
, LRB_SSL_VTEXT_COMPILETIME
);
628 (void) snprintf(buf
, len
, "OpenSSL: compiled (0x%lx, %s), library (0x%lx, %s)",
629 LRB_SSL_VNUM_COMPILETIME
, LRB_SSL_VTEXT_COMPILETIME
,
630 LRB_SSL_VNUM_RUNTIME
, LRB_SSL_VTEXT_RUNTIME
);
632 (void) snprintf(buf
, len
, "OpenSSL: compiled 0x%lx, library %s",
633 LRB_SSL_VNUM_COMPILETIME
, LRB_SSL_VTEXT_RUNTIME
);
638 rb_ssl_get_cipher(rb_fde_t
*const F
)
640 if(F
== NULL
|| F
->ssl
== NULL
)
643 static char buf
[512];
645 const char *const version
= SSL_get_version(SSL_P(F
));
646 const char *const cipher
= SSL_get_cipher_name(SSL_P(F
));
648 (void) snprintf(buf
, sizeof buf
, "%s, %s", version
, cipher
);
654 rb_ssl_read(rb_fde_t
*const F
, void *const buf
, const size_t count
)
656 return rb_ssl_read_or_write(0, F
, buf
, NULL
, count
);
660 rb_ssl_write(rb_fde_t
*const F
, const void *const buf
, const size_t count
)
662 return rb_ssl_read_or_write(1, F
, NULL
, buf
, count
);
668 * Internal library-agnostic code
672 rb_ssl_connect_realcb(rb_fde_t
*const F
, const int status
, struct ssl_connect
*const sconn
)
674 lrb_assert(F
->connect
!= NULL
);
676 F
->connect
->callback
= sconn
->callback
;
677 F
->connect
->data
= sconn
->data
;
679 rb_connect_callback(F
, status
);
684 rb_ssl_timeout_cb(rb_fde_t
*const F
, void *const data
__attribute__((unused
)))
686 lrb_assert(F
->accept
!= NULL
);
687 lrb_assert(F
->accept
->callback
!= NULL
);
689 F
->accept
->callback(F
, RB_ERR_TIMEOUT
, NULL
, 0, F
->accept
->data
);
693 rb_ssl_tryconn_timeout_cb(rb_fde_t
*const F
, void *const data
)
695 rb_ssl_connect_realcb(F
, RB_ERR_TIMEOUT
, data
);
699 rb_ssl_tryconn(rb_fde_t
*const F
, const int status
, void *const data
)
701 lrb_assert(F
!= NULL
);
703 struct ssl_connect
*const sconn
= data
;
707 rb_ssl_connect_realcb(F
, status
, sconn
);
711 F
->type
|= RB_FD_SSL
;
713 rb_settimeout(F
, sconn
->timeout
, rb_ssl_tryconn_timeout_cb
, sconn
);
714 rb_ssl_init_fd(F
, RB_FD_TLS_DIRECTION_OUT
);
715 rb_ssl_connect_common(F
, sconn
);
721 * External library-agnostic code
725 rb_supports_ssl(void)
731 rb_ssl_handshake_count(rb_fde_t
*const F
)
733 return F
->handshake_count
;
737 rb_ssl_clear_handshake_count(rb_fde_t
*const F
)
739 F
->handshake_count
= 0;
743 rb_ssl_start_accepted(rb_fde_t
*const F
, ACCB
*const cb
, void *const data
, const int timeout
)
745 F
->type
|= RB_FD_SSL
;
747 F
->accept
= rb_malloc(sizeof(struct acceptdata
));
748 F
->accept
->callback
= cb
;
749 F
->accept
->data
= data
;
750 F
->accept
->addrlen
= 0;
751 (void) memset(&F
->accept
->S
, 0x00, sizeof F
->accept
->S
);
753 rb_settimeout(F
, timeout
, rb_ssl_timeout_cb
, NULL
);
754 rb_ssl_init_fd(F
, RB_FD_TLS_DIRECTION_IN
);
755 rb_ssl_accept_common(F
, NULL
);
759 rb_ssl_accept_setup(rb_fde_t
*const srv_F
, rb_fde_t
*const cli_F
, struct sockaddr
*const st
, const int addrlen
)
761 cli_F
->type
|= RB_FD_SSL
;
763 cli_F
->accept
= rb_malloc(sizeof(struct acceptdata
));
764 cli_F
->accept
->callback
= srv_F
->accept
->callback
;
765 cli_F
->accept
->data
= srv_F
->accept
->data
;
766 cli_F
->accept
->addrlen
= (rb_socklen_t
) addrlen
;
767 (void) memset(&cli_F
->accept
->S
, 0x00, sizeof cli_F
->accept
->S
);
768 (void) memcpy(&cli_F
->accept
->S
, st
, (size_t) addrlen
);
770 rb_settimeout(cli_F
, 10, rb_ssl_timeout_cb
, NULL
);
771 rb_ssl_init_fd(cli_F
, RB_FD_TLS_DIRECTION_IN
);
772 rb_ssl_accept_common(cli_F
, NULL
);
776 rb_ssl_listen(rb_fde_t
*const F
, const int backlog
, const int defer_accept
)
778 int result
= rb_listen(F
, backlog
, defer_accept
);
780 F
->type
= RB_FD_SOCKET
| RB_FD_LISTEN
| RB_FD_SSL
;
786 rb_connect_tcp_ssl(rb_fde_t
*const F
, struct sockaddr
*const dest
, struct sockaddr
*const clocal
,
787 CNCB
*const callback
, void *const data
, const int timeout
)
792 struct ssl_connect
*const sconn
= rb_malloc(sizeof *sconn
);
794 sconn
->callback
= callback
;
795 sconn
->timeout
= timeout
;
797 rb_connect_tcp(F
, dest
, clocal
, rb_ssl_tryconn
, sconn
, timeout
);
801 rb_ssl_start_connected(rb_fde_t
*const F
, CNCB
*const callback
, void *const data
, const int timeout
)
806 struct ssl_connect
*const sconn
= rb_malloc(sizeof *sconn
);
808 sconn
->callback
= callback
;
809 sconn
->timeout
= timeout
;
811 F
->connect
= rb_malloc(sizeof(struct conndata
));
812 F
->connect
->callback
= callback
;
813 F
->connect
->data
= data
;
814 F
->type
|= RB_FD_SSL
;
816 rb_settimeout(F
, sconn
->timeout
, rb_ssl_tryconn_timeout_cb
, sconn
);
817 rb_ssl_init_fd(F
, RB_FD_TLS_DIRECTION_OUT
);
818 rb_ssl_connect_common(F
, sconn
);
821 #endif /* HAVE_OPENSSL */