ruby-sslyze 0.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.
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