Where and when does OpenSSL::OPENSSL_VERSION_NUMBER
get set? And why isn't it getting set to the latest OpenSSL that I've just installed?
First the error(s):
$ gem install activesupport -v '3.2.13'
Error while executing gem ... (RuntimeError)
Unsupported digest algorithm (SHA512)
If I go directly into irb, I can see that Ruby is using the "old" openssl:
$ irb
>> require 'openssl'
=> true
>> OpenSSL::Digest.new('sha512')
RuntimeError: Unsupported digest algorithm (sha512)
>> OpenSSL::OPENSSL_VERSION_NUMBER.to_s(16)
"9070cf"
This tells me that Ruby isn't finding the local version of OpenSSL that I just built, which should be at least 0x908000. The relevant code:
# file: usr/lib/ruby/2.0.0/openssl/digest.rb
...
alg = %w(DSS DSS1 MD2 MD4 MD5 MDC2 RIPEMD160 SHA SHA1)
if OPENSSL_VERSION_NUMBER > 0x00908000
alg += %w(SHA224 SHA256 SHA384 SHA512)
end
explains why it's not finding SHA512.
But I don't know why Ruby is using the old version of OpenSSL. I built OpenSSL and Ruby from fresh sources using
SANDBOX=/Users/me/sandboxes/ruby2
PATH=$(SANDBOX)/usr/bin:$(PATH)
# Create a fresh OpenSSL from sources
(downloaded and unpacked http://www.openssl.org/source/openssl-1.0.1e.tar.gz)
$ ./config --prefix=$(SANDBOX)/usr --openssldir=$(SANDBOX)/usr/openssl
$ make ; make install ; make clean
# verify openssl
$ which openssl
/Users/me/sandboxes/ruby2/usr/bin/openssl
$ openssl version
OpenSSL 1.0.1e 11 Feb 2013
# Create a fresh Ruby from sources
(download and unpack http://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p0.tar.gz)
$ ./configure --prefix=$(SANDBOX)/usr --with-open-ssl-dir=$(SANDBOX)/usr/openssl
$ make ; make intalll ; make clean
# verify ruby
$ which ruby
/Users/me/sandboxes/ruby2/usr/bin/ruby
But this ruby doesn't appear to find the openssl 1.0.1e that I just built.
My understanding was that the --with-open-ssl-dir
argument to ./configure
was necessary and sufficient to tell ruby to use the new OpenSSL, but that didn't seem to work.
Any ideas on how to get Ruby to recognize the new OpenSSL that I've built?
I've tried running ruby extconf.rb ; make ; make install
as suggested by @Gaurish (below), but that still finds the OpenSSL installed in the system, not in my project root directory.
When OpenSSL changes, always recompile Ruby or the openssl native extension.
Ruby compiles the OpenSSL version into the openssl native extension, even when it links to a shared OpenSSL library. Either reinstall Ruby or recompile the openssl extension to fix it.
$ ruby -ropenssl -e'puts OpenSSL::OPENSSL_VERSION'
OpenSSL 1.0.2e 3 Dec 2015
$ /usr/local/opt/openssl/bin/openssl version
OpenSSL 1.0.2g 1 Mar 2016
$ strings {{redacted}/ruby-2.3.0/lib/ruby/2.3.0/x86_64-darwin15/openssl.bundle | grep '1.0.2'
OpenSSL 1.0.2e 3 Dec 2015
$ otool -L {{redacted}}/ruby-2.3.0/lib/ruby/2.3.0/x86_64-darwin15/openssl.bundle
{{redacted}}/ruby-2.3.0/lib/ruby/2.3.0/x86_64-darwin15/openssl.bundle:
{{redacted}}/ruby-2.3.0/lib/libruby.2.3.0.dylib (compatibility version 2.3.0, current version 2.3.0)
/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/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
/usr/local/opt/gmp/lib/libgmp.10.dylib (compatibility version 14.0.0, current version 14.0.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
We use ruby-install and chruby. Instead of /opt/rubies
, we use /usr/local/rubies
to avoid sudo
. You can also sudo ln -s /usr/local/rubies /opt/rubies
if you don't want to bother setting RUBIES
for chruby.
brew install openssl && \
ruby-install ruby-2.3.0 \
--no-install-deps \
-- \
--without-X11 \
--without-tk \
--enable-shared \
--disable-install-doc \
--with-openssl-dir="$(brew --prefix openssl)"
There's yet another constant which is derived from the actual, loaded OpenSSL library.
OpenSSL::OPENSSL_LIBRARY_VERSION