aboutsummaryrefslogtreecommitdiffstats
path: root/lib/bundler/ssl_certs/certificate_manager.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bundler/ssl_certs/certificate_manager.rb')
-rw-r--r--lib/bundler/ssl_certs/certificate_manager.rb65
1 files changed, 65 insertions, 0 deletions
diff --git a/lib/bundler/ssl_certs/certificate_manager.rb b/lib/bundler/ssl_certs/certificate_manager.rb
new file mode 100644
index 0000000000..a5e5d84b64
--- /dev/null
+++ b/lib/bundler/ssl_certs/certificate_manager.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+require "fileutils"
+require "net/https"
+require "openssl"
+
+module Bundler
+ module SSLCerts
+ class CertificateManager
+ attr_reader :bundler_cert_path, :bundler_certs, :rubygems_certs
+
+ def self.update_from!(rubygems_path)
+ new(rubygems_path).update!
+ end
+
+ def initialize(rubygems_path = nil)
+ if rubygems_path
+ rubygems_cert_path = File.join(rubygems_path, "lib/rubygems/ssl_certs")
+ @rubygems_certs = certificates_in(rubygems_cert_path)
+ end
+
+ @bundler_cert_path = File.expand_path("..", __FILE__)
+ @bundler_certs = certificates_in(bundler_cert_path)
+ end
+
+ def up_to_date?
+ rubygems_certs.all? do |rc|
+ bundler_certs.find do |bc|
+ File.basename(bc) == File.basename(rc) && FileUtils.compare_file(bc, rc)
+ end
+ end
+ end
+
+ def update!
+ return if up_to_date?
+
+ FileUtils.rm bundler_certs
+ FileUtils.cp rubygems_certs, bundler_cert_path
+ end
+
+ def connect_to(host)
+ http = Net::HTTP.new(host, 443)
+ http.use_ssl = true
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
+ http.cert_store = store
+ http.head("/")
+ end
+
+ private
+
+ def certificates_in(path)
+ Dir[File.join(path, "**/*.pem")].sort
+ end
+
+ def store
+ @store ||= begin
+ store = OpenSSL::X509::Store.new
+ bundler_certs.each do |cert|
+ store.add_file cert
+ end
+ store
+ end
+ end
+ end
+ end
+end