aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2023-07-01 21:53:38 +0900
committerKazuki Yamaguchi <k@rhe.jp>2023-08-11 02:15:54 +0900
commit1c5bbdd68e902ca34f9a8cc4218babd5ebfc3a8c (patch)
treeabf345a656398548829454ee39f4bd966de6f476
parentfd6f76c0d306cb96d9d5fd0792a844cd6b65140a (diff)
downloadruby-openssl-ky/error-additional-data.tar.gz
Include "additional data" message in OpenSSL errorsky/error-additional-data
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>'
-rw-r--r--ext/openssl/ossl.c29
-rw-r--r--test/openssl/test_ossl.rb12
2 files changed, 29 insertions, 12 deletions
diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c
index e67832d4..1abc3882 100644
--- a/ext/openssl/ossl.c
+++ b/ext/openssl/ossl.c
@@ -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
diff --git a/test/openssl/test_ossl.rb b/test/openssl/test_ossl.rb
index e1d86bd4..5759c75b 100644
--- a/test/openssl/test_ossl.rb
+++ b/test/openssl/test_ossl.rb
@@ -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