diff options
author | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2020-02-16 15:21:29 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-16 15:21:29 +0900 |
commit | b99775b163ce44079c1f8727ce9b4ed8bb03489d (patch) | |
tree | 4f9fd53f21c94dfeb05fefe1143bbe770228733a /ext/openssl/ossl_ssl.c | |
parent | 0bfa479c52963b95a47ceab3d453f21b646366a2 (diff) |
Import openssl-2.2.0 (#2693)
Import the master branch of ruby/openssl for preparing to release openssl-2.2.0
Notes
Notes:
Merged-By: hsbt <hsbt@ruby-lang.org>
Diffstat (limited to 'ext/openssl/ossl_ssl.c')
-rw-r--r-- | ext/openssl/ossl_ssl.c | 113 |
1 files changed, 94 insertions, 19 deletions
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 80a42383f7..dfbfbb22ee 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -810,6 +810,10 @@ ossl_sslctx_setup(VALUE self) } #endif /* OPENSSL_NO_EC */ +#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH + SSL_CTX_set_post_handshake_auth(ctx, 1); +#endif + val = rb_attr_get(self, id_i_cert_store); if (!NIL_P(val)) { X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */ @@ -1318,6 +1322,17 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self) return self; } +static VALUE +ossl_sslctx_add_certificate_chain_file(VALUE self, VALUE path) +{ + StringValue(path); + SSL_CTX *ctx = NULL; + + GetSSLCTX(self, ctx); + + return SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(path)) == 1 ? Qtrue : Qfalse; +} + /* * call-seq: * ctx.session_add(session) -> true | false @@ -1877,18 +1892,24 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) } } else { - ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread"); + ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread"); - rb_warning("SSL session is not started yet."); - if (nonblock) { + rb_warning("SSL session is not started yet."); +#if defined(RB_PASS_KEYWORDS) + if (nonblock) { VALUE argv[3]; argv[0] = len; argv[1] = str; argv[2] = opts; return rb_funcallv_kw(io, meth, 3, argv, RB_PASS_KEYWORDS); } - else - return rb_funcall(io, meth, 2, len, str); +#else + if (nonblock) { + return rb_funcall(io, meth, 3, len, str, opts); + } +#endif + else + return rb_funcall(io, meth, 2, len, str); } end: @@ -1911,7 +1932,6 @@ ossl_ssl_read(int argc, VALUE *argv, VALUE self) } /* - * :nodoc: * call-seq: * ssl.sysread_nonblock(length) => string * ssl.sysread_nonblock(length, buffer) => buffer @@ -1976,15 +1996,21 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts) ID meth = nonblock ? rb_intern("write_nonblock") : rb_intern("syswrite"); - rb_warning("SSL session is not started yet."); - if (nonblock) { + rb_warning("SSL session is not started yet."); +#if defined(RB_PASS_KEYWORDS) + if (nonblock) { VALUE argv[2]; argv[0] = str; argv[1] = opts; return rb_funcallv_kw(io, meth, 2, argv, RB_PASS_KEYWORDS); } - else - return rb_funcall(io, meth, 1, str); +#else + if (nonblock) { + return rb_funcall(io, meth, 2, str, opts); + } +#endif + else + return rb_funcall(io, meth, 1, str); } end: @@ -2004,7 +2030,6 @@ ossl_ssl_write(VALUE self, VALUE str) } /* - * :nodoc: * call-seq: * ssl.syswrite_nonblock(string) => Integer * @@ -2022,7 +2047,6 @@ ossl_ssl_write_nonblock(int argc, VALUE *argv, VALUE self) } /* - * :nodoc: * call-seq: * ssl.stop => nil * @@ -2294,6 +2318,56 @@ ossl_ssl_get_verify_result(VALUE self) /* * call-seq: + * ssl.finished_message => "finished message" + * + * Returns the last *Finished* message sent + * + */ +static VALUE +ossl_ssl_get_finished(VALUE self) +{ + SSL *ssl; + + GetSSL(self, ssl); + + char sizer[1]; + size_t len = SSL_get_finished(ssl, sizer, 0); + + if(len == 0) + return Qnil; + + char* buf = ALLOCA_N(char, len); + SSL_get_finished(ssl, buf, len); + return rb_str_new(buf, len); +} + +/* + * call-seq: + * ssl.peer_finished_message => "peer finished message" + * + * Returns the last *Finished* message received + * + */ +static VALUE +ossl_ssl_get_peer_finished(VALUE self) +{ + SSL *ssl; + + GetSSL(self, ssl); + + char sizer[1]; + size_t len = SSL_get_peer_finished(ssl, sizer, 0); + + if(len == 0) + return Qnil; + + char* buf = ALLOCA_N(char, len); + SSL_get_peer_finished(ssl, buf, len); + return rb_str_new(buf, len); +} + +/* + * call-seq: * ssl.client_ca => [x509name, ...] * * Returns the list of client CAs. Please note that in contrast to @@ -2614,13 +2688,13 @@ Init_ossl_ssl(void) rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue); /* - * A callback invoked whenever a new handshake is initiated. May be used - * to disable renegotiation entirely. + * A callback invoked whenever a new handshake is initiated on an + * established connection. May be used to disable renegotiation entirely. * * The callback is invoked with the active SSLSocket. The callback's - * return value is irrelevant, normal return indicates "approval" of the + * return value is ignored. A normal return indicates "approval" of the * renegotiation and will continue the process. To forbid renegotiation - * and to cancel the process, an Error may be raised within the callback. + * and to cancel the process, raise an exception within the callback. * * === Disable client renegotiation * @@ -2628,10 +2702,8 @@ Init_ossl_ssl(void) * renegotiation entirely. You may use a callback as follows to implement * this feature: * - * num_handshakes = 0 * ctx.renegotiation_cb = lambda do |ssl| - * num_handshakes += 1 - * raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1 + * raise RuntimeError, "Client renegotiation disabled" * end */ rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse); @@ -2712,6 +2784,7 @@ Init_ossl_ssl(void) rb_define_method(cSSLContext, "enable_fallback_scsv", ossl_sslctx_enable_fallback_scsv, 0); #endif rb_define_method(cSSLContext, "add_certificate", ossl_sslctx_add_certificate, -1); + rb_define_method(cSSLContext, "add_certificate_chain_file", ossl_sslctx_add_certificate_chain_file, 1); rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0); rb_define_alias(cSSLContext, "freeze", "setup"); @@ -2809,6 +2882,8 @@ Init_ossl_ssl(void) rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0); /* #hostname is defined in lib/openssl/ssl.rb */ rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1); + rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0); + rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0); # ifdef HAVE_SSL_GET_SERVER_TMP_KEY rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0); # endif |