ruby-sslyze 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.document +3 -0
  3. data/.gitignore +4 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +19 -0
  6. data/.yardopts +1 -0
  7. data/ChangeLog.md +8 -0
  8. data/Gemfile +18 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.md +70 -0
  11. data/Rakefile +23 -0
  12. data/lib/sslyze.rb +3 -0
  13. data/lib/sslyze/cert_info.rb +55 -0
  14. data/lib/sslyze/certificate.rb +139 -0
  15. data/lib/sslyze/certificate/domain_name.rb +77 -0
  16. data/lib/sslyze/certificate/extensions.rb +127 -0
  17. data/lib/sslyze/certificate/extensions/authority_information_access.rb +38 -0
  18. data/lib/sslyze/certificate/extensions/extension.rb +26 -0
  19. data/lib/sslyze/certificate/extensions/x509v3_basic_constraints.rb +60 -0
  20. data/lib/sslyze/certificate/extensions/x509v3_certificate_policies.rb +50 -0
  21. data/lib/sslyze/certificate/extensions/x509v3_crl_distribution_points.rb +32 -0
  22. data/lib/sslyze/certificate/extensions/x509v3_extended_key_usage.rb +32 -0
  23. data/lib/sslyze/certificate/extensions/x509v3_key_usage.rb +50 -0
  24. data/lib/sslyze/certificate/extensions/x509v3_subject_alternative_name.rb +71 -0
  25. data/lib/sslyze/certificate/issuer.rb +56 -0
  26. data/lib/sslyze/certificate/public_key.rb +9 -0
  27. data/lib/sslyze/certificate/subject.rb +117 -0
  28. data/lib/sslyze/certificate/subject_public_key_info.rb +53 -0
  29. data/lib/sslyze/certificate/validity.rb +9 -0
  30. data/lib/sslyze/certificate_chain.rb +89 -0
  31. data/lib/sslyze/certificate_validation.rb +44 -0
  32. data/lib/sslyze/cipher_suite.rb +237 -0
  33. data/lib/sslyze/key_exchange.rb +106 -0
  34. data/lib/sslyze/ocsp_response.rb +87 -0
  35. data/lib/sslyze/program.rb +66 -0
  36. data/lib/sslyze/protocol.rb +133 -0
  37. data/lib/sslyze/target.rb +295 -0
  38. data/lib/sslyze/task.rb +65 -0
  39. data/lib/sslyze/types.rb +17 -0
  40. data/lib/sslyze/version.rb +4 -0
  41. data/lib/sslyze/xml.rb +139 -0
  42. data/ruby-sslyze.gemspec +24 -0
  43. data/spec/cert_info_spec.rb +29 -0
  44. data/spec/certificate/subject_name_spec.rb +72 -0
  45. data/spec/certificate_chain_spec.rb +61 -0
  46. data/spec/certificate_spec.rb +330 -0
  47. data/spec/certificate_validation_spec.rb +27 -0
  48. data/spec/cipher_suite_spec.rb +50 -0
  49. data/spec/issuer_spec.rb +33 -0
  50. data/spec/key_exchange_spec.rb +97 -0
  51. data/spec/ocsp_response_spec.rb +59 -0
  52. data/spec/protocol_spec.rb +99 -0
  53. data/spec/spec_helper.rb +9 -0
  54. data/spec/sslyze.xml +2798 -0
  55. data/spec/sslyze_spec.rb +8 -0
  56. data/spec/subject_public_key_info_spec.rb +35 -0
  57. data/spec/subject_spec.rb +67 -0
  58. data/spec/target_spec.rb +176 -0
  59. data/spec/xml_examples.rb +9 -0
  60. data/spec/xml_spec.rb +72 -0
  61. metadata +162 -0
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'sslyze'
3
+
4
+ describe SSLyze do
5
+ it "should have a VERSION constant" do
6
+ expect(subject.const_get('VERSION')).to_not be_empty
7
+ end
8
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'xml_examples'
3
+ require 'sslyze/certificate'
4
+
5
+ describe SSLyze::Certificate::SubjectPublicKeyInfo do
6
+ include_examples "XML specs"
7
+
8
+ subject { described_class.new(xml.at('/document/results/target/certinfo/certificateChain/certificate/subjectPublicKeyInfo')) }
9
+
10
+ describe "#public_key" do
11
+ it "should return a PublicKey object" do
12
+ expect(subject.public_key).to be_a(Certificate::PublicKey)
13
+ end
14
+
15
+ it "should parse the publicKey/modulus element" do
16
+ expect(subject.public_key.modulus).to be == %{00:b1:d4:dc:3c:af:fd:f3:4e:ed:c1:67:ad:e6:cb:22:e8:b7:e2:ab:28:f2:f7:dc:62:70:08:d1:0c:af:d6:16:6a:21:b0:36:4b:17:0d:36:63:04:ae:bf:ea:20:51:95:65:66:f2:bf:b9:4d:a4:0c:29:eb:f5:15:b1:e8:35:b3:70:10:94:d5:1b:59:b4:26:0f:d6:83:57:59:9d:e1:7c:09:dd:e0:13:ca:4d:6f:43:9b:cd:cf:87:3a:15:a7:85:dd:66:83:ed:93:0c:fe:2b:6d:38:1c:79:88:90:cf:ad:58:18:2d:51:d1:c2:a3:f2:47:8c:6f:38:09:b9:b8:ef:4c:93:0b:cb:83:94:87:ea:e0:a3:b5:d9:7b:9b:6b:0f:43:f9:ca:ee:80:0d:28:a7:76:f1:25:f4:c1:35:3c:f6:74:ad:de:6a:33:82:7b:dc:fd:4b:76:a7:c2:ee:f2:6a:bf:a9:24:a6:5f:e7:2e:7c:0e:db:c3:74:73:fa:7e:c6:d8:cf:60:eb:36:56:21:b6:c1:8a:b8:24:82:4d:78:24:ba:e9:1d:a1:8a:a7:87:be:66:25:69:bf:be:3b:72:6e:4f:e0:e4:85:25:08:b1:91:89:b8:d6:74:65:76:9b:2c:4f:62:1f:a1:fa:3a:be:9c:24:bf:9f:ca:b0:c5:c0:67:8d}
17
+ end
18
+
19
+ it "should parse the publicKey/exponent element" do
20
+ expect(subject.public_key.exponent).to be == 65537
21
+ end
22
+ end
23
+
24
+ describe "#public_key_algorithm" do
25
+ it "should parse the publicKeyAlgorithm element" do
26
+ expect(subject.public_key_algorithm).to be == 'rsaEncryption'
27
+ end
28
+ end
29
+
30
+ describe "#public_key_size" do
31
+ it "should parse the publicKeySize element" do
32
+ expect(subject.public_key_size).to be == 2048
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+ require 'xml_examples'
3
+ require 'sslyze/certificate'
4
+
5
+ describe SSLyze::Certificate::Subject do
6
+ include_examples "XML specs"
7
+
8
+ subject { described_class.new(xml.at('/document/results/target/certinfo/certificateChain/certificate/subject')) }
9
+
10
+ describe "#organizational_unit_name" do
11
+ pending "need data"
12
+ end
13
+
14
+ describe "#organization_name" do
15
+ it "should parse the organizationName element" do
16
+ expect(subject.organization_name).to be == 'GitHub, Inc.'
17
+ end
18
+ end
19
+
20
+ describe "#business_category" do
21
+ it "should parse the businessCategory element" do
22
+ expect(subject.business_category).to be == 'Private Organization'
23
+ end
24
+ end
25
+
26
+ describe "#serial_number" do
27
+ it "should parse the serialNumber element" do
28
+ expect(subject.serial_number).to be == 5157550
29
+ end
30
+ end
31
+
32
+ describe "#common_name" do
33
+ it "should parse the commonName element" do
34
+ expect(subject.common_name.name).to be == 'github.com'
35
+ end
36
+ end
37
+
38
+ describe "#state_or_province_name" do
39
+ it "should parse the stateOrProvinceName element" do
40
+ expect(subject.state_or_province_name).to be == 'California'
41
+ end
42
+ end
43
+
44
+ describe "#country_name" do
45
+ it "should parse the countryName element" do
46
+ expect(subject.country_name).to be == 'US'
47
+ end
48
+ end
49
+
50
+ describe "#street_address" do
51
+ it "should parse the streetAddress element" do
52
+ expect(subject.street_address).to be == '548 4th Street'
53
+ end
54
+ end
55
+
56
+ describe "#locality_name" do
57
+ it "should parse the localityName element" do
58
+ expect(subject.locality_name).to be == 'San Francisco'
59
+ end
60
+ end
61
+
62
+ describe "#postal_code" do
63
+ it "should parse the postalCode element" do
64
+ expect(subject.postal_code).to be == '94107'
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,176 @@
1
+ require 'spec_helper'
2
+ require 'xml_examples'
3
+ require 'sslyze/target'
4
+
5
+ describe SSLyze::Target do
6
+ include_examples "XML specs"
7
+
8
+ subject { described_class.new(xml.at('/document/results/target')) }
9
+
10
+ describe "#host" do
11
+ it "must parse the host attribute" do
12
+ expect(subject.host).to be == 'github.com'
13
+ end
14
+ end
15
+
16
+ describe "#ip" do
17
+ it "must parse the ip attribute" do
18
+ expect(subject.ip).to be == '192.30.252.130'
19
+ end
20
+ end
21
+
22
+ describe "#port" do
23
+ it "must parse the port attribute" do
24
+ expect(subject.port).to be == 443
25
+ end
26
+ end
27
+
28
+ describe "#cert_info" do
29
+ it "must return a CertInfo object" do
30
+ expect(subject.cert_info).to be_kind_of(CertInfo)
31
+ end
32
+ end
33
+
34
+ describe "#compression" do
35
+ it "must parse the compressionMethod elements into a Hash" do
36
+ expect(subject.compression).to be == {deflate: false}
37
+ end
38
+ end
39
+
40
+ describe "#heartbleed?" do
41
+ it "must query isVulnerable attribute within heartbleed" do
42
+ expect(subject.heartbleed?).to be == false
43
+ end
44
+ end
45
+
46
+ describe "#session_renegotiation" do
47
+ it "should return a SessionRenegotiation object" do
48
+ expect(subject.session_renegotiation).to be_kind_of(described_class::SessionRenegotiation)
49
+ end
50
+
51
+ it "should parse the canBeClientInitiated attribute" do
52
+ expect(subject.session_renegotiation.client_initiated).to be(false)
53
+ end
54
+
55
+ it "should parse the isSecure attribute" do
56
+ expect(subject.session_renegotiation.secure).to be(true)
57
+ end
58
+ end
59
+
60
+ describe "#sslv2" do
61
+ it "must return a Protocol object" do
62
+ expect(subject.sslv2).to be_kind_of(Protocol)
63
+ end
64
+ end
65
+
66
+ describe "#sslv3" do
67
+ it "must return a Protocol object" do
68
+ expect(subject.sslv3).to be_kind_of(Protocol)
69
+ end
70
+ end
71
+
72
+ describe "#tlsv1" do
73
+ it "must return a Protocol object" do
74
+ expect(subject.tlsv1).to be_kind_of(Protocol)
75
+ end
76
+ end
77
+
78
+ describe "#tlsv1_1" do
79
+ it "must return a Protocol object" do
80
+ expect(subject.tlsv1_1).to be_kind_of(Protocol)
81
+ end
82
+ end
83
+
84
+ describe "#tlsv1_2" do
85
+ it "must return a Protocol object" do
86
+ expect(subject.tlsv1_2).to be_kind_of(Protocol)
87
+ end
88
+ end
89
+
90
+ describe "#each_ssl_protocol" do
91
+ context "when a block is given" do
92
+ it "should yield sslv2 and sslv3" do
93
+ expect { |b|
94
+ subject.each_ssl_protocol(&b)
95
+ }.to yield_successive_args(subject.sslv2, subject.sslv3)
96
+ end
97
+ end
98
+
99
+ context "when no block is given" do
100
+ it "should return an Enumerator" do
101
+ expect(subject.each_ssl_protocol).to be_kind_of(Enumerator)
102
+ end
103
+ end
104
+ end
105
+
106
+ describe "#ssl_protocols" do
107
+ it "should return sslv2 and sslv3" do
108
+ expect(subject.ssl_protocols).to be == [subject.sslv2, subject.sslv3]
109
+ end
110
+ end
111
+
112
+ describe "#each_tls_protocol" do
113
+ context "when a block is given" do
114
+ it "should yield tlsv1, tlsv1_1 and tlsv1_2" do
115
+ expect { |b|
116
+ subject.each_tls_protocol(&b)
117
+ }.to yield_successive_args(
118
+ subject.tlsv1,
119
+ subject.tlsv1_1,
120
+ subject.tlsv1_2
121
+ )
122
+ end
123
+ end
124
+
125
+ context "when no block is given" do
126
+ it "should return an Enumerator" do
127
+ expect(subject.each_tls_protocol).to be_kind_of(Enumerator)
128
+ end
129
+ end
130
+ end
131
+
132
+ describe "#tls_protocols" do
133
+ it "should return tlsv1, tlsv1_1 and tlsv1_2" do
134
+ expect(subject.tls_protocols).to be == [
135
+ subject.tlsv1,
136
+ subject.tlsv1_1,
137
+ subject.tlsv1_2
138
+ ]
139
+ end
140
+ end
141
+
142
+ describe "#each_protocol" do
143
+ context "when a block is given" do
144
+ it "should yield sslv2, sslv3, tlsv1, tlsv1_1 and tlsv1_2" do
145
+ expect { |b|
146
+ subject.each_protocol(&b)
147
+ }.to yield_successive_args(
148
+ subject.sslv2,
149
+ subject.sslv3,
150
+ subject.tlsv1,
151
+ subject.tlsv1_1,
152
+ subject.tlsv1_2
153
+ )
154
+ end
155
+ end
156
+
157
+ context "when no block is given" do
158
+ it "should return an Enumerator" do
159
+ expect(subject.each_protocol).to be_kind_of(Enumerator)
160
+ end
161
+ end
162
+ end
163
+
164
+ describe "#protocols" do
165
+ it "should return sslv2, sslv3, tlsv1, tlsv1_1 and tlsv1_2" do
166
+ expect(subject.protocols).to be == [
167
+ subject.sslv2,
168
+ subject.sslv3,
169
+ subject.tlsv1,
170
+ subject.tlsv1_1,
171
+ subject.tlsv1_2
172
+ ]
173
+ end
174
+ end
175
+
176
+ end
@@ -0,0 +1,9 @@
1
+ require 'rspec'
2
+ require 'sslyze/xml'
3
+
4
+ shared_examples_for "XML specs" do
5
+ let(:path) { File.expand_path('spec/sslyze.xml') }
6
+ let(:xml) { Nokogiri::XML(open(path)) }
7
+
8
+ subject { SSLyze::XML.new(xml) }
9
+ end
data/spec/xml_spec.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+ require 'xml_examples'
3
+ require 'sslyze/xml'
4
+
5
+ describe SSLyze::XML do
6
+ include_examples "XML specs"
7
+
8
+ describe ".parse" do
9
+ it "should parse the contents of the file" do
10
+ end
11
+ end
12
+
13
+ describe ".open" do
14
+ it "should open the XML file" do
15
+ end
16
+ end
17
+
18
+ describe "#version" do
19
+ it "must parse the SSLyzeVersion attribute" do
20
+ expect(subject.version).to be == "0.12.0"
21
+ end
22
+ end
23
+
24
+ describe "#default_timeout" do
25
+ it "must parse the defaultTimeout attribute" do
26
+ expect(subject.default_timeout).to be == 5
27
+ end
28
+ end
29
+
30
+ describe "#https_tunnel" do
31
+ it "must parse the httpsTunnel attribute" do
32
+ expect(subject.https_tunnel).to be nil
33
+ end
34
+ end
35
+
36
+ describe "#start_tls" do
37
+ it "must parse the startTLS attribute" do
38
+ expect(subject.start_tls).to be nil
39
+ end
40
+ end
41
+
42
+ describe "#total_scan_time" do
43
+ it "must parse the totalScanTime attribute" do
44
+ expect(subject.total_scan_time).to be_kind_of(Float)
45
+ expect(subject.total_scan_time).to be > 0.0
46
+ end
47
+ end
48
+
49
+ describe "#invalid_targets" do
50
+ pending "need data"
51
+ end
52
+
53
+ describe "#each_target" do
54
+ it "should iterate over each target element under results" do
55
+ expect { |b|
56
+ subject.each_target(&b)
57
+ }.to yield_successive_args(Target, Target, Target)
58
+ end
59
+ end
60
+
61
+ describe "#targets" do
62
+ it "should return an Array of Targets" do
63
+ expect(subject.targets).to be_an(Array).and(all(be_a(Target)))
64
+ end
65
+ end
66
+
67
+ describe "#target" do
68
+ it "should return the first target" do
69
+ expect(subject.target.host).to be == subject.targets.first.host
70
+ end
71
+ end
72
+ end
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-sslyze
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Hal Brodigan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rprogram
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ description: A ruby interface to the sslyze python utility
56
+ email: hal@trailofbits.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - ".document"
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
65
+ - ".yardopts"
66
+ - ChangeLog.md
67
+ - Gemfile
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - lib/sslyze.rb
72
+ - lib/sslyze/cert_info.rb
73
+ - lib/sslyze/certificate.rb
74
+ - lib/sslyze/certificate/domain_name.rb
75
+ - lib/sslyze/certificate/extensions.rb
76
+ - lib/sslyze/certificate/extensions/authority_information_access.rb
77
+ - lib/sslyze/certificate/extensions/extension.rb
78
+ - lib/sslyze/certificate/extensions/x509v3_basic_constraints.rb
79
+ - lib/sslyze/certificate/extensions/x509v3_certificate_policies.rb
80
+ - lib/sslyze/certificate/extensions/x509v3_crl_distribution_points.rb
81
+ - lib/sslyze/certificate/extensions/x509v3_extended_key_usage.rb
82
+ - lib/sslyze/certificate/extensions/x509v3_key_usage.rb
83
+ - lib/sslyze/certificate/extensions/x509v3_subject_alternative_name.rb
84
+ - lib/sslyze/certificate/issuer.rb
85
+ - lib/sslyze/certificate/public_key.rb
86
+ - lib/sslyze/certificate/subject.rb
87
+ - lib/sslyze/certificate/subject_public_key_info.rb
88
+ - lib/sslyze/certificate/validity.rb
89
+ - lib/sslyze/certificate_chain.rb
90
+ - lib/sslyze/certificate_validation.rb
91
+ - lib/sslyze/cipher_suite.rb
92
+ - lib/sslyze/key_exchange.rb
93
+ - lib/sslyze/ocsp_response.rb
94
+ - lib/sslyze/program.rb
95
+ - lib/sslyze/protocol.rb
96
+ - lib/sslyze/target.rb
97
+ - lib/sslyze/task.rb
98
+ - lib/sslyze/types.rb
99
+ - lib/sslyze/version.rb
100
+ - lib/sslyze/xml.rb
101
+ - ruby-sslyze.gemspec
102
+ - spec/cert_info_spec.rb
103
+ - spec/certificate/subject_name_spec.rb
104
+ - spec/certificate_chain_spec.rb
105
+ - spec/certificate_spec.rb
106
+ - spec/certificate_validation_spec.rb
107
+ - spec/cipher_suite_spec.rb
108
+ - spec/issuer_spec.rb
109
+ - spec/key_exchange_spec.rb
110
+ - spec/ocsp_response_spec.rb
111
+ - spec/protocol_spec.rb
112
+ - spec/spec_helper.rb
113
+ - spec/sslyze.xml
114
+ - spec/sslyze_spec.rb
115
+ - spec/subject_public_key_info_spec.rb
116
+ - spec/subject_spec.rb
117
+ - spec/target_spec.rb
118
+ - spec/xml_examples.rb
119
+ - spec/xml_spec.rb
120
+ homepage: https://github.com/trailofbits/ruby-sslyze#readme
121
+ licenses:
122
+ - MIT
123
+ metadata: {}
124
+ post_install_message:
125
+ rdoc_options: []
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubyforge_project:
140
+ rubygems_version: 2.4.5
141
+ signing_key:
142
+ specification_version: 4
143
+ summary: Ruby interface to sslyze
144
+ test_files:
145
+ - spec/cert_info_spec.rb
146
+ - spec/certificate/subject_name_spec.rb
147
+ - spec/certificate_chain_spec.rb
148
+ - spec/certificate_spec.rb
149
+ - spec/certificate_validation_spec.rb
150
+ - spec/cipher_suite_spec.rb
151
+ - spec/issuer_spec.rb
152
+ - spec/key_exchange_spec.rb
153
+ - spec/ocsp_response_spec.rb
154
+ - spec/protocol_spec.rb
155
+ - spec/spec_helper.rb
156
+ - spec/sslyze.xml
157
+ - spec/sslyze_spec.rb
158
+ - spec/subject_public_key_info_spec.rb
159
+ - spec/subject_spec.rb
160
+ - spec/target_spec.rb
161
+ - spec/xml_examples.rb
162
+ - spec/xml_spec.rb