On most unix system there is an application called dtrace which will tell you all the system calls made in real time, and it can filter on filesystem operations. So to cut a long story short, here's a simple guide to figuring out the CA file used by your openssl library.
- Start dtrace on filesystem calls and save the output into a file
- sudo dtrace -n 'syscall::open*:entry { printf("%s %s", execname, copyinstr(arg0))}' > dtrace.out
- Run the application which searches for does the CA lookup on the filesystem, this can be done in another terminal session.
- Grep the output file (dtrace.out) for the application name, and read the path
- cat dtrace.out | grep ruby
The result of my problem was /Users/[Username]/.rvm/gems/ruby-1.9.2-p320/gems/active_utils-1.0.5/lib/active_utils/common/../../certs/cacert.pem
The problem I was having and probably the reason why the answer was not immediately clear to me, is that I am using Active Merchant without rails, and therefore I was never aware that calls to OpenSSL would be managed by Active Utils, and use a gem specific CA certificate file. Now to all you people out there using Active Merchant, be aware that the CA certificate file is NOT based on your rvm of system installation of OpenSSL.
Thanks to #ruby , #unix and #rvm on freenode for help and inspiration. Special thanks to mpapis.
and how I wrongfully accused rvm of handling openssl certificates wrong.
Today I had the joy of debugging the content of an interaction wrapped in ssl. The problem here is of course that the application making a connection to an external server trusts the server based on the certificated supplied by the server and a chain of trust from the root certificate used by the application and to the server. These root certificates are placed in a certificate authority file. If you are in the business of snooping, a well known technique is a man-in-the-middle-attack where you place a proxy in between the start and the end point of the communication, but the certificates defeat this since the chain of trust if broken by the man in the middle who will be using a different certificate than the endpoint in order to decrypt the data send from the startpoint against the public key of the endpoint.
To overcome this problem the Charles Proxy lets you take their fake CA certificate and give it to the application which will then trust the certificate Charles issues as a man in the middle, in other words, because the application is using a fake CA certificate the security is now defeated, so be aware of what CA certificates you trust yourself.
In order to redirect traffic to Charles or any other proxy I can highly recommend proxychains.
I spend too long time today figuring out the path where my application would look for the CA file, so that I could inject the fake Charles certificate into it and listen in on the traffic. I even went to #rvm on freenode, in the belief that their integration of openssl into rvm was the cause of my problems. This is a fair assumption as rvm will compile its own version of openssl and ruby instances will use that binary and also that configuration file and CA certificate. So I was injecting the Charles certificate into the openssl rvm CA certificate under ~/.rvm/usr/ssl/cert.pem but with no luck. I also tried /etc/ssl, /opt/local/openssl and many other known paths untill I realised the solution.