Fixes 2 SSL usage problems of RemoteFetcher.
- No verification
- Follows HTTPS -> HTTP redirection
For the first problem, RemoteFetcher must use OpenSSL::SSL::VERIFY_PEER
instead of VERIFY_NONE. And to enable SSL verification of
RemoteFetcher, we need to make trusted CA configurable. This commit
adds :ssl_verify_mode and :ssl_ca_cert to Gem::ConfigFile (normally
.gemrc). Both configurations are treated as same options in open-uri.
When :ssl_ca_cert is set, only the given path is treated as the trusted
CA certificate(s). If it's not set, OpenSSL's default store (sometimes
configured as /etc/ssl/certs by system) *AND*
lib/rubygems/ssl_certs/*.pem are trusted. lib/rubygems/ssl_certs/*.pem
are shipped to make sure all RubyGems clients can successfully access to
https://rubygems.org/.
At this moment, RubyGems.org uses 3 SSL servers (https://rubygems.org/,
https://s3.amazon.com/, and https://d2chzxaqi4y7f8.cloudfront.net/) and
each SSL certificate needs different root CA certificate. So
lib/rubygems/ssl_certs/ directory has 3 CA certificates in it.
For the second problem, this patch let RemoteFetcher raises
RemoteFetcher::FetchError if a server returns HTTPS -> HTTP redirection.
Other type of redirection, HTTP -> HTTP, HTTPS -> HTTPS and HTTP ->
HTTPS are allowed as before like open-uri.rb
The second issue is rather harmless because RemoteFetcher does not send
Cookie nor Referer to the server (Those resources for HTTPS site must
not be sent to HTTP site.) However, by following HTTPS -> HTTP
redirection, an attacker can inject malicious gem contents into the
user's environment who expected secure content download from HTTPS site
by using HTTPS repository.

This comment has been minimized.

I installed Ruby 1.9.3p194. I expected the certs supplied with the Ruby install would override any included with my older OpenSSL but it appears they didn't. Still mystified as to why I needed to upgrade OpenSSL to resolve the issue.

I installed Ruby 1.9.3p194. I expected the certs supplied with the Ruby install would override any included with my older OpenSSL but it appears they didn't. Still mystified as to why I needed to upgrade OpenSSL to resolve the issue.