Take the 2-minute tour ×
Ask Different is a question and answer site for power users of Apple hardware and software. It's 100% free, no registration required.

I am trying to find out where Ruby expects to find its openssl CA list. My environment is:

Confirmation that my Ruby is using homebrew OpenSSL (note: /Users/me is a redacted version of the user directory in all examples below):

$ otool -L /Users/me/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/x86_64-darwin11.4.2/openssl.bundle
/Users/me/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/x86_64-darwin11.4.2/openssl.bundle:
        /usr/local/opt/openssl/lib/libssl.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
        /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
        /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)

To test, I have written the following script:

#!/usr/bin/env ruby
require 'net/https'
https = Net::HTTP.new('encrypted.google.com', 443)
https.use_ssl = true
https.verify_mode = OpenSSL::SSL::VERIFY_PEER
https.request_get('/')
puts 'success!'

If I manually specify the path to my SSL_CERT_FILE, it works:

$ SSL_CERT_FILE=/Users/me/.rbenv/versions/1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/ssl_certs/ca-bundle.pem ./test_ssl.rb 
success!

If not, it breaks:

$ ./test_ssl.rb 
/Users/me/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/net/http.rb:799:in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)
        from /Users/me/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/net/http.rb:799:in `block in connect'
        from /Users/me/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/timeout.rb:54:in `timeout'
        from /Users/me/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/timeout.rb:99:in `timeout'
        from /Users/me/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/net/http.rb:799:in `connect'
        from /Users/me/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/net/http.rb:755:in `do_start'
        from /Users/me/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/net/http.rb:744:in `start'
        from /Users/me/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/net/http.rb:1284:in `request'
        from /Users/me/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/net/http.rb:1195:in `request_get'
        from ./test_ssl.rb:6:in `<main>'

As an aside, I am already aware that I could manually check various paths for the CA file from my script. However the script is a test of similar net/http operations within Ruby gem "faraday" on my system. I do not want to hack the faraday gem to work around this problem.

So I used dtruss to look for stat commands and see if any of them are attempted CA file lookups:

$ sudo dtruss -f -t stat64 ./test_ssl.rb
        PID/THRD  SYSCALL(args)                  = return
96741/0x6b4be4:  stat64("/usr/lib/dtrace/libdtrace_dyld.dylib\0", 0x7FFF6A9BE810, 0x7FFF6A9BF700)                = 0 0
96741/0x6b4be4:  stat64("/usr/lib/libSystem.B.dylib\0", 0x7FFF6A9BE650, 0x7FFF6A9BF4D0)          = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libcache.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)              = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libcommonCrypto.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)               = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libcompiler_rt.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)                = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libcopyfile.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)           = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libdispatch.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)           = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libdnsinfo.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)            = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libdyld.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)               = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libkeymgr.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)             = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/liblaunch.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)             = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libmacho.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)              = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libmathCommon.A.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)               = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libquarantine.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)                 = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libremovefile.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)                 = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libsystem_blocks.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)              = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libsystem_c.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)           = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libsystem_dnssd.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)               = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libsystem_info.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)                = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libsystem_kernel.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)              = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libsystem_network.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)             = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libsystem_notify.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)              = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libsystem_sandbox.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)             = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libunc.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)                = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libunwind.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)             = 0 0
96741/0x6b4be4:  stat64("/usr/lib/system/libxpc.dylib\0", 0x7FFF6A9BE350, 0x7FFF6A9BF1D0)                = 0 0
96741/0x6b4be4:  stat64("/AppleInternal\0", 0x7FFF6A9BEFF8, 0x0)                 = -1 Err#2
96741/0x6b4be4:  stat64("/usr/lib/libstdc++.6.dylib\0", 0x7FFF6A9BE640, 0x7FFF6A9BF4C0)          = 0 0
96741/0x6b4be4:  stat64("/usr/lib/libc++abi.dylib\0", 0x7FFF6A9BE550, 0x7FFF6A9BF3D0)            = 0 0

None of the file stats look like a CA file lookup! Am I using dtruss correctly? Is there some other way for me to find out where the CA certificates file should be placed?

share|improve this question
    
I hate to send you elsewhere, but this should get re-asked on the main ruby programming site IMO. stackoverflow.com I don't see any Mac specific items other than that you got the packages using homebrew. Let me know if I can help refine your post on SO. –  bmike Apr 5 '13 at 12:59
    
@bmike This is a Mac-specific question due to the debugging techniques used. On Linux I would use "strace" and find out what files were being looked for but not found. On Mac I tried to use dtruss the same way but failed. Also, on a stock Linux Ruby I'm guessing this problem won't happen due to tighter integration between SSL and Ruby packages. So this again points to a Mac-specific/Homebrew problem. Thus I don't see any other SO sites that would be as suitable for this question as the Mac site. –  EdwardTeach Apr 5 '13 at 13:22
    
You are totally right. I was confusing dtruss with dtrace - I need more coffee (and potentially more sleep) apparently. Let me bounty this up to see if we can attract more eyes to your dilemma. –  bmike Apr 5 '13 at 13:31
    
@EdwardTeach - Are you still using the SSL_CERT_DIR environment variable as a workaround? –  pingu Nov 3 '13 at 20:22
    
@pingu Yep I'm still using this workaround; no solution yet. –  EdwardTeach Nov 8 '13 at 3:42
add comment

2 Answers 2

I experienced the same problem under Ubuntu. There seems no longer to be a compiled in default (if it ever had, in theory it could also have been the distributors' work).

I opted to set the path in apache config (my rails app is controlled by passenger).

SetEnv SSL_CERT_DIR /usr/share/ca-certificates/mozilla

It now works.

There is also an SSL_CERT_FILE for a single certificate.

You have to adjust the paths.

Just check the main pages, and this page. Even line 4 over here says so: https://github.com/google/signet/blob/master/lib/signet/ssl_config.rb

I could also have set the path system-wide in /etc/environment and restarted the system.

share|improve this answer
1  
Thanks, but this is for a command-line application and not for Rails. So Apache is not in play. I am currently using the "SSL_CERT_DIR" environment variable as a workaround, though I would rather put the certificate file whereever it is that Ruby expects to find it. Which leads to the question: where does Ruby expect to find it? I can't seem to figure that out. –  EdwardTeach Jan 4 '13 at 17:51
add comment

Although I don't figure out where ruby expects to find it, you may want to try and add

export SSL_CERT_FILE=/Users/me/.rbenv/versions/1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/ssl_certs/ca-bundle.pem

to ~/.bash_profile to make it work with the command line tools (note the 'export' in front of SSL_CERT_FILE, on Windows systems (off topic, I know) this would be 'set')

share|improve this answer
    
I would like something more robust than setting environment variables, thus the question. –  EdwardTeach Mar 5 '13 at 23:32
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.