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,56 @@
1
+ module SSLyze
2
+ class Certificate
3
+ #
4
+ # Represents the `<issuer>` XML element.
5
+ #
6
+ class Issuer
7
+
8
+ #
9
+ # Initializes the issuer.
10
+ #
11
+ # @param [Nokogiri::XML::Node] node
12
+ # The `<issuer>` element.
13
+ #
14
+ def initialize(node)
15
+ @node = node
16
+ end
17
+
18
+ #
19
+ # Country name.
20
+ #
21
+ # @return [String]
22
+ #
23
+ def country_name
24
+ @country_name || @node.at('countryName').inner_text
25
+ end
26
+
27
+ #
28
+ # Common name.
29
+ #
30
+ # @return [String]
31
+ #
32
+ def common_name
33
+ @common_name ||= @node.at('commonName').inner_text
34
+ end
35
+
36
+ #
37
+ # Organizational unit name.
38
+ #
39
+ # @return [String]
40
+ #
41
+ def organizational_unit_name
42
+ @organizational_unit_name ||= @node.at('organizationalUnitName').inner_text
43
+ end
44
+
45
+ #
46
+ # Organization name.
47
+ #
48
+ # @return [String]
49
+ #
50
+ def organization_name
51
+ @organization_name ||= @node.at('organizationName').inner_text
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,9 @@
1
+ module SSLyze
2
+ class Certificate
3
+ #
4
+ # Represents the `<publicKey>` XML element.
5
+ #
6
+ class PublicKey < Struct.new(:modulus, :exponent)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,117 @@
1
+ require 'sslyze/certificate/domain_name'
2
+
3
+ module SSLyze
4
+ class Certificate
5
+ #
6
+ # Represents the `<subject>` XML element.
7
+ #
8
+ class Subject
9
+
10
+ #
11
+ # Initializes the subject.
12
+ #
13
+ # @param [Nokogiri::XML::Node] node
14
+ # The `<subject>` XML element.
15
+ #
16
+ def initialize(node)
17
+ @node = node
18
+ end
19
+
20
+ #
21
+ # Organizational unit name.
22
+ #
23
+ # @return [String]
24
+ #
25
+ def organizational_unit_name
26
+ @organizational_unit_name ||= @node.at('organizationalUnitName').inner_text
27
+ end
28
+
29
+ #
30
+ # Organization name.
31
+ #
32
+ # @return [String]
33
+ #
34
+ def organization_name
35
+ @organization_name ||= @node.at('organizationName').inner_text
36
+ end
37
+
38
+ #
39
+ # Business category.
40
+ #
41
+ # @return [String]
42
+ #
43
+ def business_category
44
+ @business_category ||= @node.at('businessCategory').inner_text
45
+ end
46
+
47
+ #
48
+ # Serial number.
49
+ #
50
+ # @return [Integer]
51
+ #
52
+ def serial_number
53
+ @serial_number ||= @node.at('serialNumber').inner_text.to_i
54
+ end
55
+
56
+ #
57
+ # Common name.
58
+ #
59
+ # @return [DomainName]
60
+ #
61
+ def common_name
62
+ @common_name ||= if (common_name = @node.at('commonName'))
63
+ DomainName.new(common_name.inner_text)
64
+ end
65
+ end
66
+
67
+ #
68
+ # State/province name.
69
+ #
70
+ # @return [String]
71
+ #
72
+ def state_or_province_name
73
+ @state_or_province_name ||= @node.at('stateOrProvinceName').inner_text
74
+ end
75
+
76
+ #
77
+ # Country name.
78
+ #
79
+ # @return [String]
80
+ #
81
+ def country_name
82
+ @country_name ||= @node.at('countryName').inner_text
83
+ end
84
+
85
+ #
86
+ # Street address.
87
+ #
88
+ # @return [String]
89
+ #
90
+ def street_address
91
+ @street_address ||= @node.at('streetAddress').inner_text
92
+ end
93
+
94
+ # TODO: oid-1.3.6.1.4.1.311.60.2.1.2
95
+ # TODO: oid-1.3.6.1.4.1.311.60.2.1.3
96
+
97
+ #
98
+ # Locality name.
99
+ #
100
+ # @return [String]
101
+ #
102
+ def locality_name
103
+ @locality_name ||= @node.at('localityName').inner_text
104
+ end
105
+
106
+ #
107
+ # Postal code.
108
+ #
109
+ # @return [String]
110
+ #
111
+ def postal_code
112
+ @postal_code ||= @node.at('postalCode').inner_text
113
+ end
114
+
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,53 @@
1
+ require 'sslyze/certificate/public_key'
2
+
3
+ module SSLyze
4
+ class Certificate
5
+ #
6
+ # Represents the `<subjectPublicKeyInfo>` XML element.
7
+ #
8
+ class SubjectPublicKeyInfo
9
+
10
+ #
11
+ # Initializes the subject public key info.
12
+ #
13
+ # @param [Nokogiri::XML::Node] node
14
+ # The `<subjectPublicKeyInfo>` XML element.
15
+ #
16
+ def initialize(node)
17
+ @node = node
18
+ end
19
+
20
+ #
21
+ # Public key info.
22
+ #
23
+ # @return [PublicKey]
24
+ #
25
+ def public_key
26
+ @public_key ||= PublicKey.new(
27
+ @node.at('publicKey/modulus').inner_text,
28
+ @node.at('publicKey/exponent').inner_text.to_i
29
+ )
30
+ end
31
+
32
+ #
33
+ # Public key algorithm.
34
+ #
35
+ # @return [String]
36
+ #
37
+ def public_key_algorithm
38
+ @public_key_algorithm ||= @node.at('publicKeyAlgorithm').inner_text
39
+ end
40
+
41
+ #
42
+ # Public key size.
43
+ #
44
+ # @return [Integer]
45
+ # The key size in bits.
46
+ #
47
+ def public_key_size
48
+ @public_key_size ||= @node.at('publicKeySize').inner_text.chomp(' bits').to_i
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,9 @@
1
+ module SSLyze
2
+ class Certificate
3
+ #
4
+ # Represents the `<validity>` XML element.
5
+ #
6
+ class Validity < Struct.new(:not_after, :not_before)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,89 @@
1
+ require 'sslyze/certificate'
2
+
3
+ module SSLyze
4
+ #
5
+ # Represents the `<certificateChain>` XML element.
6
+ #
7
+ class CertificateChain
8
+
9
+ include Enumerable
10
+
11
+ #
12
+ # Initializes the certificate chain.
13
+ #
14
+ # @param [Nokogiri::XML::Node] node
15
+ # The `<certificateChain>` XML element.
16
+ #
17
+ def initialize(node)
18
+ @node = node
19
+ end
20
+
21
+ #
22
+ # Enumerates over each certificate in the chain.
23
+ #
24
+ # @yield [certificate]
25
+ #
26
+ # @yieldparam [Certificate] certificate
27
+ #
28
+ # @return [Enumerator]
29
+ #
30
+ def each
31
+ return enum_for(__method__) unless block_given?
32
+
33
+ @node.search('certificate').each do |certificate|
34
+ yield Certificate.new(certificate)
35
+ end
36
+ end
37
+
38
+ #
39
+ # The leaf certificate in the chain.
40
+ #
41
+ # @return [Certificate, nil]
42
+ #
43
+ def leaf
44
+ @leaf ||= if (certificate = @node.at('certificate[@position="leaf"]'))
45
+ Certificate.new(certificate)
46
+ end
47
+ end
48
+
49
+ #
50
+ # Enumerates over the intermediate certificates in the chain.
51
+ #
52
+ # @yield [certificate]
53
+ #
54
+ # @yieldparam [Certificate] certificate
55
+ #
56
+ # @return [Enumerator]
57
+ #
58
+ def each_intermediate
59
+ return enum_for(__method__) unless block_given?
60
+
61
+ @node.search('certificate[@position="intermediate"]').each do |certificate|
62
+ yield Certificate.new(certificate)
63
+ end
64
+ end
65
+
66
+ #
67
+ # The intermediate certificates.
68
+ #
69
+ # @return [Array<Certificate>]
70
+ #
71
+ # @see #each_intermediate
72
+ #
73
+ def intermediate
74
+ each_intermediate.to_a
75
+ end
76
+
77
+ #
78
+ # The root certificate.
79
+ #
80
+ # @return [Certificate, nil]
81
+ #
82
+ def root
83
+ if (certificate = @node.at('certificate[@position="intermediate"]:last-child'))
84
+ Certificate.new(certificate)
85
+ end
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,44 @@
1
+ require 'sslyze/types'
2
+
3
+ module SSLyze
4
+ #
5
+ # Represents the `<certificateValidation>` XML element.
6
+ #
7
+ class CertificateValidation
8
+
9
+ include Types
10
+
11
+ #
12
+ # Initializes the certificate validation.
13
+ #
14
+ # @param [Nokogiri::XML::Node] node
15
+ # The `<certificateValidation>` XMl element.
16
+ #
17
+ def initialize(node)
18
+ @node = node
19
+ end
20
+
21
+ #
22
+ # Specifies whether the hostname was validated.
23
+ #
24
+ # @return [Boolean]
25
+ #
26
+ def hostname?
27
+ Boolean[@node.at('hostnameValidation/@certificateMatchesServerHostname').value]
28
+ end
29
+
30
+ #
31
+ # Specifies whether the certificate path was validated against various
32
+ # certificate stores.
33
+ #
34
+ # @return [Hash{String => Boolean}]
35
+ # The certificate store name and validation result.
36
+ #
37
+ def path
38
+ @path ||= Hash[@node.search('pathValidation').map { |path|
39
+ [path['usingTrustStore'], path['validationResult'] == 'ok']
40
+ }]
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,237 @@
1
+ require 'sslyze/types'
2
+ require 'sslyze/key_exchange'
3
+
4
+ module SSLyze
5
+ #
6
+ # Represents the `<cipherSuite>` XML element.
7
+ #
8
+ class CipherSuite
9
+
10
+ include Types
11
+
12
+ # Mapping of OpenSSL cipher names to RFC cipher names
13
+ RFC_NAMES = {
14
+ "NULL-MD5" => "TLS_RSA_WITH_NULL_MD5",
15
+ "NULL-SHA" => "TLS_RSA_WITH_NULL_SHA",
16
+ "EXP-RC4-MD5" => "TLS_RSA_EXPORT_WITH_RC4_40_MD5",
17
+ "RC4-MD5" => "TLS_RSA_WITH_RC4_128_MD5",
18
+ "RC4-SHA" => "TLS_RSA_WITH_RC4_128_SHA",
19
+ "EXP-RC2-CBC-MD5" => "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5",
20
+ "IDEA-CBC-SHA" => "TLS_RSA_WITH_IDEA_CBC_SHA",
21
+ "EXP-DES-CBC-SHA" => "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA",
22
+ "DES-CBC-SHA" => "TLS_RSA_WITH_DES_CBC_SHA",
23
+ "DES-CBC3-SHA" => "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
24
+ "EXP-DH-DSS-DES-CBC-SHA" => "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA",
25
+ "DH-DSS-DES-CBC-SHA" => "TLS_DH_DSS_WITH_DES_CBC_SHA",
26
+ "DH-DSS-DES-CBC3-SHA" => "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA",
27
+ "EXP-DH-RSA-DES-CBC-SHA" => "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA",
28
+ "DH-RSA-DES-CBC-SHA" => "TLS_DH_RSA_WITH_DES_CBC_SHA",
29
+ "DH-RSA-DES-CBC3-SHA" => "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA",
30
+ "EXP-EDH-DSS-DES-CBC-SHA" => "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
31
+ "EDH-DSS-DES-CBC-SHA" => "TLS_DHE_DSS_WITH_DES_CBC_SHA",
32
+ "EDH-DSS-DES-CBC3-SHA" => "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
33
+ "EXP-EDH-RSA-DES-CBC-SHA" => "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
34
+ "EDH-RSA-DES-CBC-SHA" => "TLS_DHE_RSA_WITH_DES_CBC_SHA",
35
+ "EDH-RSA-DES-CBC3-SHA" => "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
36
+ "EXP-ADH-RC4-MD5" => "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5",
37
+ "ADH-RC4-MD5" => "TLS_DH_anon_WITH_RC4_128_MD5",
38
+ "EXP-ADH-DES-CBC-SHA" => "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
39
+ "ADH-DES-CBC-SHA" => "TLS_DH_anon_WITH_DES_CBC_SHA",
40
+ "ADH-DES-CBC3-SHA" => "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA",
41
+ "KRB5-DES-CBC-SHA" => "TLS_KRB5_WITH_DES_CBC_SHA",
42
+ "KRB5-DES-CBC3-SHA" => "TLS_KRB5_WITH_3DES_EDE_CBC_SHA",
43
+ "KRB5-RC4-SHA" => "TLS_KRB5_WITH_RC4_128_SHA",
44
+ "KRB5-IDEA-CBC-SHA" => "TLS_KRB5_WITH_IDEA_CBC_SHA",
45
+ "KRB5-DES-CBC-MD5" => "TLS_KRB5_WITH_DES_CBC_MD5",
46
+ "KRB5-DES-CBC3-MD5" => "TLS_KRB5_WITH_3DES_EDE_CBC_MD5",
47
+ "KRB5-RC4-MD5" => "TLS_KRB5_WITH_RC4_128_MD5",
48
+ "KRB5-IDEA-CBC-MD5" => "TLS_KRB5_WITH_IDEA_CBC_MD5",
49
+ "EXP-KRB5-DES-CBC-SHA" => "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",
50
+ "EXP-KRB5-RC2-CBC-SHA" => "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA",
51
+ "EXP-KRB5-RC4-SHA" => "TLS_KRB5_EXPORT_WITH_RC4_40_SHA",
52
+ "EXP-KRB5-DES-CBC-MD5" => "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",
53
+ "EXP-KRB5-RC2-CBC-MD5" => "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5",
54
+ "EXP-KRB5-RC4-MD5" => "TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
55
+ "AES128-SHA" => "TLS_RSA_WITH_AES_128_CBC_SHA",
56
+ "DH-DSS-AES128-SHA" => "TLS_DH_DSS_WITH_AES_128_CBC_SHA",
57
+ "DH-RSA-AES128-SHA" => "TLS_DH_RSA_WITH_AES_128_CBC_SHA",
58
+ "DHE-DSS-AES128-SHA" => "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
59
+ "DHE-RSA-AES128-SHA" => "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
60
+ "ADH-AES128-SHA" => "TLS_DH_anon_WITH_AES_128_CBC_SHA",
61
+ "AES256-SHA" => "TLS_RSA_WITH_AES_256_CBC_SHA",
62
+ "DH-DSS-AES256-SHA" => "TLS_DH_DSS_WITH_AES_256_CBC_SHA",
63
+ "DH-RSA-AES256-SHA" => "TLS_DH_RSA_WITH_AES_256_CBC_SHA",
64
+ "DHE-DSS-AES256-SHA" => "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
65
+ "DHE-RSA-AES256-SHA" => "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
66
+ "ADH-AES256-SHA" => "TLS_DH_anon_WITH_AES_256_CBC_SHA",
67
+ "NULL-SHA256" => "TLS_RSA_WITH_NULL_SHA256",
68
+ "AES128-SHA256" => "TLS_RSA_WITH_AES_128_CBC_SHA256",
69
+ "AES256-SHA256" => "TLS_RSA_WITH_AES_256_CBC_SHA256",
70
+ "DH-DSS-AES128-SHA256" => "TLS_DH_DSS_WITH_AES_128_CBC_SHA256",
71
+ "DH-RSA-AES128-SHA256" => "TLS_DH_RSA_WITH_AES_128_CBC_SHA256",
72
+ "DHE-DSS-AES128-SHA256" => "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",
73
+ "CAMELLIA128-SHA" => "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA",
74
+ "DH-DSS-CAMELLIA128-SHA" => "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA",
75
+ "DH-RSA-CAMELLIA128-SHA" => "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA",
76
+ "DHE-DSS-CAMELLIA128-SHA" => "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA",
77
+ "DHE-RSA-CAMELLIA128-SHA" => "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA",
78
+ "ADH-CAMELLIA128-SHA" => "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA",
79
+ "EXP1024-DES-CBC-SHA" => "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA",
80
+ "EXP1024-DHE-DSS-DES-CBC-SHA" => "TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA",
81
+ "EXP1024-RC4-SHA" => "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA",
82
+ "EXP1024-DHE-DSS-RC4-SHA" => "TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA",
83
+ "DHE-DSS-RC4-SHA" => "TLS_DHE_DSS_WITH_RC4_128_SHA",
84
+ "DHE-RSA-AES128-SHA256" => "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
85
+ "DH-DSS-AES256-SHA256" => "TLS_DH_DSS_WITH_AES_256_CBC_SHA256",
86
+ "DH-RSA-AES256-SHA256" => "TLS_DH_RSA_WITH_AES_256_CBC_SHA256",
87
+ "DHE-DSS-AES256-SHA256" => "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
88
+ "DHE-RSA-AES256-SHA256" => "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
89
+ "ADH-AES128-SHA256" => "TLS_DH_anon_WITH_AES_128_CBC_SHA256",
90
+ "ADH-AES256-SHA256" => "TLS_DH_anon_WITH_AES_256_CBC_SHA256",
91
+ "GOST94-GOST89-GOST89" => "TLS_GOSTR341094_WITH_28147_CNT_IMIT",
92
+ "GOST2001-GOST89-GOST89" => "TLS_GOSTR341001_WITH_28147_CNT_IMIT",
93
+ "CAMELLIA256-SHA" => "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA",
94
+ "DH-DSS-CAMELLIA256-SHA" => "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA",
95
+ "DH-RSA-CAMELLIA256-SHA" => "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA",
96
+ "DHE-DSS-CAMELLIA256-SHA" => "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA",
97
+ "DHE-RSA-CAMELLIA256-SHA" => "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA",
98
+ "ADH-CAMELLIA256-SHA" => "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA",
99
+ "PSK-RC4-SHA" => "TLS_PSK_WITH_RC4_128_SHA",
100
+ "PSK-3DES-EDE-CBC-SHA" => "TLS_PSK_WITH_3DES_EDE_CBC_SHA",
101
+ "PSK-AES128-CBC-SHA" => "TLS_PSK_WITH_AES_128_CBC_SHA",
102
+ "PSK-AES256-CBC-SHA" => "TLS_PSK_WITH_AES_256_CBC_SHA",
103
+ "SEED-SHA" => "TLS_RSA_WITH_SEED_CBC_SHA",
104
+ "DH-DSS-SEED-SHA" => "TLS_DH_DSS_WITH_SEED_CBC_SHA",
105
+ "DH-RSA-SEED-SHA" => "TLS_DH_RSA_WITH_SEED_CBC_SHA",
106
+ "DHE-DSS-SEED-SHA" => "TLS_DHE_DSS_WITH_SEED_CBC_SHA",
107
+ "DHE-RSA-SEED-SHA" => "TLS_DHE_RSA_WITH_SEED_CBC_SHA",
108
+ "ADH-SEED-SHA" => "TLS_DH_anon_WITH_SEED_CBC_SHA",
109
+ "AES128-GCM-SHA256" => "TLS_RSA_WITH_AES_128_GCM_SHA256",
110
+ "AES256-GCM-SHA384" => "TLS_RSA_WITH_AES_256_GCM_SHA384",
111
+ "DHE-RSA-AES128-GCM-SHA256" => "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
112
+ "DHE-RSA-AES256-GCM-SHA384" => "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
113
+ "DH-RSA-AES128-GCM-SHA256" => "TLS_DH_RSA_WITH_AES_128_GCM_SHA256",
114
+ "DH-RSA-AES256-GCM-SHA384" => "TLS_DH_RSA_WITH_AES_256_GCM_SHA384",
115
+ "DHE-DSS-AES128-GCM-SHA256" => "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
116
+ "DHE-DSS-AES256-GCM-SHA384" => "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
117
+ "DH-DSS-AES128-GCM-SHA256" => "TLS_DH_DSS_WITH_AES_128_GCM_SHA256",
118
+ "DH-DSS-AES256-GCM-SHA384" => "TLS_DH_DSS_WITH_AES_256_GCM_SHA384",
119
+ "ADH-AES128-GCM-SHA256" => "TLS_DH_anon_WITH_AES_128_GCM_SHA256",
120
+ "ADH-AES256-GCM-SHA384" => "TLS_DH_anon_WITH_AES_256_GCM_SHA384",
121
+ "TLS_FALLBACK_SCSV" => "TLS_FALLBACK_SCSV",
122
+ "ECDH-ECDSA-NULL-SHA" => "TLS_ECDH_ECDSA_WITH_NULL_SHA",
123
+ "ECDH-ECDSA-RC4-SHA" => "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
124
+ "ECDH-ECDSA-DES-CBC3-SHA" => "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
125
+ "ECDH-ECDSA-AES128-SHA" => "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
126
+ "ECDH-ECDSA-AES256-SHA" => "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
127
+ "ECDHE-ECDSA-NULL-SHA" => "TLS_ECDHE_ECDSA_WITH_NULL_SHA",
128
+ "ECDHE-ECDSA-RC4-SHA" => "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
129
+ "ECDHE-ECDSA-DES-CBC3-SHA" => "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
130
+ "ECDHE-ECDSA-AES128-SHA" => "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
131
+ "ECDHE-ECDSA-AES256-SHA" => "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
132
+ "ECDH-RSA-NULL-SHA" => "TLS_ECDH_RSA_WITH_NULL_SHA",
133
+ "ECDH-RSA-RC4-SHA" => "TLS_ECDH_RSA_WITH_RC4_128_SHA",
134
+ "ECDH-RSA-DES-CBC3-SHA" => "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
135
+ "ECDH-RSA-AES128-SHA" => "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
136
+ "ECDH-RSA-AES256-SHA" => "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
137
+ "ECDHE-RSA-NULL-SHA" => "TLS_ECDHE_RSA_WITH_NULL_SHA",
138
+ "ECDHE-RSA-RC4-SHA" => "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
139
+ "ECDHE-RSA-DES-CBC3-SHA" => "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
140
+ "ECDHE-RSA-AES128-SHA" => "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
141
+ "ECDHE-RSA-AES256-SHA" => "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
142
+ "AECDH-NULL-SHA" => "TLS_ECDH_anon_WITH_NULL_SHA",
143
+ "AECDH-RC4-SHA" => "TLS_ECDH_anon_WITH_RC4_128_SHA",
144
+ "AECDH-DES-CBC3-SHA" => "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
145
+ "AECDH-AES128-SHA" => "TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
146
+ "AECDH-AES256-SHA" => "TLS_ECDH_anon_WITH_AES_256_CBC_SHA",
147
+ "SRP-3DES-EDE-CBC-SHA" => "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA",
148
+ "SRP-RSA-3DES-EDE-CBC-SHA" => "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA",
149
+ "SRP-DSS-3DES-EDE-CBC-SHA" => "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA",
150
+ "SRP-AES-128-CBC-SHA" => "TLS_SRP_SHA_WITH_AES_128_CBC_SHA",
151
+ "SRP-RSA-AES-128-CBC-SHA" => "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA",
152
+ "SRP-DSS-AES-128-CBC-SHA" => "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA",
153
+ "SRP-AES-256-CBC-SHA" => "TLS_SRP_SHA_WITH_AES_256_CBC_SHA",
154
+ "SRP-RSA-AES-256-CBC-SHA" => "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA",
155
+ "SRP-DSS-AES-256-CBC-SHA" => "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA",
156
+ "ECDHE-ECDSA-AES128-SHA256" => "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
157
+ "ECDHE-ECDSA-AES256-SHA384" => "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
158
+ "ECDH-ECDSA-AES128-SHA256" => "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
159
+ "ECDH-ECDSA-AES256-SHA384" => "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
160
+ "ECDHE-RSA-AES128-SHA256" => "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
161
+ "ECDHE-RSA-AES256-SHA384" => "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
162
+ "ECDH-RSA-AES128-SHA256" => "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
163
+ "ECDH-RSA-AES256-SHA384" => "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
164
+ "ECDHE-ECDSA-AES128-GCM-SHA256" => "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
165
+ "ECDHE-ECDSA-AES256-GCM-SHA384" => "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
166
+ "ECDH-ECDSA-AES128-GCM-SHA256" => "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
167
+ "ECDH-ECDSA-AES256-GCM-SHA384" => "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
168
+ "ECDHE-RSA-AES128-GCM-SHA256" => "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
169
+ "ECDHE-RSA-AES256-GCM-SHA384" => "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
170
+ "ECDH-RSA-AES128-GCM-SHA256" => "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",
171
+ "ECDH-RSA-AES256-GCM-SHA384" => "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",
172
+ "ECDHE-RSA-CHACHA20-POLY1305" => "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
173
+ "ECDHE-ECDSA-CHACHA20-POLY1305" => "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
174
+ "DHE-RSA-CHACHA20-POLY1305" => "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
175
+ "RC2-CBC-MD5" => "SSL_CK_RC2_128_CBC_WITH_MD5",
176
+ "IDEA-CBC-MD5" => "SSL_CK_IDEA_128_CBC_WITH_MD5",
177
+ "DES-CBC-MD5" => "SSL_CK_DES_64_CBC_WITH_MD5",
178
+ "DES-CBC3-MD5" => "SSL_CK_DES_192_EDE3_CBC_WITH_MD5",
179
+ "RC4-64-MD5" => "SSL_CK_RC4_64_WITH_MD5"
180
+ }
181
+
182
+ #
183
+ # Initializes the cipher suite.
184
+ #
185
+ # @param [Nokogiri::XML::Node] node
186
+ # The `<cipherSuite>` XML element.
187
+ #
188
+ def initialize(node)
189
+ @node = node
190
+ end
191
+
192
+ #
193
+ # The cipher suite name.
194
+ #
195
+ # @return [String]
196
+ #
197
+ def name
198
+ @name ||= @node['name']
199
+ end
200
+
201
+ alias openssl_name name
202
+
203
+ #
204
+ # Maps the OpenSSL cipher name to it's RFC name.
205
+ #
206
+ # @return [String, nil]
207
+ #
208
+ def rfc_name
209
+ RFC_NAMES[name]
210
+ end
211
+
212
+ #
213
+ # The connection status when the cipher suite was used.
214
+ #
215
+ def connection_status
216
+ @connection_status ||= @node['connectionStatus']
217
+ end
218
+
219
+ def anonymous?
220
+ Boolean[@node['anonymous']]
221
+ end
222
+
223
+ #
224
+ # Key exchange information.
225
+ #
226
+ # @return [KeyExchange, nil]
227
+ #
228
+ def key_exchange
229
+ @key_exchange ||= if (key_exchange_node = @node.at('keyExchange'))
230
+ KeyExchange.new(key_exchange_node)
231
+ end
232
+ end
233
+
234
+ alias to_s name
235
+
236
+ end
237
+ end