sslsmart 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE.txt +45 -0
- data/README +5 -0
- data/bin/fs_icon_32.ico +0 -0
- data/bin/resultcontainer.rb +11 -0
- data/bin/rootcerts.pem +3509 -0
- data/bin/sslsmartconfig.rb +177 -0
- data/bin/sslsmartcontroller.rb +351 -0
- data/bin/sslsmartdb.rb +151 -0
- data/bin/sslsmartgui.rb +888 -0
- data/bin/sslsmartlib.rb +287 -0
- data/bin/sslsmartlog.rb +35 -0
- data/bin/sslsmartmisc.rb +50 -0
- data/sample.rb +19 -0
- data/sslsmart.gemspec +20 -0
- metadata +110 -0
@@ -0,0 +1,177 @@
|
|
1
|
+
# Gursev Singh Kalra @ Foundstone(McAfee)
|
2
|
+
# Please see LICENSE.txt for licensing information
|
3
|
+
|
4
|
+
require 'singleton'
|
5
|
+
require 'sslsmartlib'
|
6
|
+
require 'sslsmartlog'
|
7
|
+
|
8
|
+
$log = SSLSmartLog.instance
|
9
|
+
|
10
|
+
class CipherSuite
|
11
|
+
def initialize(version, name, bits)
|
12
|
+
@test = true
|
13
|
+
@version = version
|
14
|
+
@name = name
|
15
|
+
@bits = bits
|
16
|
+
end
|
17
|
+
|
18
|
+
def test=(val)
|
19
|
+
case val
|
20
|
+
when true, false
|
21
|
+
@test = val
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def test?
|
26
|
+
@test
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
"test = #{@test}\tversion = #{@version}\tbits = #{@bits}\tname = #{@name}"
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# Sort with version, bits and then name
|
35
|
+
def <=>(obj)
|
36
|
+
if((version <=>obj.version) == 0)
|
37
|
+
if((bitcomp = (obj.bits.to_i <=> bits.to_i)) == 0)
|
38
|
+
return name <=> obj.name
|
39
|
+
else
|
40
|
+
return bitcomp
|
41
|
+
end
|
42
|
+
else
|
43
|
+
version <=> obj.version
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def +(cs)
|
48
|
+
@bits = "--"
|
49
|
+
@name = @name + ":" + cs.name
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
attr_reader :version, :name, :bits, :test
|
54
|
+
end
|
55
|
+
|
56
|
+
class SSLSmartConfig
|
57
|
+
SCAN_TYPES = ["Connect", "Content"]
|
58
|
+
SCAN_MODES = ["Test Individual Ciphers", "SSL Version Check (Faster)"]
|
59
|
+
include Singleton
|
60
|
+
|
61
|
+
def initialize
|
62
|
+
@urls = []
|
63
|
+
@cipher_suites = []
|
64
|
+
@sslv2 = true
|
65
|
+
@sslv3 = true
|
66
|
+
@tlsv1 = true
|
67
|
+
@scan_type = SCAN_TYPES[1] # Content or Connect
|
68
|
+
@scan_mode = SCAN_MODES[0] # Cipher or version check
|
69
|
+
@proxy_add = nil
|
70
|
+
@proxy_port = nil
|
71
|
+
@rootcert_path = File.join(File.expand_path("."), "rootcerts.pem")
|
72
|
+
@filter = nil
|
73
|
+
end
|
74
|
+
|
75
|
+
attr_reader :urls, :cipher_suites, :sslv2, :sslv3, :tlsv1, :scan_type, :proxy_add, :proxy_port, :rootcert_path, :filter, :scan_mode
|
76
|
+
attr_writer :cipher_suites
|
77
|
+
|
78
|
+
def update_test_status(cs)
|
79
|
+
case cs.version
|
80
|
+
when "SSLv2"
|
81
|
+
cs.test = @sslv2
|
82
|
+
when "SSLv3"
|
83
|
+
cs.test = @sslv3
|
84
|
+
when "TLSv1"
|
85
|
+
cs.test = @tlsv1
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def update_version_test_status()
|
90
|
+
@cipher_suites.each do |cs|
|
91
|
+
update_test_status(cs)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def index_for_version(version)
|
96
|
+
@cipher_suites.each_with_index do |x, index|
|
97
|
+
return index if(x.version == version)
|
98
|
+
end
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
|
102
|
+
def update_config(config_hash)
|
103
|
+
return unless(config_hash.class == Hash)
|
104
|
+
$log.info("Updating configuration with #{config_hash.inspect}")
|
105
|
+
config_hash.each do |key, value|
|
106
|
+
case key
|
107
|
+
when :urls
|
108
|
+
@urls = value
|
109
|
+
when :cipher_suites
|
110
|
+
@cipher_suites = value
|
111
|
+
when :sslv2
|
112
|
+
@sslv2 = value
|
113
|
+
update_version_test_status()
|
114
|
+
when :sslv3
|
115
|
+
@sslv3 = value
|
116
|
+
update_version_test_status()
|
117
|
+
when :tlsv1
|
118
|
+
@tlsv1 = value
|
119
|
+
update_version_test_status()
|
120
|
+
when :scan_type
|
121
|
+
@scan_type = SCAN_TYPES[value] if(SCAN_TYPES[value])
|
122
|
+
when :proxy_add
|
123
|
+
@proxy_add = value
|
124
|
+
when :proxy_port
|
125
|
+
@proxy_port = value
|
126
|
+
when :rootcert_path
|
127
|
+
@rootcert_path = value
|
128
|
+
when :filter
|
129
|
+
begin
|
130
|
+
cipher_suites = OpenSSL::SSL.get_mod_cipher_suites(value)
|
131
|
+
rescue => ex
|
132
|
+
raise ex
|
133
|
+
end
|
134
|
+
@filter = value
|
135
|
+
@cipher_suites.clear
|
136
|
+
|
137
|
+
case @scan_mode
|
138
|
+
when SCAN_MODES[0]
|
139
|
+
cipher_suites.each do |x|
|
140
|
+
cs = CipherSuite.new(x[1], x[0], x[2].to_s)
|
141
|
+
update_test_status(cs)
|
142
|
+
@cipher_suites << cs
|
143
|
+
end
|
144
|
+
when SCAN_MODES[1]
|
145
|
+
cipher_suites.each do |xmode|
|
146
|
+
newsuite = CipherSuite.new(xmode[1], xmode[0], xmode[2].to_s)
|
147
|
+
idx = index_for_version(newsuite.version)
|
148
|
+
if(idx)
|
149
|
+
@cipher_suites[idx] = @cipher_suites[idx] + newsuite
|
150
|
+
else
|
151
|
+
update_test_status(newsuite)
|
152
|
+
@cipher_suites << newsuite
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
@cipher_suites.sort!
|
159
|
+
when :scan_mode
|
160
|
+
@scan_mode = SCAN_MODES[value] if(SCAN_MODES[value])
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
def count_to_test()
|
167
|
+
count = 0
|
168
|
+
cipher_suites.each do |x|
|
169
|
+
count += 1 if(x.test?)
|
170
|
+
end
|
171
|
+
count
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
CONF = SSLSmartConfig.instance
|
177
|
+
CONF.update_config({:filter => "DEFAULT"})
|
@@ -0,0 +1,351 @@
|
|
1
|
+
# Gursev Singh Kalra @ Foundstone(McAfee)
|
2
|
+
# Please see LICENSE.txt for licensing information
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'sslsmartlib'
|
6
|
+
require 'sslsmartconfig'
|
7
|
+
require 'sslsmartdb'
|
8
|
+
require 'uri'
|
9
|
+
require 'cgi'
|
10
|
+
require 'builder'
|
11
|
+
require 'socket'
|
12
|
+
require 'sslsmartlog'
|
13
|
+
|
14
|
+
$log = SSLSmartLog.instance
|
15
|
+
$conf = SSLSmartConfig.instance
|
16
|
+
|
17
|
+
MAX_THREADS = 3
|
18
|
+
MAX_THREAD_TIME = 10
|
19
|
+
class SSLSmartController < SSLSmartDB
|
20
|
+
def initialize()
|
21
|
+
super()
|
22
|
+
end
|
23
|
+
|
24
|
+
def start_test()
|
25
|
+
$log.debug("Starting SSLSmart Test")
|
26
|
+
begin
|
27
|
+
thr = []
|
28
|
+
$conf.urls.each_with_index do |url, url_index|
|
29
|
+
$log.info("Starting Test for #{url}")
|
30
|
+
purl = URI.parse(url)
|
31
|
+
path_query = (purl.query == nil || purl.query == "") ? "#{purl.path}" : "#{purl.path}?#{purl.query}"
|
32
|
+
add_url(url)
|
33
|
+
|
34
|
+
begin
|
35
|
+
Socket.gethostbyname(purl.host) # An exception is raised if this fails and is logged
|
36
|
+
rq = Net::HTTP.new(purl.host, purl.port, $conf.proxy_add, $conf.proxy_port)
|
37
|
+
rq.use_ssl = true
|
38
|
+
rq.disable_validations
|
39
|
+
rq.get("#{path_query}")
|
40
|
+
rescue SocketError => ex
|
41
|
+
$log.error("#{ex.class}\t#{purl.host}\t#{ex.message}")
|
42
|
+
next
|
43
|
+
rescue => ex
|
44
|
+
$log.error("#{ex.class}\t#{purl.host}\t#{ex.message}")
|
45
|
+
next
|
46
|
+
end
|
47
|
+
|
48
|
+
rq = Net::HTTP.new(purl.host, purl.port, $conf.proxy_add, $conf.proxy_port)
|
49
|
+
cert_details = rq.get_cert_details
|
50
|
+
$log.debug("Certificate Retrieved for #{purl.host}:#{purl.port}")
|
51
|
+
rq = Net::HTTP.new(purl.host, purl.port, $conf.proxy_add, $conf.proxy_port)
|
52
|
+
cert_validity = rq.verify_cert($conf.rootcert_path)
|
53
|
+
$log.debug("Certificate Vefified for #{purl.host}:#{purl.port}")
|
54
|
+
add_cert(url, cert_details, cert_validity)
|
55
|
+
yield url, url_index, nil if(block_given?)
|
56
|
+
|
57
|
+
#rq = Net::HTTP.new(purl.host, purl.port, $conf.proxy_add, $conf.proxy_port)
|
58
|
+
|
59
|
+
$conf.cipher_suites.each_with_index do |cipher_suite, suite_index|
|
60
|
+
$log.debug("Starting Threads")
|
61
|
+
thr << Thread.new do
|
62
|
+
next unless(cipher_suite.test?)
|
63
|
+
$log.debug("Testing #{url} with #{cipher_suite}")
|
64
|
+
rq = Net::HTTP.new(purl.host, purl.port, $conf.proxy_add, $conf.proxy_port)
|
65
|
+
response = rq.verify_ssl_config(cipher_suite.version, cipher_suite.name, SSLSmartConfig::SCAN_TYPES.index($conf.scan_type), "#{path_query}")
|
66
|
+
add_cipher_response(url, suite_index, response)
|
67
|
+
yield url, url_index, suite_index if(block_given?) #"#{cipher_suite.version}\t#{cipher_suite.bits}\t#{cipher_suite.name}\t\t#{response.status}"
|
68
|
+
end #End of thread
|
69
|
+
|
70
|
+
t1 = Time.now
|
71
|
+
if(thr.length >= MAX_THREADS)
|
72
|
+
thr.each do |x|
|
73
|
+
if(Time.now - t1 > MAX_THREAD_TIME)
|
74
|
+
x.terminate
|
75
|
+
$log.warn "Thread killed"
|
76
|
+
end
|
77
|
+
x.join
|
78
|
+
end
|
79
|
+
thr.clear
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
$log.debug("Ending Test for #{url}")
|
84
|
+
end
|
85
|
+
|
86
|
+
rescue => ex
|
87
|
+
$log.fatal(ex.message)
|
88
|
+
$log.fatal(ex.backtrace)
|
89
|
+
raise
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# def show_results()
|
94
|
+
# $conf.urls.each do |url|
|
95
|
+
# puts "#{url}"
|
96
|
+
# puts "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
|
97
|
+
# puts get_cert(url.to_sym).data.to_text
|
98
|
+
# puts cert_valid?(url.to_sym).status
|
99
|
+
# $conf.cipher_suites.each_with_index do |cipher_suite, suite_index|
|
100
|
+
# next unless(cipher_suite.test?)
|
101
|
+
# print "#{cipher_suite}\t#{suite_index}\t"
|
102
|
+
# puts "#{get_response(url, suite_index).status}" if(get_response(url, suite_index))
|
103
|
+
# end
|
104
|
+
# end
|
105
|
+
#
|
106
|
+
# end
|
107
|
+
|
108
|
+
|
109
|
+
def create_report(type)
|
110
|
+
case type
|
111
|
+
when :text, :textv
|
112
|
+
return create_text_report(type)
|
113
|
+
when :xml, :xmlv
|
114
|
+
return create_xml_report(type)
|
115
|
+
when :html, :htmlv
|
116
|
+
return create_html_report(type)
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
#WORKING GET_TEXT_REPORT FUNCTION
|
122
|
+
def create_text_report(type)
|
123
|
+
$log.debug("Creating text report")
|
124
|
+
return nil unless(type == :text || type == :textv)
|
125
|
+
tr = ""
|
126
|
+
tr << %q{
|
127
|
+
___ ___ _ ___ _ ___ _ _
|
128
|
+
/ __/ __| | / __|_ __ __ _ _ _| |_ | _ \___ ____ _| | |_ ___
|
129
|
+
\__ \__ \ |__\__ \ ' \/ _` | '_| _| | / -_|_-< || | | _(_-<
|
130
|
+
|___/___/____|___/_|_|_\__,_|_| \__| |_|_\___/__/\_,_|_|\__/__/
|
131
|
+
|
132
|
+
}
|
133
|
+
$conf.urls.each do |url|
|
134
|
+
next if(self.get_progress(url) == 0)
|
135
|
+
tr << "\n#{url}\n"
|
136
|
+
tr << "-"*80
|
137
|
+
if(results = get_all_cipher_results(url))
|
138
|
+
results.each_with_index do |result, suite_index|
|
139
|
+
next unless(result)
|
140
|
+
case result.status
|
141
|
+
when true
|
142
|
+
tr << "\n[+] Accepted%7s %-25s%5s bits %-s" % [$conf.cipher_suites[suite_index].version, $conf.cipher_suites[suite_index].name, $conf.cipher_suites[suite_index].bits, get_response_code(url, suite_index)]
|
143
|
+
if(type == :textv)
|
144
|
+
resp = get_text_response(url, suite_index)
|
145
|
+
tr << "\n%s\n" % [resp] if(resp)
|
146
|
+
end
|
147
|
+
when false
|
148
|
+
tr << "\n[-] Rejected%7s %-25s%5s bits %-s" % [$conf.cipher_suites[suite_index].version, $conf.cipher_suites[suite_index].name, $conf.cipher_suites[suite_index].bits, get_response_code(url, suite_index)]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
if(cert_validity = cert_valid?(url))
|
154
|
+
case cert_validity.status
|
155
|
+
when true
|
156
|
+
tr << "\n\n[+] Valid Digital Certificate\n"
|
157
|
+
when false
|
158
|
+
tr << "\n\n[-] Invalid Digital Certificate. "
|
159
|
+
tr << "#{cert_validity.data.message}\n" if(cert_validity.data)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
cert = get_cert(url)
|
163
|
+
if(type == :textv)
|
164
|
+
tr << cert.data.to_text if(cert && cert.data)
|
165
|
+
else
|
166
|
+
if(cert && cert.data)
|
167
|
+
tr << "\t%-20s\t:%s" % ["Certificate Subject", cert.data.subject]
|
168
|
+
tr << "\n\t%-20s\t:%s" % ["Certificate Issuer", cert.data.issuer]
|
169
|
+
tr << "\n\t%-20s\t:%s" % ["Valid Not Before", cert.data.not_before]
|
170
|
+
tr << "\n\t%-20s\t:%s" % ["Valid Not After", cert.data.not_after]
|
171
|
+
end
|
172
|
+
end
|
173
|
+
tr << "\n\n"
|
174
|
+
end
|
175
|
+
tr << "\n\n"
|
176
|
+
tr
|
177
|
+
end
|
178
|
+
|
179
|
+
#WORKING GET_TEXT_REPORT FUNCTION
|
180
|
+
def create_html_report(type)
|
181
|
+
$log.debug("Creating html report")
|
182
|
+
return nil unless(type == :html || type == :htmlv)
|
183
|
+
tr = ""
|
184
|
+
tr << "<html><head><title>SSLSmart Results</title></head>\n<body>"
|
185
|
+
tr << "\n<h1 align='center'>SSLSmart Results</h1>"
|
186
|
+
$conf.urls.each do |url|
|
187
|
+
next if(self.get_progress(url) == 0)
|
188
|
+
tr << "\n"
|
189
|
+
tr << '<table width="80%" border="1" cellpadding="0" cellspacing="0">'
|
190
|
+
tr << "\n<tr align='center'><td colspan='5' bgcolor=#A4A4A4><h3>#{url}</h3></td></tr>"
|
191
|
+
if(results = get_all_cipher_results(url))
|
192
|
+
tr << "<tr bgcolor=#BDBDBD>
|
193
|
+
<td><b>Supported?</b></td>
|
194
|
+
<td><b>Version</b></td>
|
195
|
+
<td><b>Cipher Suite</></td>
|
196
|
+
<td><b>Bits</b></td>
|
197
|
+
<td><b>Response Code</b></td>
|
198
|
+
</tr>
|
199
|
+
" if(results.length > 0)
|
200
|
+
results.each_with_index do |result, suite_index|
|
201
|
+
next unless(result)
|
202
|
+
case result.status
|
203
|
+
when true
|
204
|
+
tr << "<tr >
|
205
|
+
<td>Yes</td>
|
206
|
+
<td>#{$conf.cipher_suites[suite_index].version}</td>
|
207
|
+
<td>#{$conf.cipher_suites[suite_index].name}</td>
|
208
|
+
<td>#{$conf.cipher_suites[suite_index].bits}</td>
|
209
|
+
<td>#{get_response_code(url, suite_index)}</td>
|
210
|
+
</tr>"
|
211
|
+
if(type == :htmlv)
|
212
|
+
resp = get_text_response(url, suite_index)
|
213
|
+
if(resp)
|
214
|
+
resp = CGI.escapeHTML(resp)
|
215
|
+
resp = resp.gsub(/[\n\r]/,'<br/>')
|
216
|
+
tr << "\n<tr><td colspan='5'><font size='2'>#{resp}</font></td></tr>"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
when false
|
220
|
+
tr << "<tr>
|
221
|
+
<td>No</td>
|
222
|
+
<td>#{$conf.cipher_suites[suite_index].version}</td>
|
223
|
+
<td>#{$conf.cipher_suites[suite_index].name}</td>
|
224
|
+
<td>#{$conf.cipher_suites[suite_index].bits}</td>
|
225
|
+
<td>#{get_response_code(url, suite_index)}</td>
|
226
|
+
</tr>"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
cert = get_cert(url)
|
232
|
+
validity = ""
|
233
|
+
if(cert && cert.data)
|
234
|
+
if(cert_validity = cert_valid?(url))
|
235
|
+
case cert_validity.status
|
236
|
+
when true
|
237
|
+
validity << "Valid Digital Certificate"
|
238
|
+
when false
|
239
|
+
validity << "Invalid Digital Certificate. "
|
240
|
+
validity << "#{cert_validity.data.message}\n" if(cert_validity.data)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
tr << "<tr><td colspan='5' align='center' bgcolor=#BDBDBD><b>Certificate Details</b></td></tr>\n"
|
245
|
+
tr << "<tr><td colspan='2'><b>Validity</b></td><td colspan='3'>#{validity} </td></tr>\n"
|
246
|
+
tr << "<tr><td colspan='2'><b>Subject </b></td><td colspan='3'>#{cert.data.subject} </td></tr>\n"
|
247
|
+
tr << "<tr><td colspan='2'><b>Issuer </b></td><td colspan='3'>#{cert.data.issuer} </td></tr>\n"
|
248
|
+
tr << "<tr><td colspan='2'><b>Valid Not before </b></td><td colspan='3'>#{cert.data.not_before} </td></tr>\n"
|
249
|
+
tr << "<tr><td colspan='2'><b>Valid Not After </b></td><td colspan='3'>#{cert.data.not_after} </td></tr>\n"
|
250
|
+
if(type == :htmlv)
|
251
|
+
tr << "<tr><td colspan='2'><b>Version </b></td><td colspan='3'>#{cert.data.version}</td></tr>\n"
|
252
|
+
tr << "<tr><td colspan='2'><b>Serial Number </b></td><td colspan='3'>#{cert.data.serial} </td></tr>\n"
|
253
|
+
tr << "<tr><td colspan='2'><b>Signature Algorithm</b></td><td colspan='3'>#{cert.data.signature_algorithm} </td></tr>\n"
|
254
|
+
cert.data.extensions.each do |extn|
|
255
|
+
extns = extn.to_s.split("=")
|
256
|
+
tr << "<tr><td colspan='2'><b>#{extns[0]}</b></td><td colspan='3'>#{extns[1]} </td></tr>\n"
|
257
|
+
end
|
258
|
+
tr << "<tr><td colspan='2'><b>Public Key</b></td><td colspan='3'>#{cert.data.public_key.to_text.gsub(/\n/,'<br/>')} </td></tr>\n"
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
tr << "</table><br/><br/>\n"
|
263
|
+
|
264
|
+
end
|
265
|
+
tr << "</body>\n</html>"
|
266
|
+
tr
|
267
|
+
end
|
268
|
+
|
269
|
+
|
270
|
+
def create_xml_report(type)
|
271
|
+
$log.debug("Creating XML report")
|
272
|
+
return nil unless(type == :xml || type == :xmlv)
|
273
|
+
tr = ""
|
274
|
+
xm = Builder::XmlMarkup.new(:target => tr, :indent => 2)
|
275
|
+
xm.instruct!
|
276
|
+
|
277
|
+
xm.SSLSmart {
|
278
|
+
$conf.urls.each do |url|
|
279
|
+
next if(self.get_progress(url) == 0)
|
280
|
+
|
281
|
+
xm.url("value" => url) {
|
282
|
+
if(results = get_all_cipher_results(url))
|
283
|
+
results.each_with_index do |result, suite_index|
|
284
|
+
next unless(result)
|
285
|
+
|
286
|
+
if(result.status == true || result.status == false)
|
287
|
+
xm.cipher_suite {
|
288
|
+
xm.version($conf.cipher_suites[suite_index].version)
|
289
|
+
xm.name($conf.cipher_suites[suite_index].name)
|
290
|
+
xm.bits($conf.cipher_suites[suite_index].bits)
|
291
|
+
xm.supported(result.status)
|
292
|
+
xm.response_code(get_response_code(url, suite_index))
|
293
|
+
if(type == :xmlv)
|
294
|
+
xm.full_response{
|
295
|
+
xm.cdata!(CGI.escapeHTML(get_text_response(url, suite_index))) if(get_text_response(url, suite_index))
|
296
|
+
}
|
297
|
+
end
|
298
|
+
}
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end # END OF if(results = get_all_cipher_results(url))
|
302
|
+
|
303
|
+
cert = get_cert(url)
|
304
|
+
validity_msg = ""
|
305
|
+
validity = ""
|
306
|
+
if(cert && cert.data)
|
307
|
+
if(cert_validity = cert_valid?(url))
|
308
|
+
validity = cert_validity.status
|
309
|
+
case cert_validity.status
|
310
|
+
when true
|
311
|
+
validity_msg << "Valid Digital Certificate"
|
312
|
+
when false
|
313
|
+
validity_msg << "Invalid Digital Certificate. "
|
314
|
+
validity_msg << "#{cert_validity.data.message}\n" if(cert_validity.data)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
xm.certificate {
|
319
|
+
xm.validity(validity)
|
320
|
+
xm.validity_msg(validity_msg)
|
321
|
+
xm.subject(cert.data.subject)
|
322
|
+
xm.issuer(cert.data.issuer)
|
323
|
+
xm.not_before(cert.data.not_before)
|
324
|
+
xm.not_after(cert.data.not_after)
|
325
|
+
if(type == :xmlv)
|
326
|
+
xm.version(cert.data.version)
|
327
|
+
xm.serial(cert.data.serial)
|
328
|
+
xm.signature_algorithm(cert.data.signature_algorithm)
|
329
|
+
if(cert.data.extensions)
|
330
|
+
xm.x509extensions {
|
331
|
+
cert.data.extensions.each do |extn|
|
332
|
+
extns = extn.to_s.split("=", 2)
|
333
|
+
xm.extension {
|
334
|
+
xm.name(extns[0])
|
335
|
+
xm.value(extns[1])
|
336
|
+
}
|
337
|
+
end
|
338
|
+
}
|
339
|
+
end
|
340
|
+
xm.public_key{
|
341
|
+
xm.cdata!(cert.data.public_key.to_text)
|
342
|
+
}
|
343
|
+
end
|
344
|
+
}
|
345
|
+
end
|
346
|
+
}
|
347
|
+
end # END OF $conf.urls.each do |url|
|
348
|
+
}
|
349
|
+
tr
|
350
|
+
end
|
351
|
+
end
|