ruby-sslyze 0.2.1 → 1.0.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.
- checksums.yaml +4 -4
- data/.gitignore +6 -4
- data/.travis.yml +15 -7
- data/ChangeLog.md +29 -12
- data/Gemfile +3 -2
- data/LICENSE.txt +1 -1
- data/README.md +5 -5
- data/Rakefile +1 -1
- data/lib/sslyze/cipher_suites.rb +176 -0
- data/lib/sslyze/program.rb +8 -8
- data/lib/sslyze/task.rb +40 -33
- data/lib/sslyze/version.rb +1 -1
- data/lib/sslyze/{certificate/domain_name.rb → x509/domain.rb} +5 -3
- data/lib/sslyze/x509/extension.rb +15 -0
- data/lib/sslyze/x509/extension_set.rb +140 -0
- data/lib/sslyze/x509/extensions.rb +6 -0
- data/lib/sslyze/x509/extensions/basic_constraints.rb +41 -0
- data/lib/sslyze/x509/extensions/certificate_policies.rb +108 -0
- data/lib/sslyze/x509/extensions/crl_distribution_points.rb +47 -0
- data/lib/sslyze/x509/extensions/extended_key_usage.rb +58 -0
- data/lib/sslyze/x509/extensions/key_usage.rb +66 -0
- data/lib/sslyze/x509/extensions/subject_alt_name.rb +144 -0
- data/lib/sslyze/x509/name.rb +194 -0
- data/lib/sslyze/x509/public_key.rb +53 -0
- data/lib/sslyze/xml.rb +26 -37
- data/lib/sslyze/xml/attributes.rb +5 -0
- data/lib/sslyze/xml/attributes/error.rb +30 -0
- data/lib/sslyze/xml/attributes/exception.rb +30 -0
- data/lib/sslyze/xml/attributes/is_supported.rb +29 -0
- data/lib/sslyze/xml/attributes/is_vulnerable.rb +29 -0
- data/lib/sslyze/xml/attributes/title.rb +31 -0
- data/lib/sslyze/xml/certinfo.rb +67 -0
- data/lib/sslyze/xml/certinfo/certificate.rb +202 -0
- data/lib/sslyze/xml/certinfo/certificate_validation.rb +69 -0
- data/lib/sslyze/xml/certinfo/certificate_validation/hostname_validation.rb +54 -0
- data/lib/sslyze/xml/certinfo/certificate_validation/path_validation.rb +84 -0
- data/lib/sslyze/xml/certinfo/certificate_validation/verified_certificate_chain.rb +41 -0
- data/lib/sslyze/xml/certinfo/has_certificates.rb +102 -0
- data/lib/sslyze/xml/certinfo/ocsp_stapling.rb +45 -0
- data/lib/sslyze/xml/certinfo/ocsp_stapling/ocsp_response.rb +87 -0
- data/lib/sslyze/xml/certinfo/received_certificate_chain.rb +48 -0
- data/lib/sslyze/xml/compression.rb +33 -0
- data/lib/sslyze/xml/compression/compression_method.rb +38 -0
- data/lib/sslyze/xml/fallback.rb +34 -0
- data/lib/sslyze/xml/fallback/tls_fallback_scsv.rb +27 -0
- data/lib/sslyze/xml/heartbleed.rb +38 -0
- data/lib/sslyze/xml/heartbleed/openssl_heartbleed.rb +29 -0
- data/lib/sslyze/xml/http_headers.rb +42 -0
- data/lib/sslyze/xml/http_headers/http_public_key_pinning.rb +121 -0
- data/lib/sslyze/xml/http_headers/http_strict_transport_security.rb +59 -0
- data/lib/sslyze/xml/invalid_target.rb +33 -0
- data/lib/sslyze/xml/openssl_ccs.rb +34 -0
- data/lib/sslyze/xml/openssl_ccs/openssl_ccs_injection.rb +26 -0
- data/lib/sslyze/xml/plugin.rb +27 -0
- data/lib/sslyze/xml/protocol.rb +143 -0
- data/lib/sslyze/xml/protocol/cipher_suite.rb +93 -0
- data/lib/sslyze/xml/protocol/cipher_suite/key_exchange.rb +127 -0
- data/lib/sslyze/xml/reneg.rb +28 -0
- data/lib/sslyze/xml/reneg/session_renegotiation.rb +51 -0
- data/lib/sslyze/xml/resum.rb +42 -0
- data/lib/sslyze/xml/resum/session_resumption_with_session_ids.rb +94 -0
- data/lib/sslyze/xml/resum/session_resumption_with_tls_tickets.rb +69 -0
- data/lib/sslyze/xml/resum_rate.rb +30 -0
- data/lib/sslyze/xml/target.rb +371 -0
- data/lib/sslyze/xml/types.rb +19 -0
- data/ruby-sslyze.gemspec +3 -3
- data/spec/spec_helper.rb +2 -4
- data/spec/sslyze.xml +2356 -2580
- data/spec/x509/domain_spec.rb +125 -0
- data/spec/x509/extension_set_spec.rb +208 -0
- data/spec/x509/extension_spec.rb +58 -0
- data/spec/x509/extensions/basic_constraints_spec.rb +41 -0
- data/spec/x509/extensions/certificate_policies_spec.rb +38 -0
- data/spec/x509/extensions/crl_distribution_points_spec.rb +38 -0
- data/spec/x509/extensions/extended_key_usage_spec.rb +58 -0
- data/spec/x509/extensions/key_usage_spec.rb +84 -0
- data/spec/x509/extensions/subject_alt_name_spec.rb +146 -0
- data/spec/x509/name_spec.rb +85 -0
- data/spec/x509/public_key_spec.rb +113 -0
- data/spec/xml/certinfo/certificate_spec.rb +166 -0
- data/spec/xml/certinfo/certificate_validation/hostname_validation_spec.rb +23 -0
- data/spec/xml/certinfo/certificate_validation/path_validation_spec.rb +107 -0
- data/spec/xml/certinfo/certificate_validation/verified_certificate_chain_spec.rb +163 -0
- data/spec/xml/certinfo/certificate_validation_spec.rb +40 -0
- data/spec/xml/certinfo/ocsp_stapling/ocsp_response_spec.rb +61 -0
- data/spec/xml/certinfo/ocsp_stapling_spec.rb +31 -0
- data/spec/xml/certinfo/received_certificate_chain_spec.rb +165 -0
- data/spec/xml/certinfo_spec.rb +45 -0
- data/spec/xml/compression/compression_method_spec.rb +23 -0
- data/spec/xml/compression_spec.rb +23 -0
- data/spec/xml/heartbleed/openssl_heartbleed_spec.rb +17 -0
- data/spec/xml/heartbleed_spec.rb +37 -0
- data/spec/xml/http_headers/http_public_key_pinning_spec.rb +73 -0
- data/spec/xml/http_headers/http_strict_transport_security_spec.rb +107 -0
- data/spec/xml/http_headers_spec.rb +63 -0
- data/spec/xml/invalid_target_spec.rb +23 -0
- data/spec/xml/plugin_examples.rb +14 -0
- data/spec/{key_exchange_spec.rb → xml/protocol/cipher_suite/key_exchange_spec.rb} +9 -3
- data/spec/xml/protocol/cipher_suite_spec.rb +66 -0
- data/spec/xml/protocol_spec.rb +115 -0
- data/spec/xml/reneg/session_renegotiation_spec.rb +23 -0
- data/spec/xml/reneg_spec.rb +35 -0
- data/spec/xml/resum/session_resumption_with_session_ids_spec.rb +103 -0
- data/spec/xml/resum/session_resumption_with_tls_tickets_spec.rb +121 -0
- data/spec/xml/resum_rate_spec.rb +30 -0
- data/spec/xml/resum_spec.rb +47 -0
- data/spec/{target_spec.rb → xml/target_spec.rb} +73 -27
- data/spec/xml_spec.rb +13 -21
- metadata +138 -61
- data/lib/sslyze/cert_info.rb +0 -57
- data/lib/sslyze/certificate.rb +0 -139
- data/lib/sslyze/certificate/extensions.rb +0 -127
- data/lib/sslyze/certificate/extensions/authority_information_access.rb +0 -38
- data/lib/sslyze/certificate/extensions/extension.rb +0 -26
- data/lib/sslyze/certificate/extensions/x509v3_basic_constraints.rb +0 -60
- data/lib/sslyze/certificate/extensions/x509v3_certificate_policies.rb +0 -50
- data/lib/sslyze/certificate/extensions/x509v3_crl_distribution_points.rb +0 -32
- data/lib/sslyze/certificate/extensions/x509v3_extended_key_usage.rb +0 -32
- data/lib/sslyze/certificate/extensions/x509v3_key_usage.rb +0 -50
- data/lib/sslyze/certificate/extensions/x509v3_subject_alternative_name.rb +0 -71
- data/lib/sslyze/certificate/issuer.rb +0 -56
- data/lib/sslyze/certificate/public_key.rb +0 -9
- data/lib/sslyze/certificate/subject.rb +0 -117
- data/lib/sslyze/certificate/subject_public_key_info.rb +0 -53
- data/lib/sslyze/certificate/validity.rb +0 -9
- data/lib/sslyze/certificate_chain.rb +0 -89
- data/lib/sslyze/certificate_validation.rb +0 -70
- data/lib/sslyze/cipher_suite.rb +0 -237
- data/lib/sslyze/invalid_target.rb +0 -35
- data/lib/sslyze/key_exchange.rb +0 -106
- data/lib/sslyze/ocsp_response.rb +0 -87
- data/lib/sslyze/protocol.rb +0 -133
- data/lib/sslyze/target.rb +0 -312
- data/lib/sslyze/types.rb +0 -17
- data/spec/cert_info_spec.rb +0 -29
- data/spec/certificate/subject_name_spec.rb +0 -72
- data/spec/certificate_chain_spec.rb +0 -61
- data/spec/certificate_spec.rb +0 -330
- data/spec/certificate_validation_spec.rb +0 -39
- data/spec/cipher_suite_spec.rb +0 -50
- data/spec/invalid_target_spec.rb +0 -21
- data/spec/issuer_spec.rb +0 -33
- data/spec/ocsp_response_spec.rb +0 -59
- data/spec/protocol_spec.rb +0 -99
- data/spec/subject_public_key_info_spec.rb +0 -35
- data/spec/subject_spec.rb +0 -69
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'sslyze/xml/plugin'
|
|
2
|
+
require 'sslyze/xml/reneg/session_renegotiation'
|
|
3
|
+
|
|
4
|
+
module SSLyze
|
|
5
|
+
class XML
|
|
6
|
+
#
|
|
7
|
+
# Represents the `<reneg>` element.
|
|
8
|
+
#
|
|
9
|
+
# @since 1.0.0
|
|
10
|
+
#
|
|
11
|
+
class Reneg < Plugin
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
# Session Renegotiation information.
|
|
15
|
+
#
|
|
16
|
+
# @return [SessionRenegotiation, nil]
|
|
17
|
+
#
|
|
18
|
+
def session_renegotiation
|
|
19
|
+
@session_renegotiation ||= if (element = @node.at_xpath('sessionRenegotiation'))
|
|
20
|
+
SessionRenegotiation.new(element)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
alias session session_renegotiation
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'sslyze/xml/plugin'
|
|
2
|
+
require 'sslyze/xml/types'
|
|
3
|
+
|
|
4
|
+
module SSLyze
|
|
5
|
+
class XML
|
|
6
|
+
class Reneg < Plugin
|
|
7
|
+
#
|
|
8
|
+
# Represents the `<sessionRenegotiation>` XML element.
|
|
9
|
+
#
|
|
10
|
+
# @since 1.0.0
|
|
11
|
+
#
|
|
12
|
+
class SessionRenegotiation
|
|
13
|
+
|
|
14
|
+
include Types
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Initializes the {SessionRenegotiation} object.
|
|
18
|
+
#
|
|
19
|
+
# @param [Nokogiri::XML::Element] node
|
|
20
|
+
# The `<sessionRenegotiation>` XML element.
|
|
21
|
+
#
|
|
22
|
+
def initialize(node)
|
|
23
|
+
@node = node
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# Returns the `canBeClientInitiated` attribute.
|
|
28
|
+
#
|
|
29
|
+
# @return [Boolean]
|
|
30
|
+
#
|
|
31
|
+
def can_be_client_initiated?
|
|
32
|
+
Boolean[@node['canBeClientInitiated']]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
alias client_initiated? can_be_client_initiated?
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
# Returns the `isSecure` attribute.
|
|
39
|
+
#
|
|
40
|
+
# @return [Boolean]
|
|
41
|
+
#
|
|
42
|
+
def is_secure?
|
|
43
|
+
Boolean[@node['isSecure']]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
alias secure? is_secure?
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'sslyze/xml/plugin'
|
|
2
|
+
require 'sslyze/xml/resum/session_resumption_with_session_ids'
|
|
3
|
+
require 'sslyze/xml/resum/session_resumption_with_tls_tickets'
|
|
4
|
+
|
|
5
|
+
module SSLyze
|
|
6
|
+
class XML
|
|
7
|
+
#
|
|
8
|
+
# Represents the `<resum>` XML element.
|
|
9
|
+
#
|
|
10
|
+
# @since 1.0.0
|
|
11
|
+
#
|
|
12
|
+
class Resum < Plugin
|
|
13
|
+
|
|
14
|
+
#
|
|
15
|
+
# Parses the `<sessionResumptionWithSessionIDs>` XML element.
|
|
16
|
+
#
|
|
17
|
+
# @return [SessionResumptionWithSessionIDs, nil]
|
|
18
|
+
#
|
|
19
|
+
def session_resumption_with_session_ids
|
|
20
|
+
@session_resumption_with_session_ids ||= if (element = @node.at_xpath('sessionResumptionWithSessionIDs'))
|
|
21
|
+
SessionResumptionWithSessionIDs.new(element)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
alias with_session_ids session_resumption_with_session_ids
|
|
26
|
+
|
|
27
|
+
#
|
|
28
|
+
# Parses the `<sessionResumptionWithTLSTickets>` XML element.
|
|
29
|
+
#
|
|
30
|
+
# @return [SessionResumptionWithTLSTickets, nil]
|
|
31
|
+
#
|
|
32
|
+
def session_resumption_with_tls_tickets
|
|
33
|
+
@session_resumption_with_tls_tickets ||= if (element = @node.at_xpath('sessionResumptionWithTLSTickets'))
|
|
34
|
+
SessionResumptionWithTLSTickets.new(element)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
alias with_tls_tickets session_resumption_with_tls_tickets
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require 'sslyze/xml/plugin'
|
|
2
|
+
require 'sslyze/xml/types'
|
|
3
|
+
require 'sslyze/xml/attributes/is_supported'
|
|
4
|
+
|
|
5
|
+
module SSLyze
|
|
6
|
+
class XML
|
|
7
|
+
class Resum < Plugin
|
|
8
|
+
#
|
|
9
|
+
# Represents the `<sessionResumptionWithSessionIDs>` XML element.
|
|
10
|
+
#
|
|
11
|
+
# @since 1.0.0
|
|
12
|
+
#
|
|
13
|
+
class SessionResumptionWithSessionIDs
|
|
14
|
+
|
|
15
|
+
include Types
|
|
16
|
+
include Attributes::IsSupported
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# Initializes the {SessionResumptionWithSessionIDs} object.
|
|
20
|
+
#
|
|
21
|
+
# @param [Nokogiri::XML::Element] node
|
|
22
|
+
# The `<sessionResumptionWithSessionIDs>` XML element.
|
|
23
|
+
#
|
|
24
|
+
def initialize(node)
|
|
25
|
+
@node = node
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#
|
|
29
|
+
# Number of failed attempts.
|
|
30
|
+
#
|
|
31
|
+
# @return [Integer]
|
|
32
|
+
#
|
|
33
|
+
def failed_attempts
|
|
34
|
+
@failed_attempts ||= @node['failedAttempts'].to_i
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
# Number of successful attempts.
|
|
39
|
+
#
|
|
40
|
+
# @return [Integer]
|
|
41
|
+
#
|
|
42
|
+
def successful_attempts
|
|
43
|
+
@successful_attempts ||= @node['successfulAttempts'].to_i
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
# Number of total attempts.
|
|
48
|
+
#
|
|
49
|
+
# @return [Integer]
|
|
50
|
+
#
|
|
51
|
+
def total_attempts
|
|
52
|
+
@total_attempts ||= @node['totalAttempts'].to_i
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
#
|
|
56
|
+
# The number of errors that occurred.
|
|
57
|
+
#
|
|
58
|
+
# @return [Integer]
|
|
59
|
+
#
|
|
60
|
+
def error_count
|
|
61
|
+
@error_count ||= @node['errors'].to_i
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# Enumerates over each error message.
|
|
66
|
+
#
|
|
67
|
+
# @yield [error]
|
|
68
|
+
#
|
|
69
|
+
# @yieldparam [String] error
|
|
70
|
+
#
|
|
71
|
+
# @return [Enumerator]
|
|
72
|
+
# An enumerator will be returned if no block was given.
|
|
73
|
+
#
|
|
74
|
+
def each_error
|
|
75
|
+
return enum_for(__method__) unless block_given?
|
|
76
|
+
|
|
77
|
+
@node.xpath('error').each do |error|
|
|
78
|
+
yield error.inner_text
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
#
|
|
83
|
+
# All error messages.
|
|
84
|
+
#
|
|
85
|
+
# @return [Array<String>]
|
|
86
|
+
#
|
|
87
|
+
def errors
|
|
88
|
+
each_error.to_a
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'sslyze/xml/plugin'
|
|
2
|
+
require 'sslyze/xml/types'
|
|
3
|
+
require 'sslyze/xml/attributes/is_supported'
|
|
4
|
+
require 'sslyze/xml/attributes/error'
|
|
5
|
+
|
|
6
|
+
module SSLyze
|
|
7
|
+
class XML
|
|
8
|
+
class Resum < Plugin
|
|
9
|
+
#
|
|
10
|
+
# Represents the `<sessionResumptionWithTLSTickets>` XML element.
|
|
11
|
+
#
|
|
12
|
+
# @since 1.0.0
|
|
13
|
+
#
|
|
14
|
+
class SessionResumptionWithTLSTickets
|
|
15
|
+
|
|
16
|
+
include Types
|
|
17
|
+
include Attributes::IsSupported
|
|
18
|
+
include Attributes::Error
|
|
19
|
+
|
|
20
|
+
#
|
|
21
|
+
# Initializes the {SessionResumptionWithTLSTickets} object.
|
|
22
|
+
#
|
|
23
|
+
# @param [Nokogiri::XML::Element] node
|
|
24
|
+
# The `<sessionResumptionWithTLSTickets>` XML element.
|
|
25
|
+
#
|
|
26
|
+
def initialize(node)
|
|
27
|
+
@node = node
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
#
|
|
31
|
+
# Returns the `error` attribute.
|
|
32
|
+
#
|
|
33
|
+
# @return [String, nil]
|
|
34
|
+
#
|
|
35
|
+
def error
|
|
36
|
+
@error ||= @node['error']
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
# Determines if there was an error.
|
|
41
|
+
#
|
|
42
|
+
# @return [Boolean]
|
|
43
|
+
#
|
|
44
|
+
def error?
|
|
45
|
+
!error.nil?
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
#
|
|
49
|
+
# Returns the descriptive reason.
|
|
50
|
+
#
|
|
51
|
+
# @return [String, nil]
|
|
52
|
+
#
|
|
53
|
+
def reason
|
|
54
|
+
@reason ||= @node['reason']
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
# Converts the element to a String.
|
|
59
|
+
#
|
|
60
|
+
# @return [String]
|
|
61
|
+
#
|
|
62
|
+
def to_s
|
|
63
|
+
reason || ''
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'sslyze/xml/plugin'
|
|
2
|
+
require 'sslyze/xml/resum/session_resumption_with_session_ids'
|
|
3
|
+
|
|
4
|
+
module SSLyze
|
|
5
|
+
class XML
|
|
6
|
+
#
|
|
7
|
+
# Represents the `<resum_rate/>` XML element.
|
|
8
|
+
#
|
|
9
|
+
# @since 1.0.0
|
|
10
|
+
#
|
|
11
|
+
class ResumRate < Plugin
|
|
12
|
+
|
|
13
|
+
SessionResumptionWithSessionIDs = Resum::SessionResumptionWithSessionIDs
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# Parses the `<sessionResumptionWithSessionIDs/>` XML element.
|
|
17
|
+
#
|
|
18
|
+
# @return [SessionResumptionWithSessionIDs, nil]
|
|
19
|
+
#
|
|
20
|
+
def session_resumption_with_session_ids
|
|
21
|
+
@session_resumption_with_session_ids ||= if (element = @node.at('sessionResumptionWithSessionIDs'))
|
|
22
|
+
SessionResumptionWithSessionIDs.new(element)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
alias with_session_ids session_resumption_with_session_ids
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
require 'sslyze/xml/types'
|
|
2
|
+
require 'sslyze/xml/certinfo'
|
|
3
|
+
require 'sslyze/xml/compression'
|
|
4
|
+
require 'sslyze/xml/heartbleed'
|
|
5
|
+
require 'sslyze/xml/http_headers'
|
|
6
|
+
require 'sslyze/xml/reneg'
|
|
7
|
+
require 'sslyze/xml/resum'
|
|
8
|
+
require 'sslyze/xml/resum_rate'
|
|
9
|
+
require 'sslyze/xml/protocol'
|
|
10
|
+
require 'sslyze/xml/fallback'
|
|
11
|
+
require 'sslyze/xml/openssl_ccs'
|
|
12
|
+
|
|
13
|
+
require 'ipaddr'
|
|
14
|
+
|
|
15
|
+
module SSLyze
|
|
16
|
+
class XML
|
|
17
|
+
#
|
|
18
|
+
# Represents the `<target>` XML element.
|
|
19
|
+
#
|
|
20
|
+
class Target
|
|
21
|
+
|
|
22
|
+
include Types
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# Initializes the target.
|
|
26
|
+
#
|
|
27
|
+
# @param [Nokogiri::XML::Node] node
|
|
28
|
+
# The `<target>` XML element.
|
|
29
|
+
#
|
|
30
|
+
def initialize(node)
|
|
31
|
+
@node = node
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# The host name of the target.
|
|
36
|
+
#
|
|
37
|
+
# @return [String]
|
|
38
|
+
#
|
|
39
|
+
def host
|
|
40
|
+
@host ||= @node['host']
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
#
|
|
44
|
+
# The IP address of the target.
|
|
45
|
+
#
|
|
46
|
+
# @return [String]
|
|
47
|
+
#
|
|
48
|
+
def ip
|
|
49
|
+
@ip ||= @node['ip']
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
# The IP address of the target.
|
|
54
|
+
#
|
|
55
|
+
# @return [IPAddr]
|
|
56
|
+
#
|
|
57
|
+
# @since 1.0.0
|
|
58
|
+
#
|
|
59
|
+
def ipaddr
|
|
60
|
+
IPAddr.new(ip)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
#
|
|
64
|
+
# The port number that was scanned.
|
|
65
|
+
#
|
|
66
|
+
# @return [Integer]
|
|
67
|
+
#
|
|
68
|
+
def port
|
|
69
|
+
@port ||= @node['port'].to_i
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
#
|
|
73
|
+
# Which compression algorithms are supported.
|
|
74
|
+
#
|
|
75
|
+
# @return [Compression, nil]
|
|
76
|
+
#
|
|
77
|
+
def compression
|
|
78
|
+
@compression ||= if (element = @node.at_xpath('compression'))
|
|
79
|
+
Compression.new(element)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# Certificate information.
|
|
85
|
+
#
|
|
86
|
+
# @return [Certinfo, nil]
|
|
87
|
+
#
|
|
88
|
+
# @since 1.0.0
|
|
89
|
+
#
|
|
90
|
+
def certinfo
|
|
91
|
+
@cert_info ||= if (element = @node.at_xpath('certinfo'))
|
|
92
|
+
Certinfo.new(element)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
alias cert_info certinfo
|
|
97
|
+
|
|
98
|
+
#
|
|
99
|
+
# @return [Heartbleed, nil]
|
|
100
|
+
#
|
|
101
|
+
# @since 1.0.0
|
|
102
|
+
#
|
|
103
|
+
def heartbleed
|
|
104
|
+
@heartbleed ||= if (element = @node.at_xpath('heartbleed'))
|
|
105
|
+
Heartbleed.new(element)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
#
|
|
110
|
+
# @return [HTTPHeaders, nil]
|
|
111
|
+
#
|
|
112
|
+
# @since 1.0.0
|
|
113
|
+
#
|
|
114
|
+
def http_headers
|
|
115
|
+
@http_headers ||= if (element = @node.at_xpath('http_headers'))
|
|
116
|
+
HTTPHeaders.new(element)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
#
|
|
121
|
+
# Specifies whether the service supports Session Renegotiation.
|
|
122
|
+
#
|
|
123
|
+
# @return [Reneg, nil]
|
|
124
|
+
#
|
|
125
|
+
# @since 1.0.0
|
|
126
|
+
#
|
|
127
|
+
def reneg
|
|
128
|
+
@reneg ||= if (element = @node.at_xpath('reneg'))
|
|
129
|
+
Reneg.new(element)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
alias session_renegotiation reneg
|
|
134
|
+
|
|
135
|
+
#
|
|
136
|
+
# @return [Resum, nil]
|
|
137
|
+
#
|
|
138
|
+
# @since 1.0.0
|
|
139
|
+
#
|
|
140
|
+
def resum
|
|
141
|
+
@resum ||= if (element = @node.at_xpath('resum'))
|
|
142
|
+
Resum.new(element)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
alias session_resumption resum
|
|
147
|
+
|
|
148
|
+
#
|
|
149
|
+
# @return [Resum, nil]
|
|
150
|
+
#
|
|
151
|
+
# @since 1.0.0
|
|
152
|
+
#
|
|
153
|
+
def resum_rate
|
|
154
|
+
@resum ||= if (element = @node.at_xpath('resum_rate'))
|
|
155
|
+
ResumRate.new(element)
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
alias session_resumption resum_rate
|
|
160
|
+
|
|
161
|
+
#
|
|
162
|
+
# SSLv2 protocol information.
|
|
163
|
+
#
|
|
164
|
+
# @return [Protocol, nil]
|
|
165
|
+
#
|
|
166
|
+
def sslv2
|
|
167
|
+
@sslv2 ||= if (element = @node.at_xpath('sslv2'))
|
|
168
|
+
Protocol.new(element)
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
alias ssl_v2 sslv2
|
|
173
|
+
|
|
174
|
+
#
|
|
175
|
+
# SSLv3 protocol information.
|
|
176
|
+
#
|
|
177
|
+
# @return [Protocol, nil]
|
|
178
|
+
#
|
|
179
|
+
def sslv3
|
|
180
|
+
@sslv3 ||= if (element = @node.at_xpath('sslv3'))
|
|
181
|
+
Protocol.new(element)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
alias ssl_v3 sslv3
|
|
186
|
+
|
|
187
|
+
#
|
|
188
|
+
# TLSv1 protocol information.
|
|
189
|
+
#
|
|
190
|
+
# @return [Protocol, nil]
|
|
191
|
+
#
|
|
192
|
+
def tlsv1
|
|
193
|
+
@tlsv1 ||= if (element = @node.at_xpath('tlsv1'))
|
|
194
|
+
Protocol.new(element)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
alias tls_v1 tlsv1
|
|
199
|
+
|
|
200
|
+
#
|
|
201
|
+
# TLSv1.1 protocol information.
|
|
202
|
+
#
|
|
203
|
+
# @return [Protocol, nil]
|
|
204
|
+
#
|
|
205
|
+
def tlsv1_1
|
|
206
|
+
@tlsv1_1 ||= if (element = @node.at_xpath('tlsv1_1'))
|
|
207
|
+
Protocol.new(element)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
alias tls_v1_1 tlsv1_1
|
|
212
|
+
|
|
213
|
+
#
|
|
214
|
+
# TLSv1.2 protocol information.
|
|
215
|
+
#
|
|
216
|
+
# @return [Protocol, nil]
|
|
217
|
+
#
|
|
218
|
+
def tlsv1_2
|
|
219
|
+
@tlsv1_2 ||= if (element = @node.at_xpath('tlsv1_2'))
|
|
220
|
+
Protocol.new(element)
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
alias tls_v1_2 tlsv1_2
|
|
225
|
+
|
|
226
|
+
#
|
|
227
|
+
# Iterates over every SSL protocol.
|
|
228
|
+
#
|
|
229
|
+
# @yield [protocol]
|
|
230
|
+
# The given block will be passed each SSL protocol.
|
|
231
|
+
#
|
|
232
|
+
# @yieldparam [Protocol] protocol
|
|
233
|
+
# A SSL protocol.
|
|
234
|
+
#
|
|
235
|
+
# @return [Enumerator]
|
|
236
|
+
# If a no block was given, an Enumerator will be returned.
|
|
237
|
+
#
|
|
238
|
+
# @see #sslv2
|
|
239
|
+
# @see #sslv3
|
|
240
|
+
#
|
|
241
|
+
def each_ssl_protocol
|
|
242
|
+
return enum_for(__method__) unless block_given?
|
|
243
|
+
|
|
244
|
+
yield sslv2 if sslv2
|
|
245
|
+
yield sslv3 if sslv3
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
#
|
|
249
|
+
# All supported SSL protocols.
|
|
250
|
+
#
|
|
251
|
+
# @return [Array<Protocol>]
|
|
252
|
+
#
|
|
253
|
+
def ssl_protocols
|
|
254
|
+
each_ssl_protocol.to_a
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
#
|
|
258
|
+
# Iterates over every TLS protocol.
|
|
259
|
+
#
|
|
260
|
+
# @yield [protocol]
|
|
261
|
+
# The given block will be passed each TLS protocol.
|
|
262
|
+
#
|
|
263
|
+
# @yieldparam [Protocol] protocol
|
|
264
|
+
# A TLS protocol.
|
|
265
|
+
#
|
|
266
|
+
# @return [Enumerator]
|
|
267
|
+
# If a no block was given, an Enumerator will be returned.
|
|
268
|
+
#
|
|
269
|
+
# @see #tlsv1
|
|
270
|
+
# @see #tlsv1_1
|
|
271
|
+
# @see #tlsv1_2
|
|
272
|
+
#
|
|
273
|
+
def each_tls_protocol
|
|
274
|
+
return enum_for(__method__) unless block_given?
|
|
275
|
+
|
|
276
|
+
yield tlsv1 if tlsv1
|
|
277
|
+
yield tlsv1_1 if tlsv1_1
|
|
278
|
+
yield tlsv1_2 if tlsv1_2
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
#
|
|
282
|
+
# All supported TLS protocols.
|
|
283
|
+
#
|
|
284
|
+
# @return [Array<Protocol>]
|
|
285
|
+
#
|
|
286
|
+
def tls_protocols
|
|
287
|
+
each_tls_protocol.to_a
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
#
|
|
291
|
+
# Iterates over every SSL/TLS protocol.
|
|
292
|
+
#
|
|
293
|
+
# @yield [protocol]
|
|
294
|
+
# The given block will be passed each SSL/TLS protocol.
|
|
295
|
+
#
|
|
296
|
+
# @yieldparam [Protocol] protocol
|
|
297
|
+
# A SSL/TLS protocol.
|
|
298
|
+
#
|
|
299
|
+
# @return [Enumerator]
|
|
300
|
+
# If a no block was given, an Enumerator will be returned.
|
|
301
|
+
#
|
|
302
|
+
# @see #sslv2
|
|
303
|
+
# @see #sslv3
|
|
304
|
+
# @see #tlsv1
|
|
305
|
+
# @see #tlsv1_1
|
|
306
|
+
# @see #tlsv1_2
|
|
307
|
+
#
|
|
308
|
+
def each_protocol(&block)
|
|
309
|
+
return enum_for(__method__) unless block
|
|
310
|
+
|
|
311
|
+
each_ssl_protocol(&block)
|
|
312
|
+
each_tls_protocol(&block)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
#
|
|
316
|
+
# All supported SSL/TLS protocols.
|
|
317
|
+
#
|
|
318
|
+
# @return [Array<Protocol>]
|
|
319
|
+
#
|
|
320
|
+
def protocols
|
|
321
|
+
each_protocol.to_a
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
#
|
|
325
|
+
# @return [Fallback, nil]
|
|
326
|
+
#
|
|
327
|
+
# @since 1.0.0
|
|
328
|
+
#
|
|
329
|
+
def fallback
|
|
330
|
+
@fallback ||= if (element = @node.at_xpath('fallback'))
|
|
331
|
+
Fallback.new(element)
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
#
|
|
336
|
+
# @return [OpenSSLCCS, nil]
|
|
337
|
+
#
|
|
338
|
+
# @since 1.0.0
|
|
339
|
+
#
|
|
340
|
+
def openssl_ccs
|
|
341
|
+
@openssl_ccs ||= if (element = @node.at_xpath('openssl_ccs'))
|
|
342
|
+
OpenSSLCCS.new(element)
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
#
|
|
347
|
+
# Convert the target to a String.
|
|
348
|
+
#
|
|
349
|
+
# @return [String]
|
|
350
|
+
# The host and port.
|
|
351
|
+
#
|
|
352
|
+
def to_s
|
|
353
|
+
"#{host}:#{port}"
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
#
|
|
357
|
+
# Compares the other target to this target.
|
|
358
|
+
#
|
|
359
|
+
# @param [Target] other
|
|
360
|
+
# The other target.
|
|
361
|
+
#
|
|
362
|
+
# @return [Boolean]
|
|
363
|
+
# Whether the other target has the same {#host} and {#port}.
|
|
364
|
+
#
|
|
365
|
+
def ==(other)
|
|
366
|
+
other.kind_of?(self.class) && other.host == host && other.port == port
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
end
|