14 #define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
17 # define TO_SOCKET(s) _get_osfhandle(s)
19 # define TO_SOCKET(s) (s)
22 #define GetSSLCTX(obj, ctx) do { \
23 TypedData_Get_Struct((obj), SSL_CTX, &ossl_sslctx_type, (ctx)); \
27 static VALUE mSSLExtConfig;
28 static VALUE eSSLError;
32 static VALUE eSSLErrorWaitReadable;
33 static VALUE eSSLErrorWaitWritable;
35 static ID id_call, ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
36 id_npn_protocols_encoded;
37 static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
39 static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
40 id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
41 id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
42 id_i_client_cert_cb, id_i_tmp_ecdh_callback, id_i_timeout,
43 id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
44 id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
45 id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
47 static ID id_i_io, id_i_context, id_i_hostname;
49 static int ossl_ssl_ex_vcb_idx;
50 static int ossl_ssl_ex_ptr_idx;
51 static int ossl_sslctx_ex_ptr_idx;
52 #if !defined(HAVE_X509_STORE_UP_REF)
53 static int ossl_sslctx_ex_store_p;
57 ossl_sslctx_free(
void *
ptr)
60 #if !defined(HAVE_X509_STORE_UP_REF)
61 if (ctx && SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_store_p))
62 ctx->cert_store =
NULL;
80 SSL_MODE_ENABLE_PARTIAL_WRITE |
81 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
82 SSL_MODE_RELEASE_BUFFERS;
86 #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
87 ctx = SSL_CTX_new(TLS_method());
89 ctx = SSL_CTX_new(SSLv23_method());
94 SSL_CTX_set_mode(ctx, mode);
96 SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (
void *)
obj);
98 #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
106 if (!SSL_CTX_set_ecdh_auto(ctx, 1))
107 ossl_raise(eSSLError,
"SSL_CTX_set_ecdh_auto");
117 static const struct {
121 {
"SSL2", SSL2_VERSION },
122 {
"SSL3", SSL3_VERSION },
123 {
"TLS1", TLS1_VERSION },
124 {
"TLS1_1", TLS1_1_VERSION },
125 {
"TLS1_2", TLS1_2_VERSION },
126 #ifdef TLS1_3_VERSION
127 {
"TLS1_3", TLS1_3_VERSION },
141 return map[
i].version;
153 ossl_sslctx_set_minmax_proto_version(
VALUE self,
VALUE min_v,
VALUE max_v)
159 min = parse_proto_version(min_v);
160 max = parse_proto_version(max_v);
162 #ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
163 if (!SSL_CTX_set_min_proto_version(ctx, min))
164 ossl_raise(eSSLError,
"SSL_CTX_set_min_proto_version");
165 if (!SSL_CTX_set_max_proto_version(ctx, max))
166 ossl_raise(eSSLError,
"SSL_CTX_set_max_proto_version");
169 unsigned long sum = 0, opts = 0;
171 static const struct {
175 { SSL2_VERSION, SSL_OP_NO_SSLv2 },
176 { SSL3_VERSION, SSL_OP_NO_SSLv3 },
177 { TLS1_VERSION, SSL_OP_NO_TLSv1 },
178 { TLS1_1_VERSION, SSL_OP_NO_TLSv1_1 },
179 { TLS1_2_VERSION, SSL_OP_NO_TLSv1_2 },
180 # if defined(TLS1_3_VERSION)
181 { TLS1_3_VERSION, SSL_OP_NO_TLSv1_3 },
186 sum |= options_map[
i].opts;
187 if ((min && min > options_map[
i].ver) ||
188 (max && max < options_map[
i].ver)) {
189 opts |= options_map[
i].opts;
192 SSL_CTX_clear_options(ctx, sum);
193 SSL_CTX_set_options(ctx, opts);
219 ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
223 obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
234 #if !defined(OPENSSL_NO_DH) || \
235 !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
256 if (EVP_PKEY_base_id(pkey) != args->
type)
263 #if !defined(OPENSSL_NO_DH)
265 ossl_tmp_dh_callback(SSL *ssl,
int is_export,
int keylength)
272 rb_ssl = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
274 args.id = id_tmp_dh_callback;
277 args.type = EVP_PKEY_DH;
280 (
VALUE)&args, &state);
288 return EVP_PKEY_get0_DH(pkey);
292 #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
301 rb_ssl = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
303 args.id = id_tmp_ecdh_callback;
306 args.type = EVP_PKEY_EC;
309 (
VALUE)&args, &state);
317 return EVP_PKEY_get0_EC_KEY(pkey);
322 call_verify_certificate_identity(
VALUE ctx_v)
324 X509_STORE_CTX *ctx = (X509_STORE_CTX *)ctx_v;
328 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
329 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
332 if (!
RTEST(hostname)) {
333 rb_warning(
"verify_hostname requires hostname to be set");
337 cert_obj =
ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx));
343 ossl_ssl_verify_callback(
int preverify_ok, X509_STORE_CTX *ctx)
349 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
350 cb = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx);
351 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
353 verify_hostname =
rb_attr_get(sslctx_obj, id_i_verify_hostname);
356 !X509_STORE_CTX_get_error_depth(ctx)) {
357 ret =
rb_protect(call_verify_certificate_identity, (
VALUE)ctx, &status);
362 preverify_ok = ret ==
Qtrue;
369 ossl_call_session_get_cb(
VALUE ary)
383 #if (!defined(LIBRESSL_VERSION_NUMBER) ? OPENSSL_VERSION_NUMBER >= 0x10100000 : LIBRESSL_VERSION_NUMBER >= 0x2080000f)
384 ossl_sslctx_session_get_cb(SSL *ssl,
const unsigned char *
buf,
int len,
int *copy)
386 ossl_sslctx_session_get_cb(SSL *ssl,
unsigned char *
buf,
int len,
int *copy)
393 OSSL_Debug(
"SSL SESSION get callback entered");
394 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
399 ret_obj =
rb_protect(ossl_call_session_get_cb, ary, &state);
414 ossl_call_session_new_cb(
VALUE ary)
429 ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
434 OSSL_Debug(
"SSL SESSION new callback entered");
436 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
445 rb_protect(ossl_call_session_new_cb, ary, &state);
461 ossl_call_session_remove_cb(
VALUE ary)
463 VALUE sslctx_obj, cb;
468 cb =
rb_attr_get(sslctx_obj, id_i_session_remove_cb);
475 ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
477 VALUE ary, sslctx_obj, sess_obj;
487 OSSL_Debug(
"SSL SESSION remove callback entered");
489 sslctx_obj = (
VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx);
498 rb_protect(ossl_call_session_remove_cb, ary, &state);
516 if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){
526 ossl_call_servername_cb(
VALUE ary)
542 ossl_sslctx_setup(ret_obj);
545 SSL_set_SSL_CTX(ssl, ctx2);
547 }
else if (!
NIL_P(ret_obj)) {
549 "OpenSSL::SSL::SSLContext object or nil");
556 ssl_servername_cb(SSL *ssl,
int *ad,
void *
arg)
560 const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
563 return SSL_TLSEXT_ERR_OK;
565 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
570 rb_protect(ossl_call_servername_cb, ary, &state);
573 return SSL_TLSEXT_ERR_ALERT_FATAL;
576 return SSL_TLSEXT_ERR_OK;
580 ssl_renegotiation_cb(
const SSL *ssl)
584 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
586 cb =
rb_attr_get(sslctx_obj, id_i_renegotiation_cb);
587 if (
NIL_P(cb))
return;
592 #if !defined(OPENSSL_NO_NEXTPROTONEG) || \
593 defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
599 if (len < 1 || len > 255)
600 ossl_raise(eSSLError,
"Advertised protocol must have length 1..255");
609 ssl_encode_npn_protocols(
VALUE protocols)
618 const unsigned char *
in;
623 npn_select_cb_common_i(
VALUE tmp)
626 const unsigned char *
in = args->
in, *in_end =
in + args->
inlen;
633 while (
in < in_end) {
642 if (len < 1 || len >= 256) {
643 ossl_raise(eSSLError,
"Selected protocol name must have length 1..255");
650 ssl_npn_select_cb_common(SSL *ssl,
VALUE cb,
const unsigned char **out,
651 unsigned char *outlen,
const unsigned char *
in,
664 VALUE ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
667 return SSL_TLSEXT_ERR_ALERT_FATAL;
673 return SSL_TLSEXT_ERR_OK;
677 #ifndef OPENSSL_NO_NEXTPROTONEG
679 ssl_npn_advertise_cb(SSL *ssl,
const unsigned char **out,
unsigned int *outlen,
684 *out = (
const unsigned char *)
RSTRING_PTR(protocols);
687 return SSL_TLSEXT_ERR_OK;
691 ssl_npn_select_cb(SSL *ssl,
unsigned char **out,
unsigned char *outlen,
692 const unsigned char *
in,
unsigned int inlen,
void *
arg)
699 return ssl_npn_select_cb_common(ssl,
cb, (
const unsigned char **)out,
704 #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
706 ssl_alpn_select_cb(SSL *ssl,
const unsigned char **out,
unsigned char *outlen,
707 const unsigned char *
in,
unsigned int inlen,
void *
arg)
714 return ssl_npn_select_cb_common(ssl,
cb, out, outlen,
in,
inlen);
720 ssl_info_cb(
const SSL *ssl,
int where,
int val)
724 if (is_server && where & SSL_CB_HANDSHAKE_START) {
725 ssl_renegotiation_cb(ssl);
733 ossl_sslctx_get_options(
VALUE self)
741 return ULONG2NUM((
unsigned long)SSL_CTX_get_options(ctx));
748 ossl_sslctx_set_options(
VALUE self,
VALUE options)
755 SSL_CTX_clear_options(ctx, SSL_CTX_get_options(ctx));
757 if (
NIL_P(options)) {
758 SSL_CTX_set_options(ctx, SSL_OP_ALL);
760 SSL_CTX_set_options(ctx,
NUM2ULONG(options));
776 ossl_sslctx_setup(
VALUE self)
779 X509 *cert =
NULL, *client_ca =
NULL;
781 char *ca_path =
NULL, *ca_file =
NULL;
789 #if !defined(OPENSSL_NO_DH)
790 SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
793 #if !defined(OPENSSL_NO_EC)
797 # if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
798 rb_warn(
"#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead");
799 SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
800 # if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
803 if (!SSL_CTX_set_ecdh_auto(ctx, 0))
804 ossl_raise(eSSLError,
"SSL_CTX_set_ecdh_auto");
807 ossl_raise(eSSLError,
"OpenSSL does not support tmp_ecdh_callback; "
808 "use #ecdh_curves= instead");
816 SSL_CTX_set_cert_store(ctx, store);
817 #if !defined(HAVE_X509_STORE_UP_REF)
824 SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
841 if (!SSL_CTX_use_certificate(ctx, cert)) {
843 ossl_raise(eSSLError,
"SSL_CTX_use_certificate");
845 if (!SSL_CTX_use_PrivateKey(ctx,
key)) {
847 ossl_raise(eSSLError,
"SSL_CTX_use_PrivateKey");
849 if (!SSL_CTX_check_private_key(ctx)) {
850 ossl_raise(eSSLError,
"SSL_CTX_check_private_key");
859 if (!SSL_CTX_add_client_CA(ctx, client_ca)){
861 ossl_raise(eSSLError,
"SSL_CTX_add_client_CA");
867 if (!SSL_CTX_add_client_CA(ctx, client_ca)){
869 ossl_raise(eSSLError,
"SSL_CTX_add_client_CA");
878 if(ca_file || ca_path){
879 if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
884 verify_mode =
NIL_P(val) ? SSL_VERIFY_NONE :
NUM2INT(val);
885 SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
887 SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);
893 if(!
NIL_P(val)) SSL_CTX_set_verify_depth(ctx,
NUM2INT(val));
895 #ifndef OPENSSL_NO_NEXTPROTONEG
898 VALUE encoded = ssl_encode_npn_protocols(val);
899 rb_ivar_set(
self, id_npn_protocols_encoded, encoded);
900 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (
void *)encoded);
901 OSSL_Debug(
"SSL NPN advertise callback added");
904 SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (
void *)
self);
909 #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
912 VALUE rprotos = ssl_encode_npn_protocols(val);
915 if (SSL_CTX_set_alpn_protos(ctx, (
unsigned char *)
RSTRING_PTR(rprotos),
917 ossl_raise(eSSLError,
"SSL_CTX_set_alpn_protos");
921 SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (
void *)
self);
931 if (!SSL_CTX_set_session_id_context(ctx, (
unsigned char *)
RSTRING_PTR(val),
933 ossl_raise(eSSLError,
"SSL_CTX_set_session_id_context");
938 SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
942 SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
946 SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
947 OSSL_Debug(
"SSL SESSION remove callback added");
952 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
953 OSSL_Debug(
"SSL TLSEXT servername callback added");
960 ossl_ssl_cipher_to_ary(
const SSL_CIPHER *cipher)
968 bits = SSL_CIPHER_get_bits(cipher, &alg_bits);
982 ossl_sslctx_get_ciphers(
VALUE self)
986 const SSL_CIPHER *cipher;
995 num = sk_SSL_CIPHER_num(ciphers);
997 for(
i = 0;
i < num;
i++){
998 cipher = sk_SSL_CIPHER_value(ciphers,
i);
1040 ossl_raise(eSSLError,
"SSL_CTX_set_cipher_list");
1046 #if !defined(OPENSSL_NO_EC)
1083 #if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
1090 VALUE curve, splitted;
1096 ossl_raise(eSSLError,
"invalid input format");
1102 if (
nid == NID_undef)
1104 if (
nid == NID_undef)
1107 ec = EC_KEY_new_by_curve_name(
nid);
1110 EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
1111 if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
1113 ossl_raise(eSSLError,
"SSL_CTX_set_tmp_ecdh");
1116 # if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
1119 if (!SSL_CTX_set_ecdh_auto(ctx, 0))
1120 ossl_raise(eSSLError,
"SSL_CTX_set_ecdh_auto");
1128 #define ossl_sslctx_set_ecdh_curves rb_f_notimplement
1140 ossl_sslctx_get_security_level(
VALUE self)
1146 #if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
1147 return INT2NUM(SSL_CTX_get_security_level(ctx));
1174 ossl_sslctx_set_security_level(
VALUE self,
VALUE value)
1181 #if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
1182 SSL_CTX_set_security_level(ctx,
NUM2INT(value));
1187 "not supported in this version of OpenSSL");
1193 #ifdef SSL_MODE_SEND_FALLBACK_SCSV
1202 ossl_sslctx_enable_fallback_scsv(
VALUE self)
1207 SSL_CTX_set_mode(ctx, SSL_MODE_SEND_FALLBACK_SCSV);
1259 EVP_PKEY *pkey, *pub_pkey;
1271 pub_pkey = X509_get_pubkey(x509);
1272 EVP_PKEY_free(pub_pkey);
1275 if (EVP_PKEY_cmp(pub_pkey, pkey) != 1)
1279 extra_chain = ossl_x509_ary2sk(extra_chain_ary);
1281 if (!SSL_CTX_use_certificate(ctx, x509)) {
1282 sk_X509_pop_free(extra_chain, X509_free);
1283 ossl_raise(eSSLError,
"SSL_CTX_use_certificate");
1285 if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
1286 sk_X509_pop_free(extra_chain, X509_free);
1287 ossl_raise(eSSLError,
"SSL_CTX_use_PrivateKey");
1291 #if OPENSSL_VERSION_NUMBER >= 0x10002000 && !defined(LIBRESSL_VERSION_NUMBER)
1292 if (!SSL_CTX_set0_chain(ctx, extra_chain)) {
1293 sk_X509_pop_free(extra_chain, X509_free);
1301 SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain);
1302 if (orig_extra_chain && sk_X509_num(orig_extra_chain)) {
1303 rb_warning(
"SSL_CTX_set0_chain() is not available; " \
1304 "clearing previously set certificate chain");
1305 SSL_CTX_clear_extra_chain_certs(ctx);
1307 while ((x509_tmp = sk_X509_shift(extra_chain))) {
1309 if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) {
1310 X509_free(x509_tmp);
1311 sk_X509_pop_free(extra_chain, X509_free);
1312 ossl_raise(eSSLError,
"SSL_CTX_add_extra_chain_cert");
1315 sk_X509_free(extra_chain);
1336 return SSL_CTX_add_session(ctx, sess) == 1 ?
Qtrue :
Qfalse;
1354 return SSL_CTX_remove_session(ctx, sess) == 1 ?
Qtrue :
Qfalse;
1364 ossl_sslctx_get_session_cache_mode(
VALUE self)
1370 return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx));
1388 SSL_CTX_set_session_cache_mode(ctx,
NUM2LONG(
arg));
1401 ossl_sslctx_get_session_cache_size(
VALUE self)
1407 return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx));
1452 ossl_sslctx_get_session_cache_stats(
VALUE self)
1502 SSL_CTX_flush_sessions(ctx, (
long)
tm);
1510 #ifndef OPENSSL_NO_SOCK
1512 ssl_started(SSL *ssl)
1515 return SSL_get_fd(ssl) >= 0;
1519 ossl_ssl_free(
void *ssl)
1557 VALUE io, v_ctx, verify_cb;
1563 ossl_raise(eSSLError,
"SSL already initialized");
1570 ossl_sslctx_setup(v_ctx);
1581 SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (
void *)
self);
1582 SSL_set_info_callback(ssl, ssl_info_cb);
1583 verify_cb =
rb_attr_get(v_ctx, id_i_verify_callback);
1584 SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (
void *)verify_cb);
1592 ossl_ssl_setup(
VALUE self)
1599 if (ssl_started(ssl))
1613 #define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret)))
1615 #define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret))
1619 write_would_block(
int nonblock)
1622 ossl_raise(eSSLErrorWaitWritable,
"write would block");
1626 read_would_block(
int nonblock)
1629 ossl_raise(eSSLErrorWaitReadable,
"read would block");
1642 ossl_start_ssl(
VALUE self,
int (*func)(),
const char *funcname,
VALUE opts)
1648 int nonblock = opts !=
Qfalse;
1649 #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1662 if (!
NIL_P(cb_state)) {
1672 case SSL_ERROR_WANT_WRITE:
1674 write_would_block(nonblock);
1677 case SSL_ERROR_WANT_READ:
1679 read_would_block(nonblock);
1682 case SSL_ERROR_SYSCALL:
1684 ossl_raise(eSSLError,
"%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2,
errno, SSL_state_string_long(ssl));
1685 #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1687 err = ERR_peek_last_error();
1688 if (ERR_GET_LIB(
err) == ERR_LIB_SSL &&
1689 ERR_GET_REASON(
err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
1690 const char *err_msg = ERR_reason_error_string(
err),
1691 *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
1695 verify_msg =
"(null)";
1697 ossl_raise(eSSLError,
"%s returned=%d errno=%d state=%s: %s (%s)",
1698 funcname, ret2,
errno, SSL_state_string_long(ssl),
1699 err_msg, verify_msg);
1703 ossl_raise(eSSLError,
"%s returned=%d errno=%d state=%s", funcname, ret2,
errno, SSL_state_string_long(ssl));
1718 ossl_ssl_connect(
VALUE self)
1720 ossl_ssl_setup(
self);
1722 return ossl_start_ssl(
self, SSL_connect,
"SSL_connect",
Qfalse);
1753 ossl_ssl_setup(
self);
1755 return ossl_start_ssl(
self, SSL_connect,
"SSL_connect", opts);
1766 ossl_ssl_accept(
VALUE self)
1768 ossl_ssl_setup(
self);
1770 return ossl_start_ssl(
self, SSL_accept,
"SSL_accept",
Qfalse);
1801 ossl_ssl_setup(
self);
1803 return ossl_start_ssl(
self, SSL_accept,
"SSL_accept", opts);
1810 int ilen, nread = 0;
1838 if (ssl_started(ssl)) {
1842 case SSL_ERROR_NONE:
1844 case SSL_ERROR_ZERO_RETURN:
1847 case SSL_ERROR_WANT_WRITE:
1849 write_would_block(nonblock);
1852 case SSL_ERROR_WANT_READ:
1854 read_would_block(nonblock);
1857 case SSL_ERROR_SYSCALL:
1858 if (!ERR_peek_error()) {
1882 rb_warning(
"SSL session is not started yet.");
1910 return ossl_ssl_read_internal(
argc,
argv,
self, 0);
1929 return ossl_ssl_read_internal(
argc,
argv,
self, 1);
1938 int nonblock = opts !=
Qfalse;
1945 if (ssl_started(ssl)) {
1955 case SSL_ERROR_NONE:
1957 case SSL_ERROR_WANT_WRITE:
1959 write_would_block(nonblock);
1962 case SSL_ERROR_WANT_READ:
1964 read_would_block(nonblock);
1967 case SSL_ERROR_SYSCALL:
1975 ID meth = nonblock ?
1978 rb_warning(
"SSL session is not started yet.");
2002 return ossl_ssl_write_internal(
self,
str,
Qfalse);
2019 return ossl_ssl_write_internal(
self,
str, opts);
2030 ossl_ssl_stop(
VALUE self)
2036 if (!ssl_started(ssl))
2038 ret = SSL_shutdown(ssl);
2061 ossl_ssl_get_cert(
VALUE self)
2072 cert = SSL_get_certificate(ssl);
2087 ossl_ssl_get_peer_cert(
VALUE self)
2095 cert = SSL_get_peer_certificate(ssl);
2113 ossl_ssl_get_peer_cert_chain(
VALUE self)
2123 chain = SSL_get_peer_cert_chain(ssl);
2124 if(!chain)
return Qnil;
2125 num = sk_X509_num(chain);
2127 for (
i = 0;
i < num;
i++){
2128 cert = sk_X509_value(chain,
i);
2143 ossl_ssl_get_version(
VALUE self)
2160 ossl_ssl_get_cipher(
VALUE self)
2163 const SSL_CIPHER *cipher;
2166 cipher = SSL_get_current_cipher(ssl);
2167 return cipher ? ossl_ssl_cipher_to_ary(cipher) :
Qnil;
2178 ossl_ssl_get_state(
VALUE self)
2200 ossl_ssl_pending(
VALUE self)
2206 return INT2NUM(SSL_pending(ssl));
2216 ossl_ssl_session_reused(
VALUE self)
2240 if (SSL_set_session(ssl, sess) != 1)
2257 char *hostname =
NULL;
2264 if (!SSL_set_tlsext_host_name(ssl, hostname))
2283 ossl_ssl_get_verify_result(
VALUE self)
2289 return INT2NUM(SSL_get_verify_result(ssl));
2304 ossl_ssl_get_client_ca_list(
VALUE self)
2311 ca = SSL_get_client_CA_list(ssl);
2315 # ifndef OPENSSL_NO_NEXTPROTONEG
2324 ossl_ssl_npn_protocol(
VALUE self)
2327 const unsigned char *out;
2328 unsigned int outlen;
2332 SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
2336 return rb_str_new((
const char *) out, outlen);
2340 # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2349 ossl_ssl_alpn_protocol(
VALUE self)
2352 const unsigned char *out;
2353 unsigned int outlen;
2357 SSL_get0_alpn_selected(ssl, &out, &outlen);
2361 return rb_str_new((
const char *) out, outlen);
2365 # ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2373 ossl_ssl_tmp_key(
VALUE self)
2379 if (!SSL_get_server_tmp_key(ssl, &
key))
2387 #define rb_intern(s) rb_intern_const(s)
2399 ID_callback_state =
rb_intern(
"callback_state");
2401 ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (
void *)
"ossl_ssl_ex_vcb_idx", 0, 0, 0);
2402 if (ossl_ssl_ex_vcb_idx < 0)
2404 ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0, (
void *)
"ossl_ssl_ex_ptr_idx", 0, 0, 0);
2405 if (ossl_ssl_ex_ptr_idx < 0)
2407 ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (
void *)
"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
2408 if (ossl_sslctx_ex_ptr_idx < 0)
2410 #if !defined(HAVE_X509_STORE_UP_REF)
2411 ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (
void *)
"ossl_sslctx_ex_store_p", 0, 0, 0);
2412 if (ossl_sslctx_ex_store_p < 0)
2562 #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
2635 #ifndef OPENSSL_NO_NEXTPROTONEG
2667 #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2702 ossl_sslctx_set_minmax_proto_version, 2);
2708 #ifdef SSL_MODE_SEND_FALLBACK_SCSV
2778 #ifdef OPENSSL_NO_SOCK
2809 # ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2812 # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2815 # ifndef OPENSSL_NO_NEXTPROTONEG
2827 #ifdef SSL_OP_TLSEXT_PADDING
2830 #ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG
2833 #ifdef SSL_OP_ALLOW_NO_DHE_KEX
2841 #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC
2846 #ifdef SSL_OP_NO_RENEGOTIATION
2855 #ifdef SSL_OP_NO_TLSv1_3
2916 #ifdef TLS1_3_VERSION
2926 id_tmp_dh_callback =
rb_intern(
"tmp_dh_callback");
2927 id_tmp_ecdh_callback =
rb_intern(
"tmp_ecdh_callback");
2928 id_npn_protocols_encoded =
rb_intern(
"npn_protocols_encoded");
2930 #define DefIVarID(name) do \
2931 id_i_##name = rb_intern("@"#name); while (0)