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_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;
76 ossl_sslctx_s_alloc(
VALUE klass)
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");
114 parse_proto_version(
VALUE str)
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 },
185 for (i = 0; i <
numberof(options_map); i++) {
186 sum |= options_map[i].opts;
187 if (min && min > options_map[i].ver || max && max < options_map[i].ver)
188 opts |= options_map[i].opts;
190 SSL_CTX_clear_options(ctx, sum);
191 SSL_CTX_set_options(ctx, opts);
199 ossl_call_client_cert_cb(
VALUE obj)
217 ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
221 obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
232 #if !defined(OPENSSL_NO_DH) || \ 233 !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) 254 if (EVP_PKEY_base_id(pkey) != args->
type)
261 #if !defined(OPENSSL_NO_DH) 263 ossl_tmp_dh_callback(SSL *ssl,
int is_export,
int keylength)
270 rb_ssl = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
272 args.
id = id_tmp_dh_callback;
275 args.
type = EVP_PKEY_DH;
278 (
VALUE)&args, &state);
286 return EVP_PKEY_get0_DH(pkey);
290 #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) 299 rb_ssl = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
301 args.
id = id_tmp_ecdh_callback;
304 args.
type = EVP_PKEY_EC;
307 (
VALUE)&args, &state);
315 return EVP_PKEY_get0_EC_KEY(pkey);
320 call_verify_certificate_identity(
VALUE ctx_v)
322 X509_STORE_CTX *ctx = (X509_STORE_CTX *)ctx_v;
326 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
327 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
330 if (!
RTEST(hostname)) {
331 rb_warning(
"verify_hostname requires hostname to be set");
335 cert_obj =
ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx));
341 ossl_ssl_verify_callback(
int preverify_ok, X509_STORE_CTX *ctx)
347 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
348 cb = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx);
349 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
351 verify_hostname =
rb_attr_get(sslctx_obj, id_i_verify_hostname);
354 !X509_STORE_CTX_get_error_depth(ctx)) {
355 ret =
rb_protect(call_verify_certificate_identity, (
VALUE)ctx, &status);
360 preverify_ok = ret ==
Qtrue;
367 ossl_call_session_get_cb(
VALUE ary)
382 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) 383 ossl_sslctx_session_get_cb(SSL *ssl,
const unsigned char *
buf,
int len,
int *copy)
385 ossl_sslctx_session_get_cb(SSL *ssl,
unsigned char *
buf,
int len,
int *copy)
392 OSSL_Debug(
"SSL SESSION get callback entered");
393 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
398 ret_obj =
rb_protect(ossl_call_session_get_cb, ary, &state);
413 ossl_call_session_new_cb(
VALUE ary)
428 ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
433 OSSL_Debug(
"SSL SESSION new callback entered");
435 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
444 rb_protect(ossl_call_session_new_cb, ary, &state);
460 ossl_call_session_remove_cb(
VALUE ary)
467 cb =
rb_attr_get(sslctx_obj, id_i_session_remove_cb);
474 ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
476 VALUE ary, sslctx_obj, sess_obj;
486 OSSL_Debug(
"SSL SESSION remove callback entered");
488 sslctx_obj = (
VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx);
497 rb_protect(ossl_call_session_remove_cb, ary, &state);
515 if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){
525 ossl_call_servername_cb(
VALUE ary)
541 ossl_sslctx_setup(ret_obj);
544 SSL_set_SSL_CTX(ssl, ctx2);
546 }
else if (!
NIL_P(ret_obj)) {
548 "OpenSSL::SSL::SSLContext object or nil");
555 ssl_servername_cb(SSL *ssl,
int *ad,
void *arg)
559 const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
562 return SSL_TLSEXT_ERR_OK;
564 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
569 rb_protect(ossl_call_servername_cb, ary, &state);
572 return SSL_TLSEXT_ERR_ALERT_FATAL;
575 return SSL_TLSEXT_ERR_OK;
579 ssl_renegotiation_cb(
const SSL *ssl)
583 ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
585 cb =
rb_attr_get(sslctx_obj, id_i_renegotiation_cb);
586 if (
NIL_P(cb))
return;
591 #if !defined(OPENSSL_NO_NEXTPROTONEG) || \ 592 defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) 594 ssl_npn_encode_protocol_i(
VALUE cur,
VALUE encoded)
598 if (len < 1 || len > 255)
599 ossl_raise(eSSLError,
"Advertised protocol must have length 1..255");
608 ssl_encode_npn_protocols(
VALUE protocols)
617 const unsigned char *
in;
622 npn_select_cb_common_i(
VALUE tmp)
625 const unsigned char *
in = args->
in, *in_end = in + args->
inlen;
632 while (in < in_end) {
641 if (len < 1 || len >= 256) {
642 ossl_raise(eSSLError,
"Selected protocol name must have length 1..255");
649 ssl_npn_select_cb_common(SSL *ssl,
VALUE cb,
const unsigned char **out,
650 unsigned char *outlen,
const unsigned char *
in,
663 VALUE ssl_obj = (
VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
666 return SSL_TLSEXT_ERR_ALERT_FATAL;
672 return SSL_TLSEXT_ERR_OK;
676 #ifndef OPENSSL_NO_NEXTPROTONEG 678 ssl_npn_advertise_cb(SSL *ssl,
const unsigned char **out,
unsigned int *outlen,
683 *out = (
const unsigned char *)
RSTRING_PTR(protocols);
686 return SSL_TLSEXT_ERR_OK;
690 ssl_npn_select_cb(SSL *ssl,
unsigned char **out,
unsigned char *outlen,
691 const unsigned char *
in,
unsigned int inlen,
void *arg)
695 sslctx_obj = (
VALUE) arg;
698 return ssl_npn_select_cb_common(ssl, cb, (
const unsigned char **)out,
703 #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB 705 ssl_alpn_select_cb(SSL *ssl,
const unsigned char **out,
unsigned char *outlen,
706 const unsigned char *
in,
unsigned int inlen,
void *arg)
710 sslctx_obj = (
VALUE) arg;
713 return ssl_npn_select_cb_common(ssl, cb, out, outlen,
in,
inlen);
719 ssl_info_cb(
const SSL *ssl,
int where,
int val)
723 if (is_server && where & SSL_CB_HANDSHAKE_START) {
724 ssl_renegotiation_cb(ssl);
732 ossl_sslctx_get_options(
VALUE self)
740 return ULONG2NUM((
unsigned long)SSL_CTX_get_options(ctx));
747 ossl_sslctx_set_options(
VALUE self,
VALUE options)
754 SSL_CTX_clear_options(ctx, SSL_CTX_get_options(ctx));
756 if (
NIL_P(options)) {
757 SSL_CTX_set_options(ctx, SSL_OP_ALL);
759 SSL_CTX_set_options(ctx,
NUM2ULONG(options));
775 ossl_sslctx_setup(
VALUE self)
778 X509 *cert =
NULL, *client_ca =
NULL;
780 char *ca_path =
NULL, *ca_file =
NULL;
788 #if !defined(OPENSSL_NO_DH) 789 SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
792 #if !defined(OPENSSL_NO_EC) 796 # if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) 797 rb_warn(
"#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead");
798 SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
799 # if defined(HAVE_SSL_CTX_SET_ECDH_AUTO) 802 if (!SSL_CTX_set_ecdh_auto(ctx, 0))
803 ossl_raise(eSSLError,
"SSL_CTX_set_ecdh_auto");
806 ossl_raise(eSSLError,
"OpenSSL does not support tmp_ecdh_callback; " 807 "use #ecdh_curves= instead");
815 SSL_CTX_set_cert_store(ctx, store);
816 #if !defined(HAVE_X509_STORE_UP_REF) 823 SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
840 if (!SSL_CTX_use_certificate(ctx, cert)) {
842 ossl_raise(eSSLError,
"SSL_CTX_use_certificate");
844 if (!SSL_CTX_use_PrivateKey(ctx, key)) {
846 ossl_raise(eSSLError,
"SSL_CTX_use_PrivateKey");
848 if (!SSL_CTX_check_private_key(ctx)) {
849 ossl_raise(eSSLError,
"SSL_CTX_check_private_key");
858 if (!SSL_CTX_add_client_CA(ctx, client_ca)){
860 ossl_raise(eSSLError,
"SSL_CTX_add_client_CA");
866 if (!SSL_CTX_add_client_CA(ctx, client_ca)){
868 ossl_raise(eSSLError,
"SSL_CTX_add_client_CA");
877 if(ca_file || ca_path){
878 if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
883 verify_mode =
NIL_P(val) ? SSL_VERIFY_NONE :
NUM2INT(val);
884 SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
886 SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);
892 if(!
NIL_P(val)) SSL_CTX_set_verify_depth(ctx,
NUM2INT(val));
894 #ifndef OPENSSL_NO_NEXTPROTONEG 897 VALUE encoded = ssl_encode_npn_protocols(val);
898 rb_ivar_set(
self, id_npn_protocols_encoded, encoded);
899 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (
void *)encoded);
900 OSSL_Debug(
"SSL NPN advertise callback added");
903 SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (
void *)
self);
908 #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB 911 VALUE rprotos = ssl_encode_npn_protocols(val);
914 if (SSL_CTX_set_alpn_protos(ctx, (
unsigned char *)
RSTRING_PTR(rprotos),
916 ossl_raise(eSSLError,
"SSL_CTX_set_alpn_protos");
920 SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (
void *)
self);
930 if (!SSL_CTX_set_session_id_context(ctx, (
unsigned char *)
RSTRING_PTR(val),
932 ossl_raise(eSSLError,
"SSL_CTX_set_session_id_context");
937 SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
941 SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
945 SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
946 OSSL_Debug(
"SSL SESSION remove callback added");
951 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
952 OSSL_Debug(
"SSL TLSEXT servername callback added");
959 ossl_ssl_cipher_to_ary(
const SSL_CIPHER *cipher)
967 bits = SSL_CIPHER_get_bits(cipher, &alg_bits);
981 ossl_sslctx_get_ciphers(
VALUE self)
985 const SSL_CIPHER *cipher;
994 num = sk_SSL_CIPHER_num(ciphers);
996 for(i = 0; i < num; i++){
997 cipher = sk_SSL_CIPHER_value(ciphers, i);
1039 ossl_raise(eSSLError,
"SSL_CTX is not initialized.");
1043 ossl_raise(eSSLError,
"SSL_CTX_set_cipher_list");
1049 #if !defined(OPENSSL_NO_EC) 1078 ossl_sslctx_set_ecdh_curves(
VALUE self,
VALUE arg)
1086 #if defined(HAVE_SSL_CTX_SET1_CURVES_LIST) 1087 if (!SSL_CTX_set1_curves_list(ctx,
RSTRING_PTR(arg)))
1093 VALUE curve, splitted;
1099 ossl_raise(eSSLError,
"invalid input format");
1105 if (nid == NID_undef)
1107 if (nid == NID_undef)
1110 ec = EC_KEY_new_by_curve_name(nid);
1113 EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
1114 if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
1116 ossl_raise(eSSLError,
"SSL_CTX_set_tmp_ecdh");
1119 # if defined(HAVE_SSL_CTX_SET_ECDH_AUTO) 1122 if (!SSL_CTX_set_ecdh_auto(ctx, 0))
1123 ossl_raise(eSSLError,
"SSL_CTX_set_ecdh_auto");
1131 #define ossl_sslctx_set_ecdh_curves rb_f_notimplement 1143 ossl_sslctx_get_security_level(
VALUE self)
1149 #if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL) 1150 return INT2NUM(SSL_CTX_get_security_level(ctx));
1177 ossl_sslctx_set_security_level(
VALUE self,
VALUE value)
1184 #if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL) 1185 SSL_CTX_set_security_level(ctx,
NUM2INT(value));
1190 "not supported in this version of OpenSSL");
1203 ossl_sslctx_session_add(
VALUE self,
VALUE arg)
1211 return SSL_CTX_add_session(ctx, sess) == 1 ?
Qtrue :
Qfalse;
1221 ossl_sslctx_session_remove(
VALUE self,
VALUE arg)
1229 return SSL_CTX_remove_session(ctx, sess) == 1 ?
Qtrue :
Qfalse;
1239 ossl_sslctx_get_session_cache_mode(
VALUE self)
1245 return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx));
1257 ossl_sslctx_set_session_cache_mode(
VALUE self,
VALUE arg)
1263 SSL_CTX_set_session_cache_mode(ctx,
NUM2LONG(arg));
1276 ossl_sslctx_get_session_cache_size(
VALUE self)
1282 return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx));
1293 ossl_sslctx_set_session_cache_size(
VALUE self,
VALUE arg)
1299 SSL_CTX_sess_set_cache_size(ctx,
NUM2LONG(arg));
1327 ossl_sslctx_get_session_cache_stats(
VALUE self)
1377 SSL_CTX_flush_sessions(ctx, (
long)tm);
1385 #ifndef OPENSSL_NO_SOCK 1387 ssl_started(SSL *ssl)
1390 return SSL_get_fd(ssl) >= 0;
1394 ossl_ssl_free(
void *ssl)
1408 ossl_ssl_s_alloc(
VALUE klass)
1432 VALUE io, v_ctx, verify_cb;
1438 ossl_raise(eSSLError,
"SSL already initialized");
1445 ossl_sslctx_setup(v_ctx);
1456 SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (
void *)
self);
1457 SSL_set_info_callback(ssl, ssl_info_cb);
1458 verify_cb =
rb_attr_get(v_ctx, id_i_verify_callback);
1459 SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (
void *)verify_cb);
1467 ossl_ssl_setup(
VALUE self)
1474 if (ssl_started(ssl))
1488 #define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret))) 1490 #define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret)) 1494 write_would_block(
int nonblock)
1497 ossl_raise(eSSLErrorWaitWritable,
"write would block");
1501 read_would_block(
int nonblock)
1504 ossl_raise(eSSLErrorWaitReadable,
"read would block");
1508 no_exception_p(
VALUE opts)
1517 ossl_start_ssl(
VALUE self,
int (*func)(),
const char *funcname,
VALUE opts)
1523 int nonblock = opts !=
Qfalse;
1524 #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED) 1537 if (!
NIL_P(cb_state)) {
1547 case SSL_ERROR_WANT_WRITE:
1548 if (no_exception_p(opts)) {
return sym_wait_writable; }
1549 write_would_block(nonblock);
1552 case SSL_ERROR_WANT_READ:
1553 if (no_exception_p(opts)) {
return sym_wait_readable; }
1554 read_would_block(nonblock);
1557 case SSL_ERROR_SYSCALL:
1559 ossl_raise(eSSLError,
"%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2,
errno, SSL_state_string_long(ssl));
1560 #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED) 1562 err = ERR_peek_last_error();
1563 if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
1564 ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
1565 const char *err_msg = ERR_reason_error_string(err),
1566 *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
1570 verify_msg =
"(null)";
1572 ossl_raise(eSSLError,
"%s returned=%d errno=%d state=%s: %s (%s)",
1573 funcname, ret2,
errno, SSL_state_string_long(ssl),
1574 err_msg, verify_msg);
1578 ossl_raise(eSSLError,
"%s returned=%d errno=%d state=%s", funcname, ret2,
errno, SSL_state_string_long(ssl));
1593 ossl_ssl_connect(
VALUE self)
1595 ossl_ssl_setup(
self);
1597 return ossl_start_ssl(
self, SSL_connect,
"SSL_connect",
Qfalse);
1628 ossl_ssl_setup(
self);
1630 return ossl_start_ssl(
self, SSL_connect,
"SSL_connect", opts);
1641 ossl_ssl_accept(
VALUE self)
1643 ossl_ssl_setup(
self);
1645 return ossl_start_ssl(
self, SSL_accept,
"SSL_accept",
Qfalse);
1676 ossl_ssl_setup(
self);
1678 return ossl_start_ssl(
self, SSL_accept,
"SSL_accept", opts);
1685 int ilen, nread = 0;
1714 if (ssl_started(ssl)) {
1718 case SSL_ERROR_NONE:
1720 case SSL_ERROR_ZERO_RETURN:
1721 if (no_exception_p(opts)) {
return Qnil; }
1723 case SSL_ERROR_WANT_WRITE:
1724 if (no_exception_p(opts)) {
return sym_wait_writable; }
1725 write_would_block(nonblock);
1728 case SSL_ERROR_WANT_READ:
1729 if (no_exception_p(opts)) {
return sym_wait_readable; }
1730 read_would_block(nonblock);
1733 case SSL_ERROR_SYSCALL:
1734 if (!ERR_peek_error()) {
1745 if (no_exception_p(opts)) {
return Qnil; }
1757 rb_warning(
"SSL session is not started yet.");
1759 return rb_funcall(io, meth, 3, len, str, opts);
1780 return ossl_ssl_read_internal(
argc,
argv,
self, 0);
1799 return ossl_ssl_read_internal(
argc,
argv,
self, 1);
1808 int nonblock = opts !=
Qfalse;
1815 if (ssl_started(ssl)) {
1825 case SSL_ERROR_NONE:
1827 case SSL_ERROR_WANT_WRITE:
1828 if (no_exception_p(opts)) {
return sym_wait_writable; }
1829 write_would_block(nonblock);
1832 case SSL_ERROR_WANT_READ:
1833 if (no_exception_p(opts)) {
return sym_wait_readable; }
1834 read_would_block(nonblock);
1837 case SSL_ERROR_SYSCALL:
1845 ID meth = nonblock ?
1848 rb_warning(
"SSL session is not started yet.");
1868 return ossl_ssl_write_internal(
self, str,
Qfalse);
1885 return ossl_ssl_write_internal(
self, str, opts);
1896 ossl_ssl_stop(
VALUE self)
1902 if (!ssl_started(ssl))
1904 ret = SSL_shutdown(ssl);
1927 ossl_ssl_get_cert(
VALUE self)
1938 cert = SSL_get_certificate(ssl);
1953 ossl_ssl_get_peer_cert(
VALUE self)
1961 cert = SSL_get_peer_certificate(ssl);
1979 ossl_ssl_get_peer_cert_chain(
VALUE self)
1989 chain = SSL_get_peer_cert_chain(ssl);
1990 if(!chain)
return Qnil;
1991 num = sk_X509_num(chain);
1993 for (i = 0; i < num; i++){
1994 cert = sk_X509_value(chain, i);
2009 ossl_ssl_get_version(
VALUE self)
2026 ossl_ssl_get_cipher(
VALUE self)
2029 const SSL_CIPHER *cipher;
2032 cipher = SSL_get_current_cipher(ssl);
2033 return cipher ? ossl_ssl_cipher_to_ary(cipher) :
Qnil;
2044 ossl_ssl_get_state(
VALUE self)
2066 ossl_ssl_pending(
VALUE self)
2072 return INT2NUM(SSL_pending(ssl));
2082 ossl_ssl_session_reused(
VALUE self)
2106 if (SSL_set_session(ssl, sess) != 1)
2123 char *hostname =
NULL;
2130 if (!SSL_set_tlsext_host_name(ssl, hostname))
2149 ossl_ssl_get_verify_result(
VALUE self)
2155 return INT2NUM(SSL_get_verify_result(ssl));
2170 ossl_ssl_get_client_ca_list(
VALUE self)
2177 ca = SSL_get_client_CA_list(ssl);
2181 # ifndef OPENSSL_NO_NEXTPROTONEG 2190 ossl_ssl_npn_protocol(
VALUE self)
2193 const unsigned char *out;
2194 unsigned int outlen;
2198 SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
2202 return rb_str_new((
const char *) out, outlen);
2206 # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB 2215 ossl_ssl_alpn_protocol(
VALUE self)
2218 const unsigned char *out;
2219 unsigned int outlen;
2223 SSL_get0_alpn_selected(ssl, &out, &outlen);
2227 return rb_str_new((
const char *) out, outlen);
2231 # ifdef HAVE_SSL_GET_SERVER_TMP_KEY 2239 ossl_ssl_tmp_key(
VALUE self)
2245 if (!SSL_get_server_tmp_key(ssl, &key))
2253 #define rb_intern(s) rb_intern_const(s) 2264 ID_callback_state =
rb_intern(
"callback_state");
2266 ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (
void *)
"ossl_ssl_ex_vcb_idx", 0, 0, 0);
2267 if (ossl_ssl_ex_vcb_idx < 0)
2269 ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0, (
void *)
"ossl_ssl_ex_ptr_idx", 0, 0, 0);
2270 if (ossl_ssl_ex_ptr_idx < 0)
2272 ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (
void *)
"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
2273 if (ossl_sslctx_ex_ptr_idx < 0)
2275 #if !defined(HAVE_X509_STORE_UP_REF) 2276 ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (
void *)
"ossl_sslctx_ex_store_p", 0, 0, 0);
2277 if (ossl_sslctx_ex_store_p < 0)
2418 #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) 2491 #ifndef OPENSSL_NO_NEXTPROTONEG 2523 #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB 2558 ossl_sslctx_set_minmax_proto_version, 2);
2630 #ifdef OPENSSL_NO_SOCK 2661 # ifdef HAVE_SSL_GET_SERVER_TMP_KEY 2664 # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB 2667 # ifndef OPENSSL_NO_NEXTPROTONEG 2679 #ifdef SSL_OP_TLSEXT_PADDING 2682 #ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG 2685 #ifdef SSL_OP_ALLOW_NO_DHE_KEX 2693 #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC 2698 #ifdef SSL_OP_NO_RENEGOTIATION 2707 #ifdef SSL_OP_NO_TLSv1_3 2768 #ifdef TLS1_3_VERSION 2778 id_tmp_dh_callback =
rb_intern(
"tmp_dh_callback");
2779 id_tmp_ecdh_callback =
rb_intern(
"tmp_ecdh_callback");
2780 id_npn_protocols_encoded =
rb_intern(
"npn_protocols_encoded");
2782 #define DefIVarID(name) do \ 2783 id_i_##name = rb_intern("@"#name); while (0)
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,...)
VALUE rb_ary_entry(VALUE ary, long offset)
#define RUBY_TYPED_FREE_IMMEDIATELY
#define ssl_get_error(ssl, ret)
void rb_io_check_readable(rb_io_t *)
const rb_data_type_t ossl_ssl_type
void rb_raise(VALUE exc, const char *fmt,...)
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
EVP_PKEY * GetPrivPKeyPtr(VALUE obj)
#define TypedData_Wrap_Struct(klass, data_type, sval)
#define TypedData_Get_Struct(obj, type, data_type, sval)
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE rb_iterate(VALUE(*)(VALUE), VALUE, VALUE(*)(ANYARGS), VALUE)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_String(VALUE)
Equivalent to Kernel#String in Ruby.
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
VALUE ossl_x509name_sk2ary(const STACK_OF(X509_NAME) *names)
void rb_str_set_len(VALUE, long)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
#define SSL_SESSION_up_ref(x)
void rb_include_module(VALUE klass, VALUE module)
VALUE rb_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE)
VALUE ossl_pkey_new(EVP_PKEY *pkey)
void rb_undef_method(VALUE klass, const char *name)
#define GetSSLCTX(obj, ctx)
VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj)
#define GetOpenFile(obj, fp)
VALUE rb_str_buf_cat(VALUE, const char *, long)
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
void Init_ossl_ssl_session(void)
#define RB_TYPE_P(obj, type)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
#define EC_curve_nist2nid
X509 * GetX509CertPtr(VALUE)
RUBY_EXTERN VALUE rb_mWaitReadable
void ossl_clear_error(void)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
RUBY_EXTERN VALUE rb_cObject
STACK_OF(X509) *ossl_x509_ary2sk(VALUE)
void rb_attr(VALUE, ID, int, int, int)
VALUE rb_str_cat2(VALUE, const char *)
void rb_define_const(VALUE, const char *, VALUE)
int rb_io_wait_writable(int)
VALUE ossl_x509_new(X509 *)
VALUE rb_obj_is_instance_of(VALUE, VALUE)
call-seq: obj.instance_of?(class) -> true or false
VALUE rb_str_split(VALUE, const char *)
#define GetSSLSession(obj, sess)
void rb_sys_fail(const char *mesg)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
VALUE rb_obj_freeze(VALUE)
call-seq: obj.freeze -> obj
RUBY_EXTERN VALUE rb_mWaitWritable
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
void rb_str_modify_expand(VALUE, long)
int ossl_verify_cb_call(VALUE, int, X509_STORE_CTX *)
VALUE rb_ivar_set(VALUE, ID, VALUE)
unsigned char buf[MIME_BUF_SIZE]
VALUE rb_call_super(int, const VALUE *)
X509_STORE * GetX509StorePtr(VALUE)
int rb_respond_to(VALUE, ID)
register unsigned int len
VALUE rb_define_module_under(VALUE outer, const char *name)
#define X509_STORE_up_ref(x)
#define StringValueCStr(v)
void rb_str_modify(VALUE)
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
#define RARRAY_AREF(a, i)
void rb_warning(const char *fmt,...)
void ossl_raise(VALUE exc, const char *fmt,...)
EVP_PKEY * GetPKeyPtr(VALUE obj)
EVP_PKEY * DupPKeyPtr(VALUE obj)
X509 * DupX509CertPtr(VALUE)
void rb_io_check_writable(rb_io_t *)
#define SSL_CTX_get_ciphers(ctx)
#define RTYPEDDATA_DATA(v)
#define RSTRING_LENINT(str)
#define rb_check_frozen(obj)
VALUE rb_define_module(const char *name)
#define RB_INTEGER_TYPE_P(obj)
int rb_io_wait_readable(int)
RUBY_EXTERN VALUE rb_cTime
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE rb_str_append(VALUE, VALUE)
VALUE rb_attr_get(VALUE, ID)
VALUE rb_str_new(const char *, long)