[ruby/openssl] Include "additional data" message in OpenSSL errors

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>'

https://github.com/ruby/openssl/commit/1c5bbdd68e
This commit is contained in:
Kazuki Yamaguchi 2023-07-01 21:53:38 +09:00
Родитель 382b42be94
Коммит 12bdacdca5
2 изменённых файлов: 29 добавлений и 12 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -60,6 +60,18 @@ class OpenSSL::OSSL < OpenSSL::SSLTestCase
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
# X509V3_EXT_nconf_nid() called from OpenSSL::X509::ExtensionFactory#create_ext is a function
# that uses ERR_raise_data() to append additional information about the error.
#
# The generated message should look like:
# "subjectAltName = IP:not.a.valid.ip.address: bad ip address (value=not.a.valid.ip.address)"
ef = OpenSSL::X509::ExtensionFactory.new
assert_raise_with_message(OpenSSL::X509::ExtensionError, /\(value=not.a.valid.ip.address\)/) {
ef.create_ext("subjectAltName", "IP:not.a.valid.ip.address")
}
end
end
end