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,
89ossl_sslctx_s_alloc(
VALUE klass)
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 },
198 for (i = 0; i <
numberof(options_map); i++) {
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);
214ossl_call_client_cert_cb(
VALUE obj)
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);
286 args.ssl_obj = rb_ssl;
287 args.id = id_tmp_dh_callback;
290 args.type = EVP_PKEY_DH;
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);
315 args.ssl_obj = rb_ssl;
316 args.id = id_tmp_ecdh_callback;
319 args.type = EVP_PKEY_EC;
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);
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);
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);
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);
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)
617 int len = RSTRING_LENINT(cur);
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,
705 *outlen = RSTRING_LENINT(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)
716 sslctx_obj = (
VALUE) 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)
731 sslctx_obj = (
VALUE) 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");
833#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
834 SSL_CTX_set_post_handshake_auth(ctx, 1);
840 SSL_CTX_set_cert_store(ctx, store);
841#if !defined(HAVE_X509_STORE_UP_REF)
848 SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
865 if (!SSL_CTX_use_certificate(ctx, cert)) {
867 ossl_raise(eSSLError,
"SSL_CTX_use_certificate");
869 if (!SSL_CTX_use_PrivateKey(ctx,
key)) {
871 ossl_raise(eSSLError,
"SSL_CTX_use_PrivateKey");
873 if (!SSL_CTX_check_private_key(ctx)) {
874 ossl_raise(eSSLError,
"SSL_CTX_check_private_key");
883 if (!SSL_CTX_add_client_CA(ctx, client_ca)){
885 ossl_raise(eSSLError,
"SSL_CTX_add_client_CA");
891 if (!SSL_CTX_add_client_CA(ctx, client_ca)){
893 ossl_raise(eSSLError,
"SSL_CTX_add_client_CA");
902 if(ca_file || ca_path){
903 if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
908 verify_mode =
NIL_P(val) ? SSL_VERIFY_NONE :
NUM2INT(val);
909 SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
911 SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);
917 if(!
NIL_P(val)) SSL_CTX_set_verify_depth(ctx,
NUM2INT(val));
919#ifndef OPENSSL_NO_NEXTPROTONEG
922 VALUE encoded = ssl_encode_npn_protocols(val);
923 rb_ivar_set(self, id_npn_protocols_encoded, encoded);
924 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (
void *)self);
925 OSSL_Debug(
"SSL NPN advertise callback added");
928 SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (
void *) self);
933#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
936 VALUE rprotos = ssl_encode_npn_protocols(val);
939 if (SSL_CTX_set_alpn_protos(ctx, (
unsigned char *)
RSTRING_PTR(rprotos),
940 RSTRING_LENINT(rprotos)))
941 ossl_raise(eSSLError,
"SSL_CTX_set_alpn_protos");
945 SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (
void *) self);
955 if (!SSL_CTX_set_session_id_context(ctx, (
unsigned char *)
RSTRING_PTR(val),
956 RSTRING_LENINT(val))){
957 ossl_raise(eSSLError,
"SSL_CTX_set_session_id_context");
962 SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
966 SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
970 SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
971 OSSL_Debug(
"SSL SESSION remove callback added");
976 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
977 OSSL_Debug(
"SSL TLSEXT servername callback added");
984ossl_ssl_cipher_to_ary(
const SSL_CIPHER *cipher)
992 bits = SSL_CIPHER_get_bits(cipher, &alg_bits);
1006ossl_sslctx_get_ciphers(
VALUE self)
1010 const SSL_CIPHER *cipher;
1019 num = sk_SSL_CIPHER_num(ciphers);
1021 for(i = 0; i <
num; i++){
1022 cipher = sk_SSL_CIPHER_value(ciphers, i);
1048 else if (RB_TYPE_P(v,
T_ARRAY)) {
1064 ossl_raise(eSSLError,
"SSL_CTX_set_cipher_list");
1070#if !defined(OPENSSL_NO_EC)
1099ossl_sslctx_set_ecdh_curves(
VALUE self,
VALUE arg)
1107#if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
1108 if (!SSL_CTX_set1_curves_list(ctx,
RSTRING_PTR(arg)))
1114 VALUE curve, splitted;
1120 ossl_raise(eSSLError,
"invalid input format");
1126 if (
nid == NID_undef)
1128 if (
nid == NID_undef)
1131 ec = EC_KEY_new_by_curve_name(
nid);
1134 EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
1135 if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
1137 ossl_raise(eSSLError,
"SSL_CTX_set_tmp_ecdh");
1140# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
1143 if (!SSL_CTX_set_ecdh_auto(ctx, 0))
1144 ossl_raise(eSSLError,
"SSL_CTX_set_ecdh_auto");
1152#define ossl_sslctx_set_ecdh_curves rb_f_notimplement
1164ossl_sslctx_get_security_level(
VALUE self)
1170#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
1171 return INT2NUM(SSL_CTX_get_security_level(ctx));
1198ossl_sslctx_set_security_level(
VALUE self,
VALUE value)
1205#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
1206 SSL_CTX_set_security_level(ctx,
NUM2INT(value));
1211 "not supported in this version of OpenSSL");
1217#ifdef SSL_MODE_SEND_FALLBACK_SCSV
1226ossl_sslctx_enable_fallback_scsv(
VALUE self)
1231 SSL_CTX_set_mode(ctx, SSL_MODE_SEND_FALLBACK_SCSV);
1283 EVP_PKEY *pkey, *pub_pkey;
1295 pub_pkey = X509_get_pubkey(x509);
1296 EVP_PKEY_free(pub_pkey);
1299 if (EVP_PKEY_cmp(pub_pkey, pkey) != 1)
1303 extra_chain = ossl_x509_ary2sk(extra_chain_ary);
1305 if (!SSL_CTX_use_certificate(ctx, x509)) {
1306 sk_X509_pop_free(extra_chain, X509_free);
1307 ossl_raise(eSSLError,
"SSL_CTX_use_certificate");
1309 if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
1310 sk_X509_pop_free(extra_chain, X509_free);
1311 ossl_raise(eSSLError,
"SSL_CTX_use_PrivateKey");
1315#if OPENSSL_VERSION_NUMBER >= 0x10002000 && !defined(LIBRESSL_VERSION_NUMBER)
1316 if (!SSL_CTX_set0_chain(ctx, extra_chain)) {
1317 sk_X509_pop_free(extra_chain, X509_free);
1325 SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain);
1326 if (orig_extra_chain && sk_X509_num(orig_extra_chain)) {
1327 rb_warning(
"SSL_CTX_set0_chain() is not available; " \
1328 "clearing previously set certificate chain");
1329 SSL_CTX_clear_extra_chain_certs(ctx);
1331 while ((x509_tmp = sk_X509_shift(extra_chain))) {
1333 if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) {
1334 X509_free(x509_tmp);
1335 sk_X509_pop_free(extra_chain, X509_free);
1336 ossl_raise(eSSLError,
"SSL_CTX_add_extra_chain_cert");
1339 sk_X509_free(extra_chain);
1352ossl_sslctx_session_add(
VALUE self,
VALUE arg)
1360 return SSL_CTX_add_session(ctx, sess) == 1 ?
Qtrue :
Qfalse;
1370ossl_sslctx_session_remove(
VALUE self,
VALUE arg)
1378 return SSL_CTX_remove_session(ctx, sess) == 1 ?
Qtrue :
Qfalse;
1388ossl_sslctx_get_session_cache_mode(
VALUE self)
1394 return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx));
1406ossl_sslctx_set_session_cache_mode(
VALUE self,
VALUE arg)
1412 SSL_CTX_set_session_cache_mode(ctx,
NUM2LONG(arg));
1425ossl_sslctx_get_session_cache_size(
VALUE self)
1431 return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx));
1442ossl_sslctx_set_session_cache_size(
VALUE self,
VALUE arg)
1448 SSL_CTX_sess_set_cache_size(ctx,
NUM2LONG(arg));
1476ossl_sslctx_get_session_cache_stats(
VALUE self)
1526 SSL_CTX_flush_sessions(ctx, (
long)tm);
1534#ifndef OPENSSL_NO_SOCK
1536ssl_started(SSL *ssl)
1539 return SSL_get_fd(ssl) >= 0;
1543ossl_ssl_mark(
void *
ptr)
1551ossl_ssl_free(
void *ssl)
1559 ossl_ssl_mark, ossl_ssl_free,
1565ossl_ssl_s_alloc(
VALUE klass)
1589 VALUE io, v_ctx, verify_cb;
1595 ossl_raise(eSSLError,
"SSL already initialized");
1602 ossl_sslctx_setup(v_ctx);
1613 SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (
void *)self);
1614 SSL_set_info_callback(ssl, ssl_info_cb);
1615 verify_cb =
rb_attr_get(v_ctx, id_i_verify_callback);
1616 SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (
void *)verify_cb);
1624ossl_ssl_setup(
VALUE self)
1631 if (ssl_started(ssl))
1645#define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret)))
1647#define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret))
1651write_would_block(
int nonblock)
1654 ossl_raise(eSSLErrorWaitWritable,
"write would block");
1658read_would_block(
int nonblock)
1661 ossl_raise(eSSLErrorWaitReadable,
"read would block");
1667 if (RB_TYPE_P(opts,
T_HASH) &&
1674ossl_start_ssl(
VALUE self,
int (*func)(),
const char *funcname,
VALUE opts)
1680 int nonblock = opts !=
Qfalse;
1681#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1694 if (!
NIL_P(cb_state)) {
1704 case SSL_ERROR_WANT_WRITE:
1706 write_would_block(nonblock);
1709 case SSL_ERROR_WANT_READ:
1711 read_would_block(nonblock);
1714 case SSL_ERROR_SYSCALL:
1721 ossl_raise(eSSLError,
"%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
1722#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1724 err = ERR_peek_last_error();
1725 if (ERR_GET_LIB(
err) == ERR_LIB_SSL &&
1726 ERR_GET_REASON(
err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
1727 const char *err_msg = ERR_reason_error_string(
err),
1728 *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
1732 verify_msg =
"(null)";
1734 ossl_raise(eSSLError,
"%s returned=%d errno=%d state=%s: %s (%s)",
1735 funcname, ret2, errno, SSL_state_string_long(ssl),
1736 err_msg, verify_msg);
1740 ossl_raise(eSSLError,
"%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
1755ossl_ssl_connect(
VALUE self)
1757 ossl_ssl_setup(self);
1759 return ossl_start_ssl(self, SSL_connect,
"SSL_connect",
Qfalse);
1790 ossl_ssl_setup(self);
1792 return ossl_start_ssl(self, SSL_connect,
"SSL_connect", opts);
1803ossl_ssl_accept(
VALUE self)
1805 ossl_ssl_setup(self);
1807 return ossl_start_ssl(self, SSL_accept,
"SSL_accept",
Qfalse);
1838 ossl_ssl_setup(self);
1840 return ossl_start_ssl(self, SSL_accept,
"SSL_accept", opts);
1847 int ilen, nread = 0;
1875 if (ssl_started(ssl)) {
1880 case SSL_ERROR_NONE:
1883 case SSL_ERROR_ZERO_RETURN:
1887 case SSL_ERROR_WANT_WRITE:
1891 write_would_block(nonblock);
1895 case SSL_ERROR_WANT_READ:
1899 read_would_block(nonblock);
1903 case SSL_ERROR_SYSCALL:
1904 if (!ERR_peek_error()) {
1930 rb_warning(
"SSL session is not started yet.");
1931#if defined(RB_PASS_KEYWORDS)
1964 return ossl_ssl_read_internal(
argc,
argv, self, 0);
1983 return ossl_ssl_read_internal(
argc,
argv, self, 1);
1992 int nonblock = opts !=
Qfalse;
1999 if (ssl_started(ssl)) {
2001 int num = RSTRING_LENINT(tmp);
2009 case SSL_ERROR_NONE:
2011 case SSL_ERROR_WANT_WRITE:
2013 write_would_block(nonblock);
2016 case SSL_ERROR_WANT_READ:
2018 read_would_block(nonblock);
2021 case SSL_ERROR_SYSCALL:
2039 ID meth = nonblock ?
2042 rb_warning(
"SSL session is not started yet.");
2043#if defined(RB_PASS_KEYWORDS)
2072 return ossl_ssl_write_internal(self,
str,
Qfalse);
2089 return ossl_ssl_write_internal(self,
str, opts);
2100ossl_ssl_stop(
VALUE self)
2106 if (!ssl_started(ssl))
2108 ret = SSL_shutdown(ssl);
2131ossl_ssl_get_cert(
VALUE self)
2142 cert = SSL_get_certificate(ssl);
2157ossl_ssl_get_peer_cert(
VALUE self)
2165 cert = SSL_get_peer_certificate(ssl);
2183ossl_ssl_get_peer_cert_chain(
VALUE self)
2193 chain = SSL_get_peer_cert_chain(ssl);
2194 if(!chain)
return Qnil;
2195 num = sk_X509_num(chain);
2197 for (i = 0; i <
num; i++){
2198 cert = sk_X509_value(chain, i);
2213ossl_ssl_get_version(
VALUE self)
2230ossl_ssl_get_cipher(
VALUE self)
2233 const SSL_CIPHER *cipher;
2236 cipher = SSL_get_current_cipher(ssl);
2237 return cipher ? ossl_ssl_cipher_to_ary(cipher) :
Qnil;
2248ossl_ssl_get_state(
VALUE self)
2270ossl_ssl_pending(
VALUE self)
2276 return INT2NUM(SSL_pending(ssl));
2286ossl_ssl_session_reused(
VALUE self)
2310 if (SSL_set_session(ssl, sess) != 1)
2327 char *hostname =
NULL;
2334 if (!SSL_set_tlsext_host_name(ssl, hostname))
2353ossl_ssl_get_verify_result(
VALUE self)
2359 return LONG2NUM(SSL_get_verify_result(ssl));
2370ossl_ssl_get_finished(
VALUE self)
2373 char sizer[1], *
buf;
2378 len = SSL_get_finished(ssl, sizer, 0);
2383 SSL_get_finished(ssl,
buf,
len);
2395ossl_ssl_get_peer_finished(
VALUE self)
2398 char sizer[1], *
buf;
2403 len = SSL_get_peer_finished(ssl, sizer, 0);
2408 SSL_get_peer_finished(ssl,
buf,
len);
2424ossl_ssl_get_client_ca_list(
VALUE self)
2431 ca = SSL_get_client_CA_list(ssl);
2435# ifndef OPENSSL_NO_NEXTPROTONEG
2444ossl_ssl_npn_protocol(
VALUE self)
2447 const unsigned char *
out;
2448 unsigned int outlen;
2452 SSL_get0_next_proto_negotiated(ssl, &
out, &outlen);
2460# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2469ossl_ssl_alpn_protocol(
VALUE self)
2472 const unsigned char *
out;
2473 unsigned int outlen;
2477 SSL_get0_alpn_selected(ssl, &
out, &outlen);
2485# ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2493ossl_ssl_tmp_key(
VALUE self)
2499 if (!SSL_get_server_tmp_key(ssl, &
key))
2516 id_call = rb_intern_const(
"call");
2517 ID_callback_state = rb_intern_const(
"callback_state");
2519 ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (
void *)
"ossl_ssl_ex_vcb_idx", 0, 0, 0);
2520 if (ossl_ssl_ex_vcb_idx < 0)
2522 ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0, (
void *)
"ossl_ssl_ex_ptr_idx", 0, 0, 0);
2523 if (ossl_ssl_ex_ptr_idx < 0)
2525 ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (
void *)
"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
2526 if (ossl_sslctx_ex_ptr_idx < 0)
2528#if !defined(HAVE_X509_STORE_UP_REF)
2529 ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (
void *)
"ossl_sslctx_ex_store_p", 0, 0, 0);
2530 if (ossl_sslctx_ex_store_p < 0)
2680#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
2751#ifndef OPENSSL_NO_NEXTPROTONEG
2783#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2818 ossl_sslctx_set_minmax_proto_version, 2);
2824#ifdef SSL_MODE_SEND_FALLBACK_SCSV
2894#ifdef OPENSSL_NO_SOCK
2927# ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2930# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2933# ifndef OPENSSL_NO_NEXTPROTONEG
2945#ifdef SSL_OP_TLSEXT_PADDING
2948#ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG
2951#ifdef SSL_OP_ALLOW_NO_DHE_KEX
2959#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC
2964#ifdef SSL_OP_NO_RENEGOTIATION
2973#ifdef SSL_OP_NO_TLSv1_3
3034#ifdef TLS1_3_VERSION
3040 sym_exception =
ID2SYM(rb_intern_const(
"exception"));
3041 sym_wait_readable =
ID2SYM(rb_intern_const(
"wait_readable"));
3042 sym_wait_writable =
ID2SYM(rb_intern_const(
"wait_writable"));
3044 id_tmp_dh_callback = rb_intern_const(
"tmp_dh_callback");
3045 id_tmp_ecdh_callback = rb_intern_const(
"tmp_ecdh_callback");
3046 id_npn_protocols_encoded = rb_intern_const(
"npn_protocols_encoded");
3047 id_each = rb_intern_const(
"each");
3049#define DefIVarID(name) do \
3050 id_i_##name = rb_intern_const("@"#name); while (0)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_ary_entry(VALUE ary, long offset)
int bits(struct state *s, int need)
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
size_t map(int syms, int left, int len)
char str[HTML_ESCAPE_MAX_LEN+1]
#define RSTRING_LEN(string)
#define RSTRING_PTR(string)
void rb_gc_mark(VALUE ptr)
void rb_include_module(VALUE klass, VALUE module)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_define_module(const char *name)
VALUE rb_define_module_under(VALUE outer, const char *name)
void rb_undef_method(VALUE klass, const char *name)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
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)
void rb_warning(const char *fmt,...)
VALUE rb_cObject
Object class.
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.
unsigned in(void *in_desc, z_const unsigned char **buf)
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
VALUE rb_funcallv_kw(VALUE, ID, int, const VALUE *, int)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
VALUE rb_call_super(int, const VALUE *)
VALUE rb_str_unlocktmp(VALUE)
#define rb_str_new(str, len)
void rb_str_set_len(VALUE, long)
void rb_str_modify(VALUE)
VALUE rb_str_split(VALUE, const char *)
VALUE rb_str_append(VALUE, VALUE)
VALUE rb_str_new_frozen(VALUE)
void rb_str_modify_expand(VALUE, long)
VALUE rb_str_locktmp(VALUE)
VALUE rb_attr_get(VALUE, ID)
VALUE rb_ivar_set(VALUE, ID, VALUE)
void rb_attr(VALUE, ID, int, int, int)
int rb_respond_to(VALUE, ID)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj, VALUE marker)
ID rb_intern(const char *)
void rb_define_const(VALUE, const char *, VALUE)
void rb_io_check_writable(rb_io_t *)
void rb_io_check_readable(rb_io_t *)
int rb_io_wait_writable(int fd)
int rb_io_wait_readable(int fd)
#define no_exception_p(opts)
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
#define ALLOCA_N(type, n)
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
#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)
#define RARRAY_AREF(a, i)
#define StringValueCStr(v)
#define RTYPEDDATA_DATA(v)
#define TypedData_Get_Struct(obj, type, data_type, sval)
#define TypedData_Wrap_Struct(klass, data_type, sval)
@ RUBY_TYPED_FREE_IMMEDIATELY
#define RB_INTEGER_TYPE_P(obj)