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.
- checksums.yaml +7 -0
- data/.document +3 -0
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/.travis.yml +19 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +8 -0
- data/Gemfile +18 -0
- data/LICENSE.txt +20 -0
- data/README.md +70 -0
- data/Rakefile +23 -0
- data/lib/sslyze.rb +3 -0
- data/lib/sslyze/cert_info.rb +55 -0
- data/lib/sslyze/certificate.rb +139 -0
- data/lib/sslyze/certificate/domain_name.rb +77 -0
- data/lib/sslyze/certificate/extensions.rb +127 -0
- data/lib/sslyze/certificate/extensions/authority_information_access.rb +38 -0
- data/lib/sslyze/certificate/extensions/extension.rb +26 -0
- data/lib/sslyze/certificate/extensions/x509v3_basic_constraints.rb +60 -0
- data/lib/sslyze/certificate/extensions/x509v3_certificate_policies.rb +50 -0
- data/lib/sslyze/certificate/extensions/x509v3_crl_distribution_points.rb +32 -0
- data/lib/sslyze/certificate/extensions/x509v3_extended_key_usage.rb +32 -0
- data/lib/sslyze/certificate/extensions/x509v3_key_usage.rb +50 -0
- data/lib/sslyze/certificate/extensions/x509v3_subject_alternative_name.rb +71 -0
- data/lib/sslyze/certificate/issuer.rb +56 -0
- data/lib/sslyze/certificate/public_key.rb +9 -0
- data/lib/sslyze/certificate/subject.rb +117 -0
- data/lib/sslyze/certificate/subject_public_key_info.rb +53 -0
- data/lib/sslyze/certificate/validity.rb +9 -0
- data/lib/sslyze/certificate_chain.rb +89 -0
- data/lib/sslyze/certificate_validation.rb +44 -0
- data/lib/sslyze/cipher_suite.rb +237 -0
- data/lib/sslyze/key_exchange.rb +106 -0
- data/lib/sslyze/ocsp_response.rb +87 -0
- data/lib/sslyze/program.rb +66 -0
- data/lib/sslyze/protocol.rb +133 -0
- data/lib/sslyze/target.rb +295 -0
- data/lib/sslyze/task.rb +65 -0
- data/lib/sslyze/types.rb +17 -0
- data/lib/sslyze/version.rb +4 -0
- data/lib/sslyze/xml.rb +139 -0
- data/ruby-sslyze.gemspec +24 -0
- data/spec/cert_info_spec.rb +29 -0
- data/spec/certificate/subject_name_spec.rb +72 -0
- data/spec/certificate_chain_spec.rb +61 -0
- data/spec/certificate_spec.rb +330 -0
- data/spec/certificate_validation_spec.rb +27 -0
- data/spec/cipher_suite_spec.rb +50 -0
- data/spec/issuer_spec.rb +33 -0
- data/spec/key_exchange_spec.rb +97 -0
- data/spec/ocsp_response_spec.rb +59 -0
- data/spec/protocol_spec.rb +99 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/sslyze.xml +2798 -0
- data/spec/sslyze_spec.rb +8 -0
- data/spec/subject_public_key_info_spec.rb +35 -0
- data/spec/subject_spec.rb +67 -0
- data/spec/target_spec.rb +176 -0
- data/spec/xml_examples.rb +9 -0
- data/spec/xml_spec.rb +72 -0
- metadata +162 -0
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'sslyze/certificate/extensions/authority_information_access'
|
2
|
+
require 'sslyze/certificate/extensions/x509v3_crl_distribution_points'
|
3
|
+
require 'sslyze/certificate/extensions/x509v3_key_usage'
|
4
|
+
require 'sslyze/certificate/extensions/x509v3_extended_key_usage'
|
5
|
+
require 'sslyze/certificate/extensions/x509v3_subject_alternative_name'
|
6
|
+
require 'sslyze/certificate/extensions/x509v3_basic_constraints'
|
7
|
+
require 'sslyze/certificate/extensions/x509v3_certificate_policies'
|
8
|
+
|
9
|
+
module SSLyze
|
10
|
+
class Certificate
|
11
|
+
#
|
12
|
+
# Represents the `<extensions>` XML element.
|
13
|
+
#
|
14
|
+
class Extensions
|
15
|
+
|
16
|
+
#
|
17
|
+
# Initializes the extensions.
|
18
|
+
#
|
19
|
+
# @param [Nokogiri::XML::Node] node
|
20
|
+
# The `<extensions>` XML element.
|
21
|
+
#
|
22
|
+
def initialize(node)
|
23
|
+
@node = node
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# The x509v3 subject key identifier information.
|
28
|
+
#
|
29
|
+
# @return [String, nil]
|
30
|
+
#
|
31
|
+
def x509v3_subject_key_identifier
|
32
|
+
@x509v3_subject_key_identifier ||= if (node = @node.at('X509v3SubjectKeyIdentifier'))
|
33
|
+
node.inner_text
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# The authority information access.
|
39
|
+
#
|
40
|
+
# @return [AuthorityInformationAccess, nil]
|
41
|
+
#
|
42
|
+
def authority_information_access
|
43
|
+
@authority_information_access ||= if (node = @node.at('AuthorityInformationAccess'))
|
44
|
+
AuthorityInformationAccess.new(node)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# The x509v3 CRL Distribution Points.
|
50
|
+
#
|
51
|
+
# @return [X509v3CRLDistributionPoints, nil]
|
52
|
+
#
|
53
|
+
def x509v3_crl_distribution_points
|
54
|
+
@x509v3_crl_distribution_points ||= if (node = @node.at('X509v3CRLDistributionPoints'))
|
55
|
+
X509v3CRLDistributionPoints.new(node)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# The x509v3 basic constraints.
|
61
|
+
#
|
62
|
+
# @return [X509v3BasicConstraints, nil]
|
63
|
+
#
|
64
|
+
def x509v3_basic_constraints
|
65
|
+
@x509v3_basic_constraints ||= if (constraints = @node.at('X509v3BasicConstraints'))
|
66
|
+
X509v3BasicConstraints.new(constraints)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# x509v3 key usage.
|
72
|
+
#
|
73
|
+
# @return [X509v3KeyUsage, nil]
|
74
|
+
#
|
75
|
+
def x509v3_key_usage
|
76
|
+
@x509v3_key_usage ||= if (node = @node.at('X509v3KeyUsage'))
|
77
|
+
X509v3KeyUsage.new(node)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# x509v3 extended key usage.
|
83
|
+
#
|
84
|
+
# @return [X509v3ExtendedKeyUsage, nil]
|
85
|
+
#
|
86
|
+
def x509v3_extended_key_usage
|
87
|
+
@x509v3_extended_key_usage ||= if (node = @node.at('X509v3ExtendedKeyUsage'))
|
88
|
+
X509v3ExtendedKeyUsage.new(node)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# x509v3 subject alternative name.
|
94
|
+
#
|
95
|
+
# @return [X509v3SubjectAlternativeName, nil]
|
96
|
+
#
|
97
|
+
def x509v3_subject_alternative_name
|
98
|
+
@x509v3_subject_alternative_name ||= if (node = @node.search('X509v3SubjectAlternativeName'))
|
99
|
+
X509v3SubjectAlternativeName.new(node)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# x509v3 authority key identifier.
|
105
|
+
#
|
106
|
+
# @return [String, nil]
|
107
|
+
#
|
108
|
+
def x509v3_authority_key_identifier
|
109
|
+
@x509v3_authority_key_identifier ||= if (node = @node.at('X509v3AuthorityKeyIdentifier'))
|
110
|
+
node.inner_text
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
#
|
115
|
+
# x509v3 certificate policies.
|
116
|
+
#
|
117
|
+
# @return [X509v3CertificatePolicies, nil]
|
118
|
+
#
|
119
|
+
def x509v3_certificate_policies
|
120
|
+
@x509v3_certificate_policies ||= if (node = @node.at('X509v3CertificatePolicies'))
|
121
|
+
X509v3CertificatePolicies.new(node)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'sslyze/certificate/extensions/extension'
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module SSLyze
|
6
|
+
class Certificate
|
7
|
+
class Extensions
|
8
|
+
#
|
9
|
+
# Represents the `<AuthorityInformationAccess>` XML element.
|
10
|
+
#
|
11
|
+
class AuthorityInformationAccess < Extension
|
12
|
+
|
13
|
+
#
|
14
|
+
# The CA issuers.
|
15
|
+
#
|
16
|
+
# @return [Array<URI>]
|
17
|
+
#
|
18
|
+
def ca_issuers
|
19
|
+
@ca_issuers ||= @node.search('CAIssuers/URI/listEntry').map do |uri|
|
20
|
+
URI(uri.inner_text)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# The OCSP URIs.
|
26
|
+
#
|
27
|
+
# @return [Array<URI>]
|
28
|
+
#
|
29
|
+
def ocsp
|
30
|
+
@ocsp ||= @node.search('OCSP/URI/listEntry').map do |uri|
|
31
|
+
URI(uri.inner_text)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SSLyze
|
2
|
+
class Certificate
|
3
|
+
class Extensions
|
4
|
+
#
|
5
|
+
# Represents a SSL extension XML element.
|
6
|
+
#
|
7
|
+
class Extension
|
8
|
+
|
9
|
+
#
|
10
|
+
# Initializes the extension.
|
11
|
+
#
|
12
|
+
# @param [Nokogiri::XML::Node] node
|
13
|
+
# The extension node.
|
14
|
+
#
|
15
|
+
def initialize(node)
|
16
|
+
@node = node
|
17
|
+
end
|
18
|
+
|
19
|
+
def present?
|
20
|
+
!@node.nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'sslyze/certificate/extensions/extension'
|
2
|
+
|
3
|
+
module SSLyze
|
4
|
+
class Certificate
|
5
|
+
class Extensions
|
6
|
+
#
|
7
|
+
# Represents the `<X509v3BasicConstraints>` XML element.
|
8
|
+
#
|
9
|
+
class X509v3BasicConstraints < Extension
|
10
|
+
|
11
|
+
#
|
12
|
+
# Specifies whether the `critical` constraint was specified.
|
13
|
+
#
|
14
|
+
# @return [Boolean]
|
15
|
+
#
|
16
|
+
def critical?
|
17
|
+
@node.inner_text.include?('critical')
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# The value of the `CA` constraint.
|
22
|
+
#
|
23
|
+
# @return [Boolean, nil]
|
24
|
+
#
|
25
|
+
def ca?
|
26
|
+
if @node.inner_text.include?('CA:TRUE') then true
|
27
|
+
elsif @node.inner_text.include?('CA:FALSE') then false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# The value of the `pathlen` constraint.
|
33
|
+
#
|
34
|
+
# @return [Integer, nil]
|
35
|
+
#
|
36
|
+
def path_length
|
37
|
+
@path_length ||= if (match = @node.inner_text.match(/pathlen:(\d+)/))
|
38
|
+
match[1].to_i
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
alias path_len path_length
|
43
|
+
|
44
|
+
#
|
45
|
+
# The raw basic constraint String.
|
46
|
+
#
|
47
|
+
# @return [String]
|
48
|
+
#
|
49
|
+
def to_s
|
50
|
+
if @node then @node.inner_text
|
51
|
+
else ''
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
alias to_str to_s
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'sslyze/certificate/extensions/extension'
|
2
|
+
|
3
|
+
module SSLyze
|
4
|
+
class Certificate
|
5
|
+
class Extensions
|
6
|
+
#
|
7
|
+
# Represents the `<X509v3CertificatePolicies>` XML element.
|
8
|
+
#
|
9
|
+
class X509v3CertificatePolicies < Extension
|
10
|
+
|
11
|
+
#
|
12
|
+
# The certificate policy.
|
13
|
+
#
|
14
|
+
# @return [Array<String>]
|
15
|
+
#
|
16
|
+
def policy
|
17
|
+
@policy ||= @node.search('Policy/listEntry').map(&:inner_text)
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# The explicit text.
|
22
|
+
#
|
23
|
+
# @return [Array<String>]
|
24
|
+
#
|
25
|
+
def explicit_text
|
26
|
+
@explicit_text ||= @node.search('ExplicitText/listEntry').map(&:inner_text)
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# The CPS.
|
31
|
+
#
|
32
|
+
# @return [Array<String>]
|
33
|
+
#
|
34
|
+
def cps
|
35
|
+
@cps ||= @node.search('CPS/listEntry').map(&:inner_text)
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# User notice.
|
40
|
+
#
|
41
|
+
# @return [String, nil]
|
42
|
+
#
|
43
|
+
def user_notice
|
44
|
+
@user_notice ||= @node.search('userNotice/listEntry').map(&:inner_text)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'sslyze/certificate/extensions/extension'
|
2
|
+
|
3
|
+
module SSLyze
|
4
|
+
class Certificate
|
5
|
+
class Extensions
|
6
|
+
#
|
7
|
+
# Represents the `<X509v3CRLDistributionPoints>` XML element.
|
8
|
+
#
|
9
|
+
class X509v3CRLDistributionPoints < Extension
|
10
|
+
|
11
|
+
#
|
12
|
+
# @return [Array<String>]
|
13
|
+
#
|
14
|
+
def full_name
|
15
|
+
@full_name ||= @node.search('FullName/listEntry').map do |full_name|
|
16
|
+
full_name.inner_text
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# @return [Array<URI>]
|
22
|
+
#
|
23
|
+
def uri
|
24
|
+
@uri ||= @node.search('URI/listEntry').map do |uri|
|
25
|
+
URI(uri.inner_text)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'sslyze/certificate/extensions/extension'
|
2
|
+
|
3
|
+
module SSLyze
|
4
|
+
class Certificate
|
5
|
+
class Extensions
|
6
|
+
#
|
7
|
+
# Represetns the `<X509v3ExtendedKeyUsage>` XML element.
|
8
|
+
#
|
9
|
+
class X509v3ExtendedKeyUsage < Extension
|
10
|
+
|
11
|
+
#
|
12
|
+
# TLS web client authentication.
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
def tls_web_client_authentication
|
17
|
+
@tls_web_client_authentication ||= @node.at('TLSWebClientAuthentication').inner_text
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# TLS web server authentication.
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
#
|
25
|
+
def tls_web_server_authentication
|
26
|
+
@tls_web_server_authentication ||= @node.at('TLSWebServerAuthentication').inner_text
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'sslyze/certificate/extensions/extension'
|
2
|
+
|
3
|
+
module SSLyze
|
4
|
+
class Certificate
|
5
|
+
class Extensions
|
6
|
+
#
|
7
|
+
# Represents the `<X509v3KeyUsage>` XML element.
|
8
|
+
#
|
9
|
+
class X509v3KeyUsage < Extension
|
10
|
+
|
11
|
+
#
|
12
|
+
# Key encipherment.
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
def key_encipherment
|
17
|
+
@key_encipherment ||= @node.at('KeyEncipherment').inner_text
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Digital signature.
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
#
|
25
|
+
def digital_signature
|
26
|
+
@digital_signature ||= @node.at('DigitalSignature').inner_text
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# CRL Sign.
|
31
|
+
#
|
32
|
+
# @return [String]
|
33
|
+
#
|
34
|
+
def crl_sign
|
35
|
+
@crl_sign ||= @node.at('CRLSign').inner_text
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Certificate sign.
|
40
|
+
#
|
41
|
+
# @return [String]
|
42
|
+
#
|
43
|
+
def certificate_sign
|
44
|
+
@certificate_sign ||= @node.at('CertificateSign').inner_text
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'sslyze/certificate/extensions/x509v3_subject_alternative_name'
|
2
|
+
require 'sslyze/certificate/domain_name'
|
3
|
+
|
4
|
+
module SSLyze
|
5
|
+
class Certificate
|
6
|
+
class Extensions
|
7
|
+
#
|
8
|
+
# Represents the `<X509v3SubjectAlternativeName>` XML element.
|
9
|
+
#
|
10
|
+
class X509v3SubjectAlternativeName < Extension
|
11
|
+
|
12
|
+
#
|
13
|
+
# The alternative email names.
|
14
|
+
#
|
15
|
+
# @return [Array<String>]
|
16
|
+
#
|
17
|
+
def email
|
18
|
+
@email ||= @node.search('email/listEntry').map(&:inner_text)
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# The alternative URI names.
|
23
|
+
#
|
24
|
+
# @return [Array<String>]
|
25
|
+
#
|
26
|
+
def uri
|
27
|
+
@rui ||= @node.search('URI/listEntry').map(&:inner_text)
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# The alternative DNS names.
|
32
|
+
#
|
33
|
+
# @return [Array<DomainName>]
|
34
|
+
#
|
35
|
+
def dns
|
36
|
+
@dns ||= @node.search('DNS/listEntry').map do |entry|
|
37
|
+
DomainName.new(entry.inner_text)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# The alternative RID names.
|
43
|
+
#
|
44
|
+
# @return [Array<String>]
|
45
|
+
#
|
46
|
+
def rid
|
47
|
+
@rid ||= @node.search('RID/listEntry').map(&:inner_text)
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# The alternative IP names.
|
52
|
+
#
|
53
|
+
# @return [Array<String>]
|
54
|
+
#
|
55
|
+
def ip
|
56
|
+
@ip ||= @node.search('IP/listEntry').map(&:inner_text)
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# The alternative dirName names.
|
61
|
+
#
|
62
|
+
# @return [Array<String>]
|
63
|
+
#
|
64
|
+
def dir_name
|
65
|
+
@dir_name ||= @node.search('dirName/listEntry').map(&:inner_text)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|