Skip to content

Commit

Permalink
Include "additional data" message in OpenSSL errors
Browse files Browse the repository at this point in the history
Error entries in the OpenSSL error queue may contain additional
contextual information associated with the error, which can be helpful
when debugging.

This "additional data" is currently only printed to stderr when
OpenSSL.debug is enabled. Let's include this in the exception messages
raised with ossl_raise(), too.

	$ ruby -Ilib -ropenssl -e'OpenSSL.debug=true; OpenSSL::SSL::SSLContext.new.ecdh_curves="P-256:not-a-curve"'
	-e:1: warning: error on stack: error:0A080106:SSL routines:gid_cb:passed invalid argument (group 'not-a-curve' cannot be set)
	-e:1:in `ecdh_curves=': passed invalid argument (group 'not-a-curve' cannot be set) (OpenSSL::SSL::SSLError)
		from -e:1:in `<main>'
  • Loading branch information
rhenium committed Jul 1, 2023
1 parent 9871d39 commit 0b44ad4
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 12 deletions.
29 changes: 17 additions & 12 deletions ext/openssl/ossl.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,23 +272,28 @@ VALUE
ossl_make_error(VALUE exc, VALUE str)
{
unsigned long e;
const char *data;
int flags;

e = ERR_peek_last_error();
if (NIL_P(str))
str = rb_str_new(NULL, 0);

#ifdef HAVE_ERR_GET_ERROR_ALL
e = ERR_peek_last_error_all(NULL, NULL, NULL, &data, &flags);
#else
e = ERR_peek_last_error_line_data(NULL, NULL, &data, &flags);
#endif
if (e) {
const char *msg = ERR_reason_error_string(e);
const char *msg = ERR_reason_error_string(e);

if (NIL_P(str)) {
if (msg) str = rb_str_new_cstr(msg);
}
else {
if (RSTRING_LEN(str)) rb_str_cat2(str, ": ");
rb_str_cat2(str, msg ? msg : "(null)");
}
ossl_clear_error();
if (RSTRING_LEN(str)) rb_str_cat_cstr(str, ": ");
rb_str_cat_cstr(str, msg ? msg : "(null)");
if (flags & ERR_TXT_STRING && data)
rb_str_catf(str, " (%s)", data);
ossl_clear_error();
}

if (NIL_P(str)) str = rb_str_new(0, 0);
return rb_exc_new3(exc, str);
return rb_exc_new_str(exc, str);
}

void
Expand Down
12 changes: 12 additions & 0 deletions test/openssl/test_ossl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ def test_memcmp_timing
assert_operator(a_b_time, :<, a_c_time * 10, "fixed_length_secure_compare timing test failed")
assert_operator(a_c_time, :<, a_b_time * 10, "fixed_length_secure_compare timing test failed")
end

def test_error_data
# SSL_CTX_set1_curves_list() is a function that puts additional context to
# the error queue using ERR_raise_data(). Ensure that the text is
# automatically included in the exception message.
return unless defined?(OpenSSL::SSL)
ctx = OpenSSL::SSL::SSLContext.new
# OpenSSL 3.1: "passed invalid argument (group 'not-a-curve' cannot be set)"
assert_raise_with_message(OpenSSL::SSL::SSLError, /passed invalid argument \(.*not-a-curve.*\)/) {
ctx.ecdh_curves = "P-256:not-a-curve"
}
end
end

end

0 comments on commit 0b44ad4

Please sign in to comment.