aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--ext/openssl/ossl.c17
-rw-r--r--test/openssl/test_pkey_rsa.rb11
3 files changed, 40 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 918a9d10ad..fbefe7a993 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+Tue Dec 20 15:04:18 2011 Hiroshi Nakamura <nahi@ruby-lang.org>
+
+ * Make sure to clear $! when ignoring an exception
+
+ * ext/openssl/ossl.c (ossl_pem_passwd_cb0, ossl_verify_cb):
+ pem_passwd_cb and verify_cb ignores the exception raised in a
+ callback proc so it should clear $! for subsequent execution.
+
+ That's said, both subsequent processes for pem_passwd_cb and
+ verify_cb raises another exception before leaking $! to Ruby world.
+ We cannot test this fix in Ruby land.
+
+ * test/openssl/test_pkey_rsa.rb
+ (test_read_private_key_pem_pw_exception): Test for pem_passwd_cb +
+ exception.
+
Tue Dec 20 11:49:13 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>
* test/date/test_date_base.rb (test_jd): tests for
diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c
index f3410b64e8..7c8507050c 100644
--- a/ext/openssl/ossl.c
+++ b/ext/openssl/ossl.c
@@ -175,7 +175,11 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd)
*/
rflag = flag ? Qtrue : Qfalse;
pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status);
- if (status) return -1; /* exception was raised. */
+ if (status) {
+ /* ignore an exception raised. */
+ rb_set_errinfo(Qnil);
+ return -1;
+ }
len = RSTRING_LENINT(pass);
if (len < 4) { /* 4 is OpenSSL hardcoded limit */
rb_warning("password must be longer than 4 bytes");
@@ -216,18 +220,23 @@ ossl_verify_cb(int ok, X509_STORE_CTX *ctx)
if ((void*)proc == 0)
return ok;
if (!NIL_P(proc)) {
+ ret = Qfalse;
rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new,
(VALUE)ctx, &state);
- ret = Qfalse;
- if (!state) {
+ if (state) {
+ rb_set_errinfo(Qnil);
+ rb_warn("StoreContext initialization failure");
+ }
+ else {
args.proc = proc;
args.preverify_ok = ok ? Qtrue : Qfalse;
args.store_ctx = rctx;
ret = rb_protect((VALUE(*)(VALUE))ossl_call_verify_cb_proc, (VALUE)&args, &state);
- ossl_x509stctx_clear_ptr(rctx);
if (state) {
+ rb_set_errinfo(Qnil);
rb_warn("exception in verify_callback is ignored");
}
+ ossl_x509stctx_clear_ptr(rctx);
}
if (ret == Qtrue) {
X509_STORE_CTX_set_error(ctx, X509_V_OK);
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
index b7da0ca427..815f49b61e 100644
--- a/test/openssl/test_pkey_rsa.rb
+++ b/test/openssl/test_pkey_rsa.rb
@@ -233,6 +233,17 @@ AwEAAQ==
assert_equal([], OpenSSL.errors)
end
+ def test_read_private_key_pem_pw_exception
+ pem = OpenSSL::TestUtils::TEST_KEY_RSA1024.to_pem(OpenSSL::Cipher.new('AES-128-CBC'), 'secret')
+ # it raises an ArgumentError from PEM reading. The exception raised inside are ignored for now.
+ assert_raise(ArgumentError) do
+ OpenSSL::PKey.read(pem) do
+ raise RuntimeError
+ end
+ end
+ assert_equal([], OpenSSL.errors)
+ end
+
private
def check_PUBKEY(asn1, key)