-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
update_bundled_ca_certificates.rb
119 lines (91 loc) · 2.39 KB
/
update_bundled_ca_certificates.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# frozen_string_literal: true
require 'net/http'
require 'openssl'
URIS = [
URI('https://rubygems.org'),
URI('https://staging.rubygems.org'),
URI('https://s3.amazonaws.com'),
URI('https://fastly.rubygems.org'),
URI('https://rubygems.global.ssl.fastly.net'),
]
def connect_to uri, store
# None of the URIs are IPv6, so URI::Generic#hostname(ruby 1.9.3+) isn't needed
http = Net::HTTP.new uri.host, uri.port
http.use_ssl = uri.scheme.downcase == 'https'
http.ssl_version = :TLSv1_2
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.cert_store = store
http.get '/'
true
rescue OpenSSL::SSL::SSLError
false
end
def load_certificates io
cert_texts =
io.read.scan(/^-{5}BEGIN CERTIFICATE-{5}.*?^-{5}END CERTIFICATE-{5}/m)
cert_texts.map do |cert_text|
OpenSSL::X509::Certificate.new cert_text
end
end
def show_certificates certificates
certificates.each do |certificate|
p certificate.subject.to_a
end
end
def store_for certificates
store = OpenSSL::X509::Store.new
certificates.each do |certificate|
store.add_cert certificate
end
store
end
def test_certificates certificates, uri
1.upto certificates.length do |n|
puts "combinations of #{n} certificates"
certificates.combination(n).each do |combination|
match = test_uri uri, combination
if match then
$needed_combinations << match
puts
puts match.map { |certificate| certificate.subject }
return
else
print '.'
end
end
puts
end
end
def test_uri uri, certificates
store = store_for certificates
verified = connect_to uri, store
return certificates if verified
nil
end
def write_certificates certificates
certificates.each do |certificate|
subject = certificate.subject.to_a
name = (subject.assoc('CN') || subject.assoc('OU'))[1]
name = name.delete ' .-'
destination = "lib/rubygems/ssl_certs/#{name}.pem"
warn "overwriting certificate #{name}" if File.exist? destination
open destination, 'w' do |io|
io.write certificate.to_pem
end
end
end
io =
if ARGV.empty? then
open OpenSSL::X509::DEFAULT_CERT_FILE
else
ARGF
end
certificates = load_certificates io
puts "loaded #{certificates.length} certificates"
$needed_combinations = []
URIS.each do |uri|
puts uri
test_certificates certificates, uri
end
needed = $needed_combinations.flatten.uniq
write_certificates needed