14#define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
16#if !defined(TLS1_3_VERSION) && \
17 defined(LIBRESSL_VERSION_NUMBER) && \
18 LIBRESSL_VERSION_NUMBER >= 0x3020000fL
19# define TLS1_3_VERSION 0x0304
23# define TO_SOCKET(s) _get_osfhandle(s)
25# define TO_SOCKET(s) (s)
28#define GetSSLCTX(obj, ctx) do { \
29 TypedData_Get_Struct((obj), SSL_CTX, &ossl_sslctx_type, (ctx)); \
33static VALUE mSSLExtConfig;
34static VALUE eSSLError;
38static VALUE eSSLErrorWaitReadable;
39static VALUE eSSLErrorWaitWritable;
41static ID id_call, ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
42 id_npn_protocols_encoded,
id_each;
43static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
45static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
46 id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
47 id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
48 id_i_client_cert_cb, id_i_tmp_ecdh_callback, id_i_timeout,
49 id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
50 id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
51 id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
53static ID id_i_io, id_i_context, id_i_hostname;
55static int ossl_ssl_ex_vcb_idx;
56static int ossl_ssl_ex_ptr_idx;
57static int ossl_sslctx_ex_ptr_idx;
58#if !defined(HAVE_X509_STORE_UP_REF)
59static int ossl_sslctx_ex_store_p;
63ossl_sslctx_mark(
void *
ptr)
70ossl_sslctx_free(
void *
ptr)
73#if !defined(HAVE_X509_STORE_UP_REF)
74 if (ctx && SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_store_p))
75 ctx->cert_store =
NULL;
83 ossl_sslctx_mark, ossl_sslctx_free,
93 SSL_MODE_ENABLE_PARTIAL_WRITE |
94 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
95 SSL_MODE_RELEASE_BUFFERS;
99#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
100 ctx = SSL_CTX_new(TLS_method());
102 ctx = SSL_CTX_new(SSLv23_method());
107 SSL_CTX_set_mode(ctx, mode);
109 SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (
void *)
obj);
111#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
119 if (!SSL_CTX_set_ecdh_auto(ctx, 1))
120 ossl_raise(eSSLError,
"SSL_CTX_set_ecdh_auto");
130 static const struct {
134 {
"SSL2", SSL2_VERSION },
135 {
"SSL3", SSL3_VERSION },
136 {
"TLS1", TLS1_VERSION },
137 {
"TLS1_1", TLS1_1_VERSION },
138 {
"TLS1_2", TLS1_2_VERSION },
140 {
"TLS1_3", TLS1_3_VERSION },
154 return map[
i].version;
166ossl_sslctx_set_minmax_proto_version(
VALUE self,
VALUE min_v,
VALUE max_v)
172 min = parse_proto_version(min_v);
173 max = parse_proto_version(max_v);
175#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
176 if (!SSL_CTX_set_min_proto_version(ctx, min))
177 ossl_raise(eSSLError,
"SSL_CTX_set_min_proto_version");
178 if (!SSL_CTX_set_max_proto_version(ctx, max))
179 ossl_raise(eSSLError,
"SSL_CTX_set_max_proto_version");
182 unsigned long sum = 0, opts = 0;
184 static const struct {
188 { SSL2_VERSION, SSL_OP_NO_SSLv2 },
189 { SSL3_VERSION, SSL_OP_NO_SSLv3 },
190 { TLS1_VERSION, SSL_OP_NO_TLSv1 },
191 { TLS1_1_VERSION, SSL_OP_NO_TLSv1_1 },
192 { TLS1_2_VERSION, SSL_OP_NO_TLSv1_2 },
193# if defined(TLS1_3_VERSION)
194 { TLS1_3_VERSION, SSL_OP_NO_TLSv1_3 },
199 sum |= options_map[
i].opts;
200 if ((min && min > options_map[
i].ver) ||
201 (max && max < options_map[
i].ver)) {
202 opts |= options_map[
i].opts;
205 SSL_CTX_clear_options(ctx, sum);
206 SSL_CTX_set_options(ctx, opts);
232ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
236 obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
247#if !defined(OPENSSL_NO_DH) || \
248 !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
269 if (EVP_PKEY_base_id(pkey) != args->
type)
276#if !defined(OPENSSL_NO_DH)
278ossl_tmp_dh_callback(SSL *ssl,
int is_export,
int keylength)
285 rb_ssl = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
287 args.id = id_tmp_dh_callback;
290 args.type = EVP_PKEY_DH;
293 (
VALUE)&args, &state);
301 return EVP_PKEY_get0_DH(pkey);
305#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
314 rb_ssl = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
316 args.id = id_tmp_ecdh_callback;
319 args.type = EVP_PKEY_EC;
322 (
VALUE)&args, &state);
330 return EVP_PKEY_get0_EC_KEY(pkey);
335call_verify_certificate_identity(
VALUE ctx_v)
337 X509_STORE_CTX *ctx = (X509_STORE_CTX *)ctx_v;
341 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
342 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
345 if (!
RTEST(hostname)) {
346 rb_warning(
"verify_hostname requires hostname to be set");
350 cert_obj =
ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx));
356ossl_ssl_verify_callback(
int preverify_ok, X509_STORE_CTX *ctx)
362 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
363 cb = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx);
364 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
366 verify_hostname =
rb_attr_get(sslctx_obj, id_i_verify_hostname);
369 !X509_STORE_CTX_get_error_depth(ctx)) {
370 ret =
rb_protect(call_verify_certificate_identity, (
VALUE)ctx, &status);
377#if defined(X509_V_ERR_HOSTNAME_MISMATCH)
378 X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH);
380 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
389ossl_call_session_get_cb(
VALUE ary)
403#if (!defined(LIBRESSL_VERSION_NUMBER) ? OPENSSL_VERSION_NUMBER >= 0x10100000 : LIBRESSL_VERSION_NUMBER >= 0x2080000f)
404ossl_sslctx_session_get_cb(SSL *ssl,
const unsigned char *
buf,
int len,
int *copy)
406ossl_sslctx_session_get_cb(SSL *ssl,
unsigned char *
buf,
int len,
int *copy)
413 OSSL_Debug(
"SSL SESSION get callback entered");
414 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
419 ret_obj =
rb_protect(ossl_call_session_get_cb, ary, &state);
434ossl_call_session_new_cb(
VALUE ary)
449ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
454 OSSL_Debug(
"SSL SESSION new callback entered");
456 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
465 rb_protect(ossl_call_session_new_cb, ary, &state);
481ossl_call_session_remove_cb(
VALUE ary)
483 VALUE sslctx_obj, cb;
488 cb =
rb_attr_get(sslctx_obj, id_i_session_remove_cb);
495ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
497 VALUE ary, sslctx_obj, sess_obj;
507 OSSL_Debug(
"SSL SESSION remove callback entered");
509 sslctx_obj = (
VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx);
518 rb_protect(ossl_call_session_remove_cb, ary, &state);
536 if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){
546ossl_call_servername_cb(
VALUE ary)
562 ossl_sslctx_setup(ret_obj);
565 SSL_set_SSL_CTX(ssl, ctx2);
567 }
else if (!
NIL_P(ret_obj)) {
569 "OpenSSL::SSL::SSLContext object or nil");
576ssl_servername_cb(SSL *ssl,
int *ad,
void *
arg)
580 const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
583 return SSL_TLSEXT_ERR_OK;
585 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
590 rb_protect(ossl_call_servername_cb, ary, &state);
593 return SSL_TLSEXT_ERR_ALERT_FATAL;
596 return SSL_TLSEXT_ERR_OK;
600ssl_renegotiation_cb(
const SSL *ssl)
604 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
606 cb =
rb_attr_get(sslctx_obj, id_i_renegotiation_cb);
607 if (
NIL_P(cb))
return;
612#if !defined(OPENSSL_NO_NEXTPROTONEG) || \
613 defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
619 if (len < 1 || len > 255)
620 ossl_raise(eSSLError,
"Advertised protocol must have length 1..255");
629ssl_encode_npn_protocols(
VALUE protocols)
632 rb_block_call(protocols, id_each, 0, 0, ssl_npn_encode_protocol_i, encoded);
638 const unsigned char *
in;
643npn_select_cb_common_i(
VALUE tmp)
646 const unsigned char *
in = args->
in, *in_end =
in + args->
inlen;
653 while (
in < in_end) {
662 if (len < 1 || len >= 256) {
663 ossl_raise(eSSLError,
"Selected protocol name must have length 1..255");
670ssl_npn_select_cb_common(SSL *ssl,
VALUE cb,
const unsigned char **out,
671 unsigned char *outlen,
const unsigned char *
in,
684 VALUE ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
687 return SSL_TLSEXT_ERR_ALERT_FATAL;
693 return SSL_TLSEXT_ERR_OK;
697#ifndef OPENSSL_NO_NEXTPROTONEG
699ssl_npn_advertise_cb(SSL *ssl,
const unsigned char **out,
unsigned int *outlen,
704 *out = (
const unsigned char *)
RSTRING_PTR(protocols);
707 return SSL_TLSEXT_ERR_OK;
711ssl_npn_select_cb(SSL *ssl,
unsigned char **out,
unsigned char *outlen,
712 const unsigned char *
in,
unsigned int inlen,
void *
arg)
719 return ssl_npn_select_cb_common(ssl,
cb, (
const unsigned char **)out,
724#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
726ssl_alpn_select_cb(SSL *ssl,
const unsigned char **out,
unsigned char *outlen,
727 const unsigned char *
in,
unsigned int inlen,
void *
arg)
734 return ssl_npn_select_cb_common(ssl,
cb, out, outlen,
in,
inlen);
740ssl_info_cb(
const SSL *ssl,
int where,
int val)
744 if (is_server && where & SSL_CB_HANDSHAKE_START) {
745 ssl_renegotiation_cb(ssl);
753ossl_sslctx_get_options(
VALUE self)
761 return ULONG2NUM((
unsigned long)SSL_CTX_get_options(ctx));
768ossl_sslctx_set_options(
VALUE self,
VALUE options)
775 SSL_CTX_clear_options(ctx, SSL_CTX_get_options(ctx));
777 if (
NIL_P(options)) {
778 SSL_CTX_set_options(ctx, SSL_OP_ALL);
780 SSL_CTX_set_options(ctx,
NUM2ULONG(options));
796ossl_sslctx_setup(
VALUE self)
799 X509 *cert =
NULL, *client_ca =
NULL;
801 char *ca_path =
NULL, *ca_file =
NULL;
809#if !defined(OPENSSL_NO_DH)
810 SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
813#if !defined(OPENSSL_NO_EC)
817# if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
818 rb_warn(
"#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead");
819 SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
820# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
823 if (!SSL_CTX_set_ecdh_auto(ctx, 0))
824 ossl_raise(eSSLError,
"SSL_CTX_set_ecdh_auto");
827 ossl_raise(eSSLError,
"OpenSSL does not support tmp_ecdh_callback; "
828 "use #ecdh_curves= instead");
836 SSL_CTX_set_cert_store(ctx, store);
837#if !defined(HAVE_X509_STORE_UP_REF)
844 SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
861 if (!SSL_CTX_use_certificate(ctx, cert)) {
863 ossl_raise(eSSLError,
"SSL_CTX_use_certificate");
865 if (!SSL_CTX_use_PrivateKey(ctx,
key)) {
867 ossl_raise(eSSLError,
"SSL_CTX_use_PrivateKey");
869 if (!SSL_CTX_check_private_key(ctx)) {
870 ossl_raise(eSSLError,
"SSL_CTX_check_private_key");
879 if (!SSL_CTX_add_client_CA(ctx, client_ca)){
881 ossl_raise(eSSLError,
"SSL_CTX_add_client_CA");
887 if (!SSL_CTX_add_client_CA(ctx, client_ca)){
889 ossl_raise(eSSLError,
"SSL_CTX_add_client_CA");
898 if(ca_file || ca_path){
899 if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
904 verify_mode =
NIL_P(val) ? SSL_VERIFY_NONE :
NUM2INT(val);
905 SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
907 SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);
913 if(!
NIL_P(val)) SSL_CTX_set_verify_depth(ctx,
NUM2INT(val));
915#ifndef OPENSSL_NO_NEXTPROTONEG
918 VALUE encoded = ssl_encode_npn_protocols(val);
919 rb_ivar_set(
self, id_npn_protocols_encoded, encoded);
920 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (
void *)
self);
921 OSSL_Debug(
"SSL NPN advertise callback added");
924 SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (
void *)
self);
929#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
932 VALUE rprotos = ssl_encode_npn_protocols(val);
935 if (SSL_CTX_set_alpn_protos(ctx, (
unsigned char *)
RSTRING_PTR(rprotos),
937 ossl_raise(eSSLError,
"SSL_CTX_set_alpn_protos");
941 SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (
void *)
self);
951 if (!SSL_CTX_set_session_id_context(ctx, (
unsigned char *)
RSTRING_PTR(val),
953 ossl_raise(eSSLError,
"SSL_CTX_set_session_id_context");
958 SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
962 SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
966 SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
967 OSSL_Debug(
"SSL SESSION remove callback added");
972 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
973 OSSL_Debug(
"SSL TLSEXT servername callback added");
980ossl_ssl_cipher_to_ary(
const SSL_CIPHER *cipher)
988 bits = SSL_CIPHER_get_bits(cipher, &alg_bits);
1002ossl_sslctx_get_ciphers(
VALUE self)
1006 const SSL_CIPHER *cipher;
1015 num = sk_SSL_CIPHER_num(ciphers);
1017 for(
i = 0;
i < num;
i++){
1018 cipher = sk_SSL_CIPHER_value(ciphers,
i);
1060 ossl_raise(eSSLError,
"SSL_CTX_set_cipher_list");
1066#if !defined(OPENSSL_NO_EC)
1103#if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
1110 VALUE curve, splitted;
1116 ossl_raise(eSSLError,
"invalid input format");
1122 if (
nid == NID_undef)
1124 if (
nid == NID_undef)
1127 ec = EC_KEY_new_by_curve_name(
nid);
1130 EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
1131 if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
1133 ossl_raise(eSSLError,
"SSL_CTX_set_tmp_ecdh");
1136# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
1139 if (!SSL_CTX_set_ecdh_auto(ctx, 0))
1140 ossl_raise(eSSLError,
"SSL_CTX_set_ecdh_auto");
1148#define ossl_sslctx_set_ecdh_curves rb_f_notimplement
1160ossl_sslctx_get_security_level(
VALUE self)
1166#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
1167 return INT2NUM(SSL_CTX_get_security_level(ctx));
1194ossl_sslctx_set_security_level(
VALUE self,
VALUE value)
1201#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
1202 SSL_CTX_set_security_level(ctx,
NUM2INT(value));
1207 "not supported in this version of OpenSSL");
1213#ifdef SSL_MODE_SEND_FALLBACK_SCSV
1222ossl_sslctx_enable_fallback_scsv(
VALUE self)
1227 SSL_CTX_set_mode(ctx, SSL_MODE_SEND_FALLBACK_SCSV);
1279 EVP_PKEY *pkey, *pub_pkey;
1291 pub_pkey = X509_get_pubkey(x509);
1292 EVP_PKEY_free(pub_pkey);
1295 if (EVP_PKEY_cmp(pub_pkey, pkey) != 1)
1299 extra_chain = ossl_x509_ary2sk(extra_chain_ary);
1301 if (!SSL_CTX_use_certificate(ctx, x509)) {
1302 sk_X509_pop_free(extra_chain, X509_free);
1303 ossl_raise(eSSLError,
"SSL_CTX_use_certificate");
1305 if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
1306 sk_X509_pop_free(extra_chain, X509_free);
1307 ossl_raise(eSSLError,
"SSL_CTX_use_PrivateKey");
1311#if OPENSSL_VERSION_NUMBER >= 0x10002000 && !defined(LIBRESSL_VERSION_NUMBER)
1312 if (!SSL_CTX_set0_chain(ctx, extra_chain)) {
1313 sk_X509_pop_free(extra_chain, X509_free);
1321 SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain);
1322 if (orig_extra_chain && sk_X509_num(orig_extra_chain)) {
1323 rb_warning(
"SSL_CTX_set0_chain() is not available; " \
1324 "clearing previously set certificate chain");
1325 SSL_CTX_clear_extra_chain_certs(ctx);
1327 while ((x509_tmp = sk_X509_shift(extra_chain))) {
1329 if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) {
1330 X509_free(x509_tmp);
1331 sk_X509_pop_free(extra_chain, X509_free);
1332 ossl_raise(eSSLError,
"SSL_CTX_add_extra_chain_cert");
1335 sk_X509_free(extra_chain);
1356 return SSL_CTX_add_session(ctx, sess) == 1 ?
Qtrue :
Qfalse;
1374 return SSL_CTX_remove_session(ctx, sess) == 1 ?
Qtrue :
Qfalse;
1384ossl_sslctx_get_session_cache_mode(
VALUE self)
1390 return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx));
1408 SSL_CTX_set_session_cache_mode(ctx,
NUM2LONG(
arg));
1421ossl_sslctx_get_session_cache_size(
VALUE self)
1427 return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx));
1472ossl_sslctx_get_session_cache_stats(
VALUE self)
1522 SSL_CTX_flush_sessions(ctx, (
long)
tm);
1530#ifndef OPENSSL_NO_SOCK
1532ssl_started(SSL *ssl)
1535 return SSL_get_fd(ssl) >= 0;
1539ossl_ssl_mark(
void *
ptr)
1547ossl_ssl_free(
void *ssl)
1555 ossl_ssl_mark, ossl_ssl_free,
1585 VALUE io, v_ctx, verify_cb;
1591 ossl_raise(eSSLError,
"SSL already initialized");
1598 ossl_sslctx_setup(v_ctx);
1609 SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (
void *)
self);
1610 SSL_set_info_callback(ssl, ssl_info_cb);
1611 verify_cb =
rb_attr_get(v_ctx, id_i_verify_callback);
1612 SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (
void *)verify_cb);
1620ossl_ssl_setup(
VALUE self)
1627 if (ssl_started(ssl))
1641#define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret)))
1643#define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret))
1647write_would_block(
int nonblock)
1650 ossl_raise(eSSLErrorWaitWritable,
"write would block");
1654read_would_block(
int nonblock)
1657 ossl_raise(eSSLErrorWaitReadable,
"read would block");
1670ossl_start_ssl(
VALUE self,
int (*func)(),
const char *funcname,
VALUE opts)
1676 int nonblock = opts !=
Qfalse;
1677#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1690 if (!
NIL_P(cb_state)) {
1700 case SSL_ERROR_WANT_WRITE:
1702 write_would_block(nonblock);
1705 case SSL_ERROR_WANT_READ:
1707 read_would_block(nonblock);
1710 case SSL_ERROR_SYSCALL:
1717 ossl_raise(eSSLError,
"%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2,
errno, SSL_state_string_long(ssl));
1718#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1720 err = ERR_peek_last_error();
1721 if (ERR_GET_LIB(
err) == ERR_LIB_SSL &&
1722 ERR_GET_REASON(
err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
1723 const char *err_msg = ERR_reason_error_string(
err),
1724 *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
1728 verify_msg =
"(null)";
1730 ossl_raise(eSSLError,
"%s returned=%d errno=%d state=%s: %s (%s)",
1731 funcname, ret2,
errno, SSL_state_string_long(ssl),
1732 err_msg, verify_msg);
1736 ossl_raise(eSSLError,
"%s returned=%d errno=%d state=%s", funcname, ret2,
errno, SSL_state_string_long(ssl));
1751ossl_ssl_connect(
VALUE self)
1753 ossl_ssl_setup(
self);
1755 return ossl_start_ssl(
self, SSL_connect,
"SSL_connect",
Qfalse);
1786 ossl_ssl_setup(
self);
1788 return ossl_start_ssl(
self, SSL_connect,
"SSL_connect", opts);
1799ossl_ssl_accept(
VALUE self)
1801 ossl_ssl_setup(
self);
1803 return ossl_start_ssl(
self, SSL_accept,
"SSL_accept",
Qfalse);
1834 ossl_ssl_setup(
self);
1836 return ossl_start_ssl(
self, SSL_accept,
"SSL_accept", opts);
1843 int ilen, nread = 0;
1871 if (ssl_started(ssl)) {
1876 case SSL_ERROR_NONE:
1879 case SSL_ERROR_ZERO_RETURN:
1883 case SSL_ERROR_WANT_WRITE:
1887 write_would_block(nonblock);
1891 case SSL_ERROR_WANT_READ:
1895 read_would_block(nonblock);
1899 case SSL_ERROR_SYSCALL:
1900 if (!ERR_peek_error()) {
1926 rb_warning(
"SSL session is not started yet.");
1927#if defined(RB_PASS_KEYWORDS)
1960 return ossl_ssl_read_internal(
argc,
argv,
self, 0);
1979 return ossl_ssl_read_internal(
argc,
argv,
self, 1);
1988 int nonblock = opts !=
Qfalse;
1995 if (ssl_started(ssl)) {
2005 case SSL_ERROR_NONE:
2007 case SSL_ERROR_WANT_WRITE:
2009 write_would_block(nonblock);
2012 case SSL_ERROR_WANT_READ:
2014 read_would_block(nonblock);
2017 case SSL_ERROR_SYSCALL:
2035 ID meth = nonblock ?
2038 rb_warning(
"SSL session is not started yet.");
2039#if defined(RB_PASS_KEYWORDS)
2068 return ossl_ssl_write_internal(
self,
str,
Qfalse);
2085 return ossl_ssl_write_internal(
self,
str, opts);
2096ossl_ssl_stop(
VALUE self)
2102 if (!ssl_started(ssl))
2104 ret = SSL_shutdown(ssl);
2127ossl_ssl_get_cert(
VALUE self)
2138 cert = SSL_get_certificate(ssl);
2153ossl_ssl_get_peer_cert(
VALUE self)
2161 cert = SSL_get_peer_certificate(ssl);
2179ossl_ssl_get_peer_cert_chain(
VALUE self)
2189 chain = SSL_get_peer_cert_chain(ssl);
2190 if(!chain)
return Qnil;
2191 num = sk_X509_num(chain);
2193 for (
i = 0;
i < num;
i++){
2194 cert = sk_X509_value(chain,
i);
2209ossl_ssl_get_version(
VALUE self)
2226ossl_ssl_get_cipher(
VALUE self)
2229 const SSL_CIPHER *cipher;
2232 cipher = SSL_get_current_cipher(ssl);
2233 return cipher ? ossl_ssl_cipher_to_ary(cipher) :
Qnil;
2244ossl_ssl_get_state(
VALUE self)
2266ossl_ssl_pending(
VALUE self)
2272 return INT2NUM(SSL_pending(ssl));
2282ossl_ssl_session_reused(
VALUE self)
2306 if (SSL_set_session(ssl, sess) != 1)
2323 char *hostname =
NULL;
2330 if (!SSL_set_tlsext_host_name(ssl, hostname))
2349ossl_ssl_get_verify_result(
VALUE self)
2355 return INT2NUM(SSL_get_verify_result(ssl));
2370ossl_ssl_get_client_ca_list(
VALUE self)
2377 ca = SSL_get_client_CA_list(ssl);
2381# ifndef OPENSSL_NO_NEXTPROTONEG
2390ossl_ssl_npn_protocol(
VALUE self)
2393 const unsigned char *out;
2394 unsigned int outlen;
2398 SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
2402 return rb_str_new((
const char *) out, outlen);
2406# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2415ossl_ssl_alpn_protocol(
VALUE self)
2418 const unsigned char *out;
2419 unsigned int outlen;
2423 SSL_get0_alpn_selected(ssl, &out, &outlen);
2427 return rb_str_new((
const char *) out, outlen);
2431# ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2439ossl_ssl_tmp_key(
VALUE self)
2445 if (!SSL_get_server_tmp_key(ssl, &
key))
2453#define rb_intern(s) rb_intern_const(s)
2465 ID_callback_state =
rb_intern(
"callback_state");
2467 ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (
void *)
"ossl_ssl_ex_vcb_idx", 0, 0, 0);
2468 if (ossl_ssl_ex_vcb_idx < 0)
2470 ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0, (
void *)
"ossl_ssl_ex_ptr_idx", 0, 0, 0);
2471 if (ossl_ssl_ex_ptr_idx < 0)
2473 ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (
void *)
"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
2474 if (ossl_sslctx_ex_ptr_idx < 0)
2476#if !defined(HAVE_X509_STORE_UP_REF)
2477 ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (
void *)
"ossl_sslctx_ex_store_p", 0, 0, 0);
2478 if (ossl_sslctx_ex_store_p < 0)
2628#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
2701#ifndef OPENSSL_NO_NEXTPROTONEG
2733#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2768 ossl_sslctx_set_minmax_proto_version, 2);
2774#ifdef SSL_MODE_SEND_FALLBACK_SCSV
2844#ifdef OPENSSL_NO_SOCK
2875# ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2878# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2881# ifndef OPENSSL_NO_NEXTPROTONEG
2893#ifdef SSL_OP_TLSEXT_PADDING
2896#ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG
2899#ifdef SSL_OP_ALLOW_NO_DHE_KEX
2907#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC
2912#ifdef SSL_OP_NO_RENEGOTIATION
2921#ifdef SSL_OP_NO_TLSv1_3
2982#ifdef TLS1_3_VERSION
2992 id_tmp_dh_callback =
rb_intern(
"tmp_dh_callback");
2993 id_tmp_ecdh_callback =
rb_intern(
"tmp_ecdh_callback");
2994 id_npn_protocols_encoded =
rb_intern(
"npn_protocols_encoded");
2997#define DefIVarID(name) do \
2998 id_i_##name = rb_intern("@"#name); while (0)
char str[HTML_ESCAPE_MAX_LEN+1]
void rb_include_module(VALUE, VALUE)
VALUE rb_define_class_under(VALUE, const char *, VALUE)
Defines a class under the namespace of outer.
VALUE rb_define_module(const char *)
VALUE rb_define_module_under(VALUE, const char *)
void rb_undef_method(VALUE, const char *)
void rb_define_alias(VALUE, const char *, const char *)
Defines an alias of a method.
VALUE rb_cObject
Object class.
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_protect(VALUE(*)(VALUE), VALUE, int *)
Protects a function call from potential global escapes from the function.
void rb_warn(const char *fmt,...)
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
void rb_sys_fail(const char *mesg)
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
VALUE rb_obj_is_instance_of(VALUE, VALUE)
Determines if obj is an instance of c.
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
VALUE rb_String(VALUE)
Equivalent to Kernel#String in Ruby.
#define no_exception_p(opts)
void rb_io_check_writable(rb_io_t *)
void rb_io_check_readable(rb_io_t *)
#define GetOpenFile(obj, fp)
int rb_io_wait_readable(int)
int rb_io_wait_writable(int)
unsigned char buf[MIME_BUF_SIZE]
#define SSL_SESSION_up_ref(x)
#define EC_curve_nist2nid
#define X509_STORE_up_ref(x)
#define SSL_CTX_get_ciphers(ctx)
void ossl_raise(VALUE exc, const char *fmt,...)
void ossl_clear_error(void)
VALUE ossl_x509name_sk2ary(const STACK_OF(X509_NAME) *names)
STACK_OF(X509) *ossl_x509_ary2sk(VALUE)
EVP_PKEY * GetPrivPKeyPtr(VALUE obj)
EVP_PKEY * DupPKeyPtr(VALUE obj)
EVP_PKEY * GetPKeyPtr(VALUE obj)
VALUE ossl_pkey_new(EVP_PKEY *pkey)
#define ssl_get_error(ssl, ret)
const rb_data_type_t ossl_ssl_type
#define GetSSLCTX(obj, ctx)
void Init_ossl_ssl_session(void)
#define GetSSLSession(obj, sess)
VALUE ossl_x509_new(X509 *)
X509_STORE * GetX509StorePtr(VALUE)
int ossl_verify_cb_call(VALUE, int, X509_STORE_CTX *)
X509 * DupX509CertPtr(VALUE)
X509 * GetX509CertPtr(VALUE)
VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj, VALUE marker)