aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2017-07-11 13:25:24 +0900
committerKazuki Yamaguchi <k@rhe.jp>2017-07-11 13:25:24 +0900
commitf842b0d5c5e37527c11954a4b7a98c8d9cc57865 (patch)
tree1c345fa973ce505512d3707fa8738be8c30f93ec
parent3af2635f117f8da563d180bc1c58702aecb16e0c (diff)
downloadruby-openssl-f842b0d5c5e37527c11954a4b7a98c8d9cc57865.tar.gz
bio: do not use the FILE BIO method in ossl_obj2bio()
Read everything from an IO object into a String first and use the memory buffer BIO method just as we do for String inputs. For MSVC builds, the FILE BIO method uses the "UPLINK" interface that requires the application to provide OPENSSL_Applink() function. For us, the "application" means ruby.exe, in which we can't do anything. As a workaround, avoid using the FILE BIO method at all. Usually private keys or X.509 certificates aren't that large and the temporarily increased memory usage hopefully won't be an issue. Fixes: https://github.com/ruby/openssl/issues/128
-rw-r--r--ext/openssl/ossl_bio.c32
-rw-r--r--test/test_x509cert.rb9
2 files changed, 15 insertions, 26 deletions
diff --git a/ext/openssl/ossl_bio.c b/ext/openssl/ossl_bio.c
index ae46ac43..8fa0b696 100644
--- a/ext/openssl/ossl_bio.c
+++ b/ext/openssl/ossl_bio.c
@@ -15,32 +15,12 @@ ossl_obj2bio(volatile VALUE *pobj)
VALUE obj = *pobj;
BIO *bio;
- if (RB_TYPE_P(obj, T_FILE)) {
- rb_io_t *fptr;
- FILE *fp;
- int fd;
-
- GetOpenFile(obj, fptr);
- rb_io_check_readable(fptr);
- if ((fd = rb_cloexec_dup(FPTR_TO_FD(fptr))) < 0){
- rb_sys_fail(0);
- }
- rb_update_max_fd(fd);
- if (!(fp = fdopen(fd, "r"))){
- int e = errno;
- close(fd);
- rb_syserr_fail(e, 0);
- }
- if (!(bio = BIO_new_fp(fp, BIO_CLOSE))){
- fclose(fp);
- ossl_raise(eOSSLError, NULL);
- }
- }
- else {
- StringValue(obj);
- bio = BIO_new_mem_buf(RSTRING_PTR(obj), RSTRING_LENINT(obj));
- if (!bio) ossl_raise(eOSSLError, NULL);
- }
+ if (RB_TYPE_P(obj, T_FILE))
+ obj = rb_funcallv(obj, rb_intern("read"), 0, NULL);
+ StringValue(obj);
+ bio = BIO_new_mem_buf(RSTRING_PTR(obj), RSTRING_LENINT(obj));
+ if (!bio)
+ ossl_raise(eOSSLError, "BIO_new_mem_buf");
*pobj = obj;
return bio;
}
diff --git a/test/test_x509cert.rb b/test/test_x509cert.rb
index 0cfe4402..5b2e712d 100644
--- a/test/test_x509cert.rb
+++ b/test/test_x509cert.rb
@@ -178,6 +178,15 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
assert_equal(true, cert.check_private_key(@rsa2048))
end
+ def test_read_from_file
+ cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil)
+ Tempfile.create("cert") { |f|
+ f << cert.to_pem
+ f.rewind
+ assert_equal cert.to_der, OpenSSL::X509::Certificate.new(f).to_der
+ }
+ end
+
private
def certificate_error_returns_false