ciphersurfer 0.99.0 → 1.0.0.rc1
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/Gemfile +7 -0
- data/Gemfile.lock +10 -0
- data/README.md +16 -1
- data/VERSION +1 -1
- data/bin/ciphersurfer +91 -14
- data/lib/ciphersurfer/scanner.rb +22 -4
- data/lib/ciphersurfer/score.rb +117 -0
- data/lib/ciphersurfer.rb +1 -0
- data/spec/ciphersurfer_spec.rb +1 -3
- data/spec/scoring_spec.rb +131 -0
- metadata +71 -14
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
awesome_print (1.0.2)
|
4
5
|
diff-lcs (1.1.3)
|
5
6
|
git (1.2.5)
|
7
|
+
httpclient (2.2.4)
|
6
8
|
jeweler (1.6.4)
|
7
9
|
bundler (~> 1.0)
|
8
10
|
git (>= 1.2.5)
|
9
11
|
rake
|
12
|
+
json (1.6.5)
|
13
|
+
progressbar (0.9.2)
|
14
|
+
rainbow (1.1.3)
|
10
15
|
rake (0.9.2.2)
|
11
16
|
rcov (0.9.11)
|
12
17
|
rspec (2.3.0)
|
@@ -22,7 +27,12 @@ PLATFORMS
|
|
22
27
|
ruby
|
23
28
|
|
24
29
|
DEPENDENCIES
|
30
|
+
awesome_print
|
25
31
|
bundler (~> 1.0.0)
|
32
|
+
httpclient
|
26
33
|
jeweler (~> 1.6.4)
|
34
|
+
json
|
35
|
+
progressbar
|
36
|
+
rainbow
|
27
37
|
rcov
|
28
38
|
rspec (~> 2.3.0)
|
data/README.md
CHANGED
@@ -4,9 +4,24 @@ ciphersurfer is a tool to enumerate a website for ciphers it supports. It can
|
|
4
4
|
be used for testing pourposes and to evaluate te security configuration for an
|
5
5
|
SSL configured web server.
|
6
6
|
|
7
|
+
## Installing ciphersurfer
|
8
|
+
|
9
|
+
Installing ciphersurfer is easy. Just follow the standard ruby gem way:
|
10
|
+
|
11
|
+
gem install ciphersurfer
|
12
|
+
|
13
|
+
Now you've got a ciphersurfer executable you can invoke using your command line.
|
14
|
+
|
15
|
+
## SSLabs
|
16
|
+
|
17
|
+
For the SSL security evaluation, we use [SSLabs
|
18
|
+
document](https://www.ssllabs.com/downloads/SSL_Server_Rating_Guide_2009.pdf)
|
19
|
+
as reference.
|
20
|
+
|
7
21
|
## OWASP Testing guide
|
8
22
|
|
9
|
-
ciphersurfer goal is to make tests described in the [Owasp Testing
|
23
|
+
ciphersurfer goal is to make tests described in the [Owasp Testing
|
24
|
+
guide](https://www.owasp.org/index.php/Testing_for_SSL-TLS_(OWASP-CM-001\))
|
10
25
|
|
11
26
|
|
12
27
|
## Contributing to ciphersurfer
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0.rc1
|
data/bin/ciphersurfer
CHANGED
@@ -1,24 +1,101 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
|
4
|
-
|
5
2
|
require 'ciphersurfer'
|
3
|
+
require 'rainbow'
|
4
|
+
require 'awesome_print'
|
5
|
+
require 'progressbar'
|
6
|
+
require 'getoptlong'
|
7
|
+
require 'json'
|
8
|
+
|
9
|
+
opts = GetoptLong.new(
|
10
|
+
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
11
|
+
[ '--version', '-v', GetoptLong::NO_ARGUMENT ],
|
12
|
+
[ '--list-ciphers', '-l', GetoptLong::NO_ARGUMENT ]#,
|
13
|
+
# [ '--json', '-j', GetoptLong::NO_ARGUMENT]
|
14
|
+
)
|
6
15
|
|
7
|
-
|
8
|
-
|
9
|
-
|
16
|
+
options={:json=>false,:list_ciphers=>false}
|
17
|
+
|
18
|
+
opts.each do |opt, arg|
|
19
|
+
case opt
|
20
|
+
when '--help'
|
21
|
+
ap "usage: ciphersurfer [-ljvh] server[:port]"
|
22
|
+
ap " -l: lists supported ciphers instead of just evaluate the security level"
|
23
|
+
# ap " -j: formats the output using JSON"
|
24
|
+
ap " -v: shows version"
|
25
|
+
ap " -h: this help"
|
26
|
+
exit 0
|
27
|
+
when '--version'
|
28
|
+
ap "ciphersurfer " + Ciphersurfer::Version.version[:string]
|
29
|
+
exit 0
|
30
|
+
# unsupported right now...
|
31
|
+
#when '--json'
|
32
|
+
# options[:json]=true
|
33
|
+
when '--list-ciphers'
|
34
|
+
options[:list_ciphers]=true
|
35
|
+
end
|
10
36
|
end
|
11
|
-
|
37
|
+
|
38
|
+
if ( ARGV.length != 1 )
|
39
|
+
ap 'ciphersurfer: missing target'
|
40
|
+
exit -1
|
41
|
+
end
|
42
|
+
|
43
|
+
target = ARGV.shift
|
44
|
+
host = target.split(':')[0] ||= "localhost" #fallback here should never occur... however it's better to be paranoid
|
45
|
+
port = target.split(':')[1] ||= 443 # more common here
|
46
|
+
|
47
|
+
ap "scanning #{host}:#{port} for supported ciphers"
|
48
|
+
|
49
|
+
if ! Ciphersurfer::Scanner.alive?(host, port)
|
50
|
+
ap "it seems there is no server listening @#{host}:#{port}"
|
51
|
+
exit -2
|
52
|
+
end
|
53
|
+
|
54
|
+
protocol_version = [:SSLv2, :SSLv3, :TLSv1]#, :TLSv11, :TLSv12]
|
55
|
+
|
56
|
+
# ok = {}
|
57
|
+
supported_protocols = []
|
58
|
+
cipher_bits=[]
|
59
|
+
|
60
|
+
|
61
|
+
|
12
62
|
protocol_version.each do |version|
|
13
|
-
|
14
|
-
s = Ciphersurfer::Scanner.new({:host=>ARGV[0], :port=>ARGV[1], :proto=>version})
|
63
|
+
s = Ciphersurfer::Scanner.new({:host=>host, :port=>port, :proto=>version})
|
15
64
|
|
16
65
|
s.go
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
ok.each do |o|
|
21
|
-
puts "[+] Accepted\t #{o[:bits]} bits\t#{o[:name]}"
|
66
|
+
if (s.ok_ciphers.size != 0)
|
67
|
+
supported_protocols << version
|
68
|
+
cipher_bits = cipher_bits | s.ok_bits
|
22
69
|
end
|
70
|
+
|
71
|
+
# ok << {:proto=>version, :ciphers=>s.ok_ciphers}
|
72
|
+
|
23
73
|
end
|
24
74
|
|
75
|
+
cert = Ciphersurfer::Scanner.cert(host, port)
|
76
|
+
a=cert.public_key.to_text
|
77
|
+
key_size=/Modulus \((\d+)/i.match(a)[1]
|
78
|
+
|
79
|
+
|
80
|
+
proto_score= Ciphersurfer::Score.evaluate_protocols(supported_protocols)
|
81
|
+
cipher_score= Ciphersurfer::Score.evaluate_ciphers(cipher_bits)
|
82
|
+
key_score= Ciphersurfer::Score.evaluate_key(key_size.to_i)
|
83
|
+
score= Ciphersurfer::Score.score(proto_score, key_score, cipher_score)
|
84
|
+
ap Ciphersurfer::Score.evaluate(score) + " ("+score.to_s+")"
|
85
|
+
|
86
|
+
ap "Protocol support: " + proto_score.to_s
|
87
|
+
ap "Key exchange: " + key_score.to_s
|
88
|
+
ap "Cipher strength: " + cipher_score.to_s
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
# e.g. supported_protocols = [:SSLv2, :TLSv1]
|
94
|
+
# e.g. cipher_bits = [0, 256, 1024]
|
95
|
+
|
96
|
+
# if options[:list_ciphers]
|
97
|
+
# ok.each do |o|
|
98
|
+
# puts "[+] Accepted\\t #{o[:bits]} bits\\t#{o[:name]}"
|
99
|
+
# end
|
100
|
+
# end
|
101
|
+
|
data/lib/ciphersurfer/scanner.rb
CHANGED
@@ -1,17 +1,26 @@
|
|
1
1
|
require 'net/https'
|
2
2
|
require 'openssl'
|
3
|
+
require 'httpclient'
|
4
|
+
|
3
5
|
|
4
6
|
module Ciphersurfer
|
5
7
|
class Scanner
|
6
8
|
|
7
|
-
attr_reader :ok_ciphers, :
|
9
|
+
attr_reader :ok_ciphers, :ok_bits
|
10
|
+
attr_reader :peer_cert
|
8
11
|
|
9
12
|
def initialize(options={})
|
10
13
|
@host=options[:host]
|
11
14
|
@port=options[:port] ||= 443
|
12
15
|
@proto=options[:proto]
|
13
16
|
@ok_ciphers=[]
|
14
|
-
@
|
17
|
+
@ok_bits=[]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.cert(host, port)
|
21
|
+
client=HTTPClient.new
|
22
|
+
response=client.get("https://#{host}:#{port}")
|
23
|
+
peer_cert = response.peer_cert
|
15
24
|
end
|
16
25
|
|
17
26
|
def self.alive?(host, port)
|
@@ -25,23 +34,32 @@ module Ciphersurfer
|
|
25
34
|
return false
|
26
35
|
rescue OpenSSL::SSL::SSLError => e
|
27
36
|
return false
|
37
|
+
rescue
|
38
|
+
return false
|
28
39
|
end
|
29
40
|
end
|
41
|
+
|
30
42
|
def go
|
31
43
|
context=OpenSSL::SSL::SSLContext.new(@proto)
|
32
44
|
cipher_set = context.ciphers
|
33
45
|
cipher_set.each do |cipher_name, cipher_version, bits, algorithm_bits|
|
46
|
+
|
34
47
|
request = Net::HTTP.new(@host, @port)
|
35
48
|
request.use_ssl = true
|
49
|
+
|
50
|
+
request.ca_file='/Users/thesp0nge/src/hacking/ciphersurfer/cacert.pem'
|
36
51
|
request.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
37
52
|
request.ciphers= cipher_name
|
38
53
|
begin
|
39
54
|
response = request.get("/")
|
55
|
+
@ok_bits << bits
|
40
56
|
@ok_ciphers << {:bits=>bits, :name=>cipher_name}
|
41
57
|
rescue OpenSSL::SSL::SSLError => e
|
42
|
-
|
58
|
+
# Quietly discard SSLErrors, really I don't care if the cipher has
|
59
|
+
# not been accepted
|
43
60
|
rescue
|
44
|
-
# Quietly discard all other errors... you must perform all error
|
61
|
+
# Quietly discard all other errors... you must perform all error
|
62
|
+
# chekcs in the calling program
|
45
63
|
end
|
46
64
|
end
|
47
65
|
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Ciphersurfer
|
2
|
+
PROTOCOL_SUPPORT_RATIO = 0.3
|
3
|
+
KEY_EXCHANGE_RATIO = 0.3
|
4
|
+
CIPHER_STRENGTH = 0.4
|
5
|
+
|
6
|
+
class Score
|
7
|
+
|
8
|
+
# Gives the final evaluation given the final score
|
9
|
+
# @param the score obtained in the previous steps
|
10
|
+
# @result an evaluation between A, the highest one and F, the lowest
|
11
|
+
def self.evaluate(score)
|
12
|
+
return "F" unless score > 0
|
13
|
+
|
14
|
+
case score
|
15
|
+
|
16
|
+
when 0...20
|
17
|
+
ret = "F"
|
18
|
+
when 20...35
|
19
|
+
ret = "E"
|
20
|
+
when 35...50
|
21
|
+
ret = "D"
|
22
|
+
when 50...65
|
23
|
+
ret = "C"
|
24
|
+
when 65...80
|
25
|
+
ret = "B"
|
26
|
+
else
|
27
|
+
ret = "A"
|
28
|
+
end
|
29
|
+
|
30
|
+
return ret
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def self.evaluate_protocols(protocols)
|
35
|
+
best = -1
|
36
|
+
worst = -1
|
37
|
+
|
38
|
+
if (protocols.include?(:SSLv2))
|
39
|
+
best = 20
|
40
|
+
worst = 20
|
41
|
+
end
|
42
|
+
if (protocols.include?(:SSLv3))
|
43
|
+
best = 80
|
44
|
+
(worst = 80) unless worst != -1
|
45
|
+
end
|
46
|
+
if (protocols.include?(:TLSv1))
|
47
|
+
best = 90
|
48
|
+
(worst = 90) unless worst != -1
|
49
|
+
end
|
50
|
+
if (protocols.include?(:TLSv11))
|
51
|
+
best = 95
|
52
|
+
(worst = 95) unless worst != -1
|
53
|
+
end
|
54
|
+
if (protocols.include?(:TLSv12))
|
55
|
+
best = 100
|
56
|
+
(worst = 100) unless worst != -1
|
57
|
+
end
|
58
|
+
|
59
|
+
(best + worst) / 2
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
# @param an Array of supported ciphers bit
|
64
|
+
def self.evaluate_ciphers(ciphers)
|
65
|
+
best = -1
|
66
|
+
worst = 999999999999999999999999999999999999
|
67
|
+
|
68
|
+
#[0, 24, 1024]
|
69
|
+
ciphers.each do |c|
|
70
|
+
if (c == 0)
|
71
|
+
worst = 0
|
72
|
+
best = 0 unless best != -1
|
73
|
+
end
|
74
|
+
if (c < 128) && (c!=0)
|
75
|
+
worst = 20 unless worst < 20
|
76
|
+
best = 20 unless best > 20
|
77
|
+
end
|
78
|
+
|
79
|
+
if (c < 256) && (c>=128)
|
80
|
+
worst = 80 unless worst < 80
|
81
|
+
best = 80 unless best > 80
|
82
|
+
end
|
83
|
+
|
84
|
+
if (c >= 256)
|
85
|
+
worst = 100 unless worst < 100
|
86
|
+
best = 100
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
(best + worst) / 2
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
# FIXME: How can I test Weak key (Debian OpenSSL flaw)?
|
95
|
+
# FIXME: Evaluate if "Exportable key exchange limited to 512 bits is fully covered in k_len<1024
|
96
|
+
def self.evaluate_key(key_length)
|
97
|
+
case (key_length)
|
98
|
+
when 0
|
99
|
+
return 0
|
100
|
+
when 1...512
|
101
|
+
return 20
|
102
|
+
when 512...1024
|
103
|
+
return 40
|
104
|
+
when 1024...2048
|
105
|
+
return 80
|
106
|
+
when 2048...4096
|
107
|
+
return 90
|
108
|
+
else
|
109
|
+
return 100
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.score(proto, key, ciphers)
|
114
|
+
return ((0.3*proto) + (0.3*key) + (0.4*ciphers))
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/ciphersurfer.rb
CHANGED
data/spec/ciphersurfer_spec.rb
CHANGED
@@ -0,0 +1,131 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe 'Ciphersurfer' do
|
4
|
+
describe 'Score' do
|
5
|
+
it "should assign A to overall scores higher than 80" do
|
6
|
+
Ciphersurfer::Score.evaluate(90).should == "A"
|
7
|
+
Ciphersurfer::Score.evaluate(80).should == "A"
|
8
|
+
Ciphersurfer::Score.evaluate(79).should_not == "A"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should assign B to scores up between 65 and 79" do
|
12
|
+
Ciphersurfer::Score.evaluate(64).should_not == "B"
|
13
|
+
Ciphersurfer::Score.evaluate(65).should == "B"
|
14
|
+
Ciphersurfer::Score.evaluate(79).should == "B"
|
15
|
+
Ciphersurfer::Score.evaluate(80).should_not == "B"
|
16
|
+
end
|
17
|
+
it "should assign C to scores up between 50 and 64" do
|
18
|
+
Ciphersurfer::Score.evaluate(49).should_not == "C"
|
19
|
+
Ciphersurfer::Score.evaluate(50).should == "C"
|
20
|
+
Ciphersurfer::Score.evaluate(64).should == "C"
|
21
|
+
Ciphersurfer::Score.evaluate(65).should_not == "C"
|
22
|
+
end
|
23
|
+
it "should assign D to scores up between 35 and 49" do
|
24
|
+
Ciphersurfer::Score.evaluate(34).should_not == "D"
|
25
|
+
Ciphersurfer::Score.evaluate(35).should == "D"
|
26
|
+
Ciphersurfer::Score.evaluate(49).should == "D"
|
27
|
+
Ciphersurfer::Score.evaluate(50).should_not == "D"
|
28
|
+
end
|
29
|
+
it "should assign E to scores up between 20 and 34" do
|
30
|
+
Ciphersurfer::Score.evaluate(19).should_not == "E"
|
31
|
+
Ciphersurfer::Score.evaluate(20).should == "E"
|
32
|
+
Ciphersurfer::Score.evaluate(34).should == "E"
|
33
|
+
Ciphersurfer::Score.evaluate(35).should_not == "E"
|
34
|
+
end
|
35
|
+
it "should assign F to overall scores lower than 20" do
|
36
|
+
Ciphersurfer::Score.evaluate(19).should == "F"
|
37
|
+
Ciphersurfer::Score.evaluate(0).should == "F"
|
38
|
+
Ciphersurfer::Score.evaluate(-123).should == "F"
|
39
|
+
Ciphersurfer::Score.evaluate(20).should_not == "F"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should give a 0.5 if both SSLv2 and SSLv3 are supported but no TLS" do
|
43
|
+
Ciphersurfer::Score.evaluate_protocols([:SSLv2, :SSLv3]).should == 0.5
|
44
|
+
end
|
45
|
+
it "should give a 0.2 if only SSLv2 protocol is supported" do
|
46
|
+
Ciphersurfer::Score.evaluate_protocols([:SSLv2]).should == 0.2
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should give a 0.55 if SSLv2 and TLSv1 are supported but no SSLv3" do
|
50
|
+
Ciphersurfer::Score.evaluate_protocols([:SSLv2, :TLSv1]).should == 0.55
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should give a 0.55 if SSLv2, SSLv3 and TLSv1 are supported" do
|
54
|
+
Ciphersurfer::Score.evaluate_protocols([:SSLv2, :SSLv3, :TLSv1]).should == 0.55
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should give a 1 if only TLSv1.2 is supported" do
|
58
|
+
Ciphersurfer::Score.evaluate_protocols([:TLSv12]).should == 1.0
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should give a 0 if cipher has 0 length" do
|
62
|
+
Ciphersurfer::Score.evaluate_ciphers([0]).should == 0
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should give a 0.2 if ciphers supported have length < 128" do
|
66
|
+
Ciphersurfer::Score.evaluate_ciphers([40, 56, 64]).should == 0.2
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should give a 0.8 if ciphers supported have length < 256" do
|
70
|
+
Ciphersurfer::Score.evaluate_ciphers([128, 168, 255]).should == 0.8
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should give a 1.0 if ciphers supported have length >= 256" do
|
74
|
+
Ciphersurfer::Score.evaluate_ciphers([256, 512, 2048]).should == 1.0
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should give 0.1 if no encryption or ciphers lenght < 128" do
|
78
|
+
Ciphersurfer::Score.evaluate_ciphers([0, 40, 56, 64]).should == 0.1
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should give a 0.5 if ciphers supported have length < 256 and < 128" do
|
82
|
+
Ciphersurfer::Score.evaluate_ciphers([40, 56, 128, 168, 255]).should == 0.5
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should give a 0.6 if ciphers supported have length >= 256 and < 128" do
|
86
|
+
Ciphersurfer::Score.evaluate_ciphers([40, 56, 1024, 2048]).should == 0.6
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should give a 0 if no key provided" do
|
90
|
+
Ciphersurfer::Score.evaluate_key(0).should == 0
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should give a 0.2 if key < 512" do
|
94
|
+
Ciphersurfer::Score.evaluate_key(128).should == 0.2
|
95
|
+
Ciphersurfer::Score.evaluate_key(256).should == 0.2
|
96
|
+
Ciphersurfer::Score.evaluate_key(511).should == 0.2
|
97
|
+
Ciphersurfer::Score.evaluate_key(512).should_not == 0.2
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should give a 0.4 if 512 <= key < 1024" do
|
101
|
+
Ciphersurfer::Score.evaluate_key(512).should == 0.4
|
102
|
+
Ciphersurfer::Score.evaluate_key(1000).should == 0.4
|
103
|
+
Ciphersurfer::Score.evaluate_key(1024).should_not == 0.4
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should give a 0.8 if 1024 <= key < 2048" do
|
107
|
+
Ciphersurfer::Score.evaluate_key(1024).should == 0.8
|
108
|
+
Ciphersurfer::Score.evaluate_key(2043).should == 0.8
|
109
|
+
Ciphersurfer::Score.evaluate_key(2048).should_not == 0.8
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should give a 0.9 if 2048 <= key < 4096" do
|
113
|
+
Ciphersurfer::Score.evaluate_key(2048).should == 0.9
|
114
|
+
Ciphersurfer::Score.evaluate_key(4095).should == 0.9
|
115
|
+
Ciphersurfer::Score.evaluate_key(4096).should_not == 0.9
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should give a 1.0 if key >= 4096" do
|
119
|
+
Ciphersurfer::Score.evaluate_key(4096).should == 1.0
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
it "should evalute the overall score" do
|
124
|
+
Ciphersurfer::Score.score([1.0, 1.0, 1.0]).should == 1.0
|
125
|
+
Ciphersurfer::Score.score([0, 1.0, 1.0]).should == 0.7
|
126
|
+
Ciphersurfer::Score.score([1.0, 0, 1.0]).should == 0.7
|
127
|
+
Ciphersurfer::Score.score([1.0, 1.0, 0]).should == 0.6
|
128
|
+
Ciphersurfer::Score.score([0, 0, 1.0]).should == 0.4
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
metadata
CHANGED
@@ -1,19 +1,74 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ciphersurfer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0.rc1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Paolo Perego
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-30 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rainbow
|
16
|
+
requirement: &70292333333420 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70292333333420
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: progressbar
|
27
|
+
requirement: &70292333332820 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70292333332820
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: awesome_print
|
38
|
+
requirement: &70292333332280 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70292333332280
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: json
|
49
|
+
requirement: &70292333331760 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70292333331760
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: httpclient
|
60
|
+
requirement: &70292333331180 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70292333331180
|
14
69
|
- !ruby/object:Gem::Dependency
|
15
70
|
name: rspec
|
16
|
-
requirement: &
|
71
|
+
requirement: &70292333330580 !ruby/object:Gem::Requirement
|
17
72
|
none: false
|
18
73
|
requirements:
|
19
74
|
- - ~>
|
@@ -21,10 +76,10 @@ dependencies:
|
|
21
76
|
version: 2.3.0
|
22
77
|
type: :development
|
23
78
|
prerelease: false
|
24
|
-
version_requirements: *
|
79
|
+
version_requirements: *70292333330580
|
25
80
|
- !ruby/object:Gem::Dependency
|
26
81
|
name: bundler
|
27
|
-
requirement: &
|
82
|
+
requirement: &70292333329980 !ruby/object:Gem::Requirement
|
28
83
|
none: false
|
29
84
|
requirements:
|
30
85
|
- - ~>
|
@@ -32,10 +87,10 @@ dependencies:
|
|
32
87
|
version: 1.0.0
|
33
88
|
type: :development
|
34
89
|
prerelease: false
|
35
|
-
version_requirements: *
|
90
|
+
version_requirements: *70292333329980
|
36
91
|
- !ruby/object:Gem::Dependency
|
37
92
|
name: jeweler
|
38
|
-
requirement: &
|
93
|
+
requirement: &70292333329400 !ruby/object:Gem::Requirement
|
39
94
|
none: false
|
40
95
|
requirements:
|
41
96
|
- - ~>
|
@@ -43,10 +98,10 @@ dependencies:
|
|
43
98
|
version: 1.6.4
|
44
99
|
type: :development
|
45
100
|
prerelease: false
|
46
|
-
version_requirements: *
|
101
|
+
version_requirements: *70292333329400
|
47
102
|
- !ruby/object:Gem::Dependency
|
48
103
|
name: rcov
|
49
|
-
requirement: &
|
104
|
+
requirement: &70292333328800 !ruby/object:Gem::Requirement
|
50
105
|
none: false
|
51
106
|
requirements:
|
52
107
|
- - ! '>='
|
@@ -54,7 +109,7 @@ dependencies:
|
|
54
109
|
version: '0'
|
55
110
|
type: :development
|
56
111
|
prerelease: false
|
57
|
-
version_requirements: *
|
112
|
+
version_requirements: *70292333328800
|
58
113
|
description: ciphersurfer is a security tool that list enabled ciphers for a secure
|
59
114
|
HTTP connection
|
60
115
|
email: thesp0nge@gmail.com
|
@@ -76,8 +131,10 @@ files:
|
|
76
131
|
- bin/ciphersurfer
|
77
132
|
- lib/ciphersurfer.rb
|
78
133
|
- lib/ciphersurfer/scanner.rb
|
134
|
+
- lib/ciphersurfer/score.rb
|
79
135
|
- lib/ciphersurfer/version.rb
|
80
136
|
- spec/ciphersurfer_spec.rb
|
137
|
+
- spec/scoring_spec.rb
|
81
138
|
- spec/spec_helper.rb
|
82
139
|
homepage: http://github.com/thesp0nge/ciphersurfer
|
83
140
|
licenses:
|
@@ -94,13 +151,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
151
|
version: '0'
|
95
152
|
segments:
|
96
153
|
- 0
|
97
|
-
hash: -
|
154
|
+
hash: -2946885741293011983
|
98
155
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
156
|
none: false
|
100
157
|
requirements:
|
101
|
-
- - ! '
|
158
|
+
- - ! '>'
|
102
159
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
160
|
+
version: 1.3.1
|
104
161
|
requirements: []
|
105
162
|
rubyforge_project:
|
106
163
|
rubygems_version: 1.8.10
|