Class: TLSmap::App::Extended

Inherits:
Object
  • Object
show all
Defined in:
lib/tls_map/app/extended/ciphersuiteinfo.rb

Overview

Direct Known Subclasses

CLI::Extended

Constant Summary collapse

ROOT =

Root URL of Cipher Suite Info

'https://ciphersuite.info/'
API_ROOT =

Root URL of Cipher Suite Info API

"#{ROOT}api/".freeze
VULN_DATA =

URL of the data file containing vulnerabilities information

'https://raw.githubusercontent.com/hcrudolph/ciphersuite.info/master/directory/fixtures/00_vulnerabilities.yaml'
TECH_DATA =

URL of the data file containing technologies information

'https://raw.githubusercontent.com/hcrudolph/ciphersuite.info/master/directory/fixtures/01_technologies.yaml'
DICO =

Hash mapping API key and display name for CLI (:display) and model name in 01_technologies.yaml (:model)

{
  'tls_version' => { display: 'TLS Version(s)' },
  'protocol_version' => {
    display: 'Protocol',
    model: 'ProtocolVersion'
  },
  'kex_algorithm' => {
    display: 'Key Exchange',
    model: 'KexAlgorithm'
  },
  'auth_algorithm' => {
    display: 'Authentication',
    model: 'AuthAlgorithm'
  },
  'enc_algorithm' => {
    display: 'Encryption',
    model: 'EncAlgorithm'
  },
  'hash_algorithm' => {
    display: 'Hash',
    model: 'HashAlgorithm'
  },
  'security' => { display: 'Security' },
  'url' => { display: 'More info' },
  'vulns' => { display: 'Vulnerabilities' }
}.freeze
VULN_SEVERITY =

Hash mapping the severity number used by the API and the severity text and color for the CLI

{
  0 => { title: 'Low', color: :yellow },
  1 => { title: 'Medium', color: 'orange' },
  2 => { title: 'High', color: :red }
}.freeze
SECURITY_LEVEL =

Hash mapping the security level used by the API and color for the CLI

{
  'recommended' => { color: :green },
  'secure' => { color: :green },
  'weak' => { color: 'orange' },
  'insecure' => { color: :red }
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize ⇒ Extended

Will automatically fetch source files and parse them.



75
76
77
78
79
80
81
82
# File 'lib/tls_map/app/extended/ciphersuiteinfo.rb', line 75

def initialize
  @tech_file = Utils.tmpfile('tech', TECH_DATA)
  @vuln_file = Utils.tmpfile('vuln', VULN_DATA)
  @tech = parse_tech
  @vuln = parse_vuln
  @ciphersuite_all = nil
  @enhanced_data = nil
end

Instance Attribute Details

#enhanced_data ⇒ Hash (readonly)

Get the enhanced information of all cipher suites returned by #enhance_all.

Returns:

  • (Hash) —

    Enhanced information of all cipher suites



72
73
74
# File 'lib/tls_map/app/extended/ciphersuiteinfo.rb', line 72

def enhanced_data
  @enhanced_data
end

Instance Method Details

#enhance_all ⇒ Object

Enhance data from ciphersuite.info for all cipher suites and store it
for batch usage.
The data will be available through #enhanced_data.



94
95
96
97
98
99
100
101
# File 'lib/tls_map/app/extended/ciphersuiteinfo.rb', line 94

def enhance_all
  fetch_ciphersuite
  out = {}
  @ciphersuite_all.each_key do |k|
    out.store(k, extend(k, true))
  end
  @enhanced_data = out
end

#extend(iana_name, caching = false) ⇒ Hash

Retrieve advanced information about a cipher on Cipher Suite Info API and enhanced it.
Fetch only the requested cipher suite, small network footprint, ideal for low bandwidth or punctual use.

Parameters:

  • iana_name (String) —

    IANA cipher name

  • caching (Boolean) (defaults to: false) —

    if true will fetch info for all cipher suites the 1st time and used the cached value
    for further requests

Returns:

  • (Hash) —

    Hash containing advanced information. The keys are the same as DICO. All values are string
    except vulns which is an array of hashes containing three keys: :severity (integer), :name and
    :description.
    (string). Each hash in vulns correspond to a vulnerability.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/tls_map/app/extended/ciphersuiteinfo.rb', line 112

def extend(iana_name, caching = false) # rubocop:disable Metrics/MethodLength
  if caching
    fetch_ciphersuite
    out = @ciphersuite_all[iana_name]
  else
    obj = Net::HTTP.get(URI("#{API_ROOT}cs/#{iana_name}/"))
    out = JSON.parse(obj)[iana_name]
  end
  return {} if out.nil?

  out.store('vulns', [])
  %w[openssl_name gnutls_name hex_byte_1 hex_byte_2].each do |key|
    out.delete(key)
  end
  out.each do |k, v|
    # '' fallback since out is not containing only algorithms
    # else calling `:model` in DICO will return nil and make the concatenation fail
    # this handling is more explicit that using interpolation that will silently handle nil
    alg_index = DICO[k][:model] ? DICO[k][:model] + v : ''
    out['vulns'].push(find_vuln(alg_index)) if @tech.keys.include?(alg_index)
  end
  out['vulns'].flatten!
  out['vulns'].uniq!
  out.store('url', "#{ROOT}cs/#{iana_name}/") # Add upstream URL
  out
end

#find_vuln(tech) ⇒ Array<Hash>

Find vulnerabilities related to a technology

Parameters:

  • tech (String) —

    The technology acronym, eg. CBC and algorithm type. Based on 01_technologies.yaml,
    this would be the last part of model + pk. The model value is mapped in DICO under the :model sub-key.

Returns:

  • (Array<Hash>) —

    Array of vulnerabilities as described for #extend return value in the vulns key.



179
180
181
182
183
# File 'lib/tls_map/app/extended/ciphersuiteinfo.rb', line 179

def find_vuln(tech)
  return @tech[tech][:vulnerabilities].map { |vuln| @vuln[vuln] } unless @tech[tech][:vulnerabilities].nil?

  nil
end

#translate_acronym(term) ⇒ String

Translate cipher related acronyms

Parameters:

  • term (String) —

    Acronym, eg. DSS and algorithm type. Based on 01_technologies.yaml,
    this would be the last part of model + pk. The model value is mapped in DICO under the :model sub-key.

Returns:

  • (String) —

    The long name of the acronym, eg. Digital Signature Standard or nil if it's not found



169
170
171
172
173
# File 'lib/tls_map/app/extended/ciphersuiteinfo.rb', line 169

def translate_acronym(term)
  return @tech[term][:long_name] unless @tech[term].nil?

  nil
end