summaryrefslogtreecommitdiff
path: root/ext/openssl/ossl_ssl.c
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2020-02-16 15:21:29 +0900
committerGitHub <noreply@github.com>2020-02-16 15:21:29 +0900
commitb99775b163ce44079c1f8727ce9b4ed8bb03489d (patch)
tree4f9fd53f21c94dfeb05fefe1143bbe770228733a /ext/openssl/ossl_ssl.c
parent0bfa479c52963b95a47ceab3d453f21b646366a2 (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.c113
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