Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ext/openssl/lib/openssl/ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ class SSLServer
def initialize(svr, ctx)
@svr = svr
@ctx = ctx
unless ctx.session_id_context
if !ctx.frozen? && !ctx.session_id_context
# see #6137 - session id may not exceed 32 bytes
prng = ::Random.new($0.hash)
session_id = prng.bytes(16).unpack1('H*')
Expand Down
129 changes: 121 additions & 8 deletions ext/openssl/ossl_x509store.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,52 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
return self;
}

/*
* call-seq:
* store.flags -> Integer
*
* Gets the verification flags for the Store.
*
* See also the man page X509_VERIFY_PARAM_get_flags(3).
*/
static VALUE
ossl_x509store_get_flags(VALUE self)
{
X509_STORE *store;
X509_VERIFY_PARAM *vpm;

GetX509Store(self, store);
vpm = X509_STORE_get0_param(store);
return ULONG2NUM(X509_VERIFY_PARAM_get_flags(vpm));
}

static void
x509vpm_set_flags_i(X509_VERIFY_PARAM *vpm, VALUE flags)
{
unsigned long curr = X509_VERIFY_PARAM_get_flags(vpm);
unsigned long f = NUM2ULONG(flags);

if ((curr | f) != f) {
rb_warn("`obj.flags = new_flags` does not clear existing flags; " \
"use `obj.clear_flags` first if you want to replace them, " \
"or `obj.flags |= new_flags` to indicate that " \
"appending flags is intentional");
}
if (!X509_VERIFY_PARAM_set_flags(vpm, f))
ossl_raise(eX509StoreError, "X509_VERIFY_PARAM_set_flags");
}

/*
* call-seq:
* store.flags = flags
*
* Sets the default flags used by certificate chain verification performed with
* the Store.
*
* *NOTE*: Despite the name, this method appends the specified flags to the
* existing flag set rather than replacing it. To clear existing flags, use
* #clear_flags before calling this method.
*
* _flags_ consists of zero or more of the constants defined in OpenSSL::X509
* with name V_FLAG_* or'ed together.
*
Expand All @@ -243,14 +282,42 @@ static VALUE
ossl_x509store_set_flags(VALUE self, VALUE flags)
{
X509_STORE *store;
long f = NUM2LONG(flags);

GetX509Store(self, store);
X509_STORE_set_flags(store, f);

x509vpm_set_flags_i(X509_STORE_get0_param(store), flags);
return flags;
}

static void
x509vpm_clear_flags_i(X509_VERIFY_PARAM *vpm, VALUE flags)
{
unsigned long f = NIL_P(flags) ? ~0UL : NUM2ULONG(flags);

if (!X509_VERIFY_PARAM_clear_flags(vpm, f))
ossl_raise(eX509StoreError, "X509_VERIFY_PARAM_clear_flags");
}

/*
* call-seq:
* store.clear_flags(flags = nil)
*
* Clears verification flags _flags_ for the Store. If _flags_ is omitted,
* clears all existing flags.
*
* See also the man page X509_VERIFY_PARAM_clear_flags(3).
*/
static VALUE
ossl_x509store_clear_flags(int argc, VALUE *argv, VALUE self)
{
X509_STORE *store;
VALUE flags;

rb_scan_args(argc, argv, "01", &flags);
GetX509Store(self, store);
x509vpm_clear_flags_i(X509_STORE_get0_param(store), flags);
return Qnil;
}

/*
* call-seq:
* store.purpose = purpose
Expand Down Expand Up @@ -768,27 +835,69 @@ ossl_x509stctx_get_curr_crl(VALUE self)
return ossl_x509crl_new(crl);
}

/*
* call-seq:
* stctx.flags -> Integer
*
* Gets the verification flags for the context.
*
* See also the man page X509_VERIFY_PARAM_get_flags(3).
*/
static VALUE
ossl_x509stctx_get_flags(VALUE self)
{
X509_STORE_CTX *ctx;
X509_VERIFY_PARAM *vpm;

GetX509StCtx(self, ctx);
vpm = X509_STORE_CTX_get0_param(ctx);
return ULONG2NUM(X509_VERIFY_PARAM_get_flags(vpm));
}

/*
* call-seq:
* stctx.flags = flags
*
* Sets the verification flags to the context. This overrides the default value
* set by Store#flags=.
*
* *NOTE*: Despite the name, this method appends the specified flags to the
* existing flag set rather than replacing it. To clear existing flags, use
* #clear_flags before calling this method.
*
* See also the man page X509_VERIFY_PARAM_set_flags(3).
*/
static VALUE
ossl_x509stctx_set_flags(VALUE self, VALUE flags)
{
X509_STORE_CTX *store;
long f = NUM2LONG(flags);

GetX509StCtx(self, store);
X509_STORE_CTX_set_flags(store, f);
X509_STORE_CTX *ctx;

GetX509StCtx(self, ctx);
x509vpm_set_flags_i(X509_STORE_CTX_get0_param(ctx), flags);
return flags;
}

/*
* call-seq:
* stctx.clear_flags(flags = nil)
*
* Clears verification flags _flags_ for the Store. If _flags_ is omitted,
* clears all existing flags.
*
* See also the man page X509_VERIFY_PARAM_clear_flags(3).
*/
static VALUE
ossl_x509stctx_clear_flags(int argc, VALUE *argv, VALUE self)
{
X509_STORE_CTX *ctx;
VALUE flags;

rb_scan_args(argc, argv, "01", &flags);
GetX509StCtx(self, ctx);
x509vpm_clear_flags_i(X509_STORE_CTX_get0_param(ctx), flags);
return Qnil;
}

/*
* call-seq:
* stctx.purpose = purpose
Expand Down Expand Up @@ -944,7 +1053,9 @@ Init_ossl_x509store(void)
rb_define_method(cX509Store, "initialize", ossl_x509store_initialize, -1);
rb_undef_method(cX509Store, "initialize_copy");
rb_define_method(cX509Store, "verify_callback=", ossl_x509store_set_vfy_cb, 1);
rb_define_method(cX509Store, "flags", ossl_x509store_get_flags, 0);
rb_define_method(cX509Store, "flags=", ossl_x509store_set_flags, 1);
rb_define_method(cX509Store, "clear_flags", ossl_x509store_clear_flags, -1);
rb_define_method(cX509Store, "purpose=", ossl_x509store_set_purpose, 1);
rb_define_method(cX509Store, "trust=", ossl_x509store_set_trust, 1);
rb_define_method(cX509Store, "time=", ossl_x509store_set_time, 1);
Expand Down Expand Up @@ -973,7 +1084,9 @@ Init_ossl_x509store(void)
rb_define_method(cX509StoreContext, "error_depth", ossl_x509stctx_get_err_depth, 0);
rb_define_method(cX509StoreContext, "current_cert", ossl_x509stctx_get_curr_cert, 0);
rb_define_method(cX509StoreContext, "current_crl", ossl_x509stctx_get_curr_crl, 0);
rb_define_method(cX509StoreContext, "flags", ossl_x509stctx_get_flags, 0);
rb_define_method(cX509StoreContext, "flags=", ossl_x509stctx_set_flags, 1);
rb_define_method(cX509StoreContext, "clear_flags", ossl_x509stctx_clear_flags, -1);
rb_define_method(cX509StoreContext, "purpose=", ossl_x509stctx_set_purpose, 1);
rb_define_method(cX509StoreContext, "trust=", ossl_x509stctx_set_trust, 1);
rb_define_method(cX509StoreContext, "time=", ossl_x509stctx_set_time, 1);
Expand Down
2 changes: 1 addition & 1 deletion gems/bundled_gems
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ ostruct 0.6.3 https://github.com/ruby/ostruct
pstore 0.2.1 https://github.com/ruby/pstore
benchmark 0.5.0 https://github.com/ruby/benchmark
logger 1.7.0 https://github.com/ruby/logger
rdoc 7.2.0 https://github.com/ruby/rdoc 1f93543615928b6d45357432f16ec6006e2d8b1e
rdoc 7.2.0 https://github.com/ruby/rdoc a8df5c5d03b63cf05425bf676644688ac673a329
win32ole 1.9.3 https://github.com/ruby/win32ole
irb 1.18.0 https://github.com/ruby/irb
reline 0.6.3 https://github.com/ruby/reline
Expand Down
10 changes: 5 additions & 5 deletions lib/net/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1550,7 +1550,7 @@ def use_ssl=(flag)
attr_accessor :cert_store

# Sets or returns the available SSL ciphers.
# See {OpenSSL::SSL::SSLContext#ciphers=}[rdoc-ref:OpenSSL::SSL::SSLContext#ciphers-3D].
# See {OpenSSL::SSL::SSLContext#ciphers=}[rdoc-ref:OpenSSL::SSL::SSLContext#ciphers=].
attr_accessor :ciphers

# Sets or returns the extra X509 certificates to be added to the certificate chain.
Expand All @@ -1564,15 +1564,15 @@ def use_ssl=(flag)
attr_accessor :ssl_timeout

# Sets or returns the SSL version.
# See {OpenSSL::SSL::SSLContext#ssl_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#ssl_version-3D].
# See {OpenSSL::SSL::SSLContext#ssl_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#ssl_version=].
attr_accessor :ssl_version

# Sets or returns the minimum SSL version.
# See {OpenSSL::SSL::SSLContext#min_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#min_version-3D].
# See {OpenSSL::SSL::SSLContext#min_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#min_version=].
attr_accessor :min_version

# Sets or returns the maximum SSL version.
# See {OpenSSL::SSL::SSLContext#max_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#max_version-3D].
# See {OpenSSL::SSL::SSLContext#max_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#max_version=].
attr_accessor :max_version

# Sets or returns the callback for the server certification verification.
Expand All @@ -1588,7 +1588,7 @@ def use_ssl=(flag)

# Sets or returns whether to verify that the server certificate is valid
# for the hostname.
# See {OpenSSL::SSL::SSLContext#verify_hostname=}[rdoc-ref:OpenSSL::SSL::SSLContext#attribute-i-verify_hostname].
# See {OpenSSL::SSL::SSLContext#verify_hostname=}[rdoc-ref:OpenSSL::SSL::SSLContext#verify_hostname].
attr_accessor :verify_hostname

# Returns the X509 certificate chain (an array of strings)
Expand Down
67 changes: 67 additions & 0 deletions test/openssl/test_ssl_server.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# frozen_string_literal: true
require_relative "utils"

return unless defined?(OpenSSL::SSL)

class OpenSSL::TestSSLServer < OpenSSL::SSLTestCase
def test_tcpserver
tcps = TCPServer.new("127.0.0.1", 0)
sctx = OpenSSL::SSL::SSLContext.new
sctx.add_certificate(@svr_cert, @svr_key)
server = OpenSSL::SSL::SSLServer.new(tcps, sctx)
assert_same(tcps, server.to_io)
assert_kind_of(String, sctx.session_id_context)
th = Thread.start do
sssl = server.accept
sssl.puts(sssl.gets)
ensure
sssl&.close
end
server_connect(tcps.local_address.ip_port) do |ssl|
assert_equal(@svr_cert.to_der, ssl.peer_cert.to_der)
ssl.puts("abc")
assert_equal("abc\n", ssl.gets)
end
th.join
server.close
assert_predicate(tcps, :closed?)
end

def test_ctx_frozen
tcps = TCPServer.new("127.0.0.1", 0)
sctx = OpenSSL::SSL::SSLContext.new
sctx.add_certificate(@svr_cert, @svr_key)
sctx.setup
server = OpenSSL::SSL::SSLServer.new(tcps, sctx)
assert_nil(sctx.session_id_context)
th = Thread.start do
sssl = server.accept
sssl.puts(sssl.gets)
ensure
sssl&.close
end
server_connect(tcps.local_address.ip_port) do |ssl|
assert_equal(@svr_cert.to_der, ssl.peer_cert.to_der)
ssl.puts("abc")
assert_equal("abc\n", ssl.gets)
end
th.join
server.close
end

private

def server_connect(port, ctx = nil)
sock = TCPSocket.new("127.0.0.1", port)
ssl = ctx ? OpenSSL::SSL::SSLSocket.new(sock, ctx) : OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
ssl.connect
yield ssl if block_given?
ensure
if ssl
ssl.close
elsif sock
sock.close
end
end
end
18 changes: 18 additions & 0 deletions test/openssl/test_x509store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,24 @@ def test_dup
assert_raise(NoMethodError) { ctx.dup }
end

def test_flags_clear
store = OpenSSL::X509::Store.new
assert_equal(0, store.flags)
store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK
assert_equal(OpenSSL::X509::V_FLAG_CRL_CHECK, store.flags)
assert_warning(/clear_flags/) {
store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
}
assert_equal(
OpenSSL::X509::V_FLAG_CRL_CHECK|OpenSSL::X509::V_FLAG_CRL_CHECK_ALL,
store.flags
)
store.clear_flags(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL)
assert_equal(OpenSSL::X509::V_FLAG_CRL_CHECK, store.flags)
store.clear_flags
assert_equal(0, store.flags)
end

def test_ctx_cleanup
# Deprecated in Ruby 1.9.3
cert = OpenSSL::X509::Certificate.new
Expand Down
10 changes: 10 additions & 0 deletions tool/rbs_skip_tests
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,13 @@ test_new(RegexpSingletonTest)
# Errno::ENOENT: No such file or directory - bundle
test_collection_install__pathname_set(RBS::CliTest)
test_collection_install__set_pathname__manifest(RBS::CliTest)

# RBS 4.0.3's RDoc plugin is incompatible with the RDoc 7.2.0 development revision
test_attr_decl_1(RDocPluginParserTest)
test_attr_decl_2(RDocPluginParserTest)
test_instance_method_1(RDocPluginParserTest)
test_instance_method_comment_and_tokens(RDocPluginParserTest)
test_instance_method_generic(RDocPluginParserTest)
test_instance_method_with_block(RDocPluginParserTest)
test_method_alias_decl_1(RDocPluginParserTest)
test_method_alias_decl_2(RDocPluginParserTest)
3 changes: 2 additions & 1 deletion tool/sync_default_gems.rb
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,10 @@ def replace_rdoc_ref(file)
changed |= src.gsub!(%r[\[\Khttps://docs\.ruby-lang\.org/en/master(?:/doc)?/(([A-Z]\w+(?:/[A-Z]\w+)*)|\w+_rdoc)\.html(\#\S+)?(?=\])]) do
name, mod, label = $1, $2, $3
mod &&= mod.gsub('/', '::')
if label && (m = label.match(/\A\#(?:method-([ci])|(?:(?:class|module)-#{mod}-)?label)-([-+\w]+)\z/))
if label && (m = label.match(/\A\#(?:(?:method|attribute)-([ci])|(?:(?:class|module)-#{mod}-)?label)-(.+)\z/))
scope, label = m[1], m[2]
scope = scope ? scope.tr('ci', '.#') : '@'
label.gsub!(/-(\h\h)/) {$1.to_i(16).chr(Encoding::ASCII_8BIT)}
end
"rdoc-ref:#{mod || name.chomp("_rdoc") + ".rdoc"}#{scope}#{label}"
end
Expand Down
4 changes: 2 additions & 2 deletions zjit/src/invariants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,10 +374,10 @@ pub extern "C" fn rb_zjit_constant_state_changed(id: ID) {
let invariants = ZJITState::get_invariants();
if let Some(patch_points) = invariants.constant_state_patch_points.remove(&id) {
let cb = ZJITState::get_code_block();
debug!("Constant state changed: {:?}", id);
debug!("Constant state changed: {id:?}: {}", id.contents_lossy());

// Invalidate all patch points for this constant ID
compile_patch_points!(cb, patch_points, Const, "Constant state changed: {:?}", id);
compile_patch_points!(cb, patch_points, Const, "Constant state changed: {id:?}: {}", id.contents_lossy());

cb.mark_all_executable();
}
Expand Down