class TLSmap::App::Extended

Partial wrapper around ciphersuite.info API to get extra info about a cipher

Documentation:

Constants

API_ROOT

Root URL of Cipher Suite Info API

DICO

Hash mapping API key and display name for CLI

ROOT

Root URL of Cipher Suite Info

SECURITY_LEVEL

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

TECH_DATA

URL of the data file containing technologies information

VULN_DATA

URL of the data file containing vulnerabilities information

VULN_SEVERITY

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

Attributes

enhanced_data[R]

Get the enhanced information of all cipher suites returned by {enhance_all}. @return [Hash] Enhanced information of all cipher suites

Public Class Methods

new() click to toggle source

Will automatically fetch source files and parse them.

# File lib/tls_map/app/extended/ciphersuiteinfo.rb, line 60
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

Public Instance Methods

enhance_all() click to toggle source

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

# File lib/tls_map/app/extended/ciphersuiteinfo.rb, line 79
def enhance_all
  fetch_ciphersuite
  out = {}
  @ciphersuite_all.each do |k, _v|
    out.store(k, extend(k, true))
  end
  @enhanced_data = out
end
extend(iana_name, caching = false) click to toggle source

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. @param iana_name [String] IANA cipher name @param caching [Boolean] if true will fetch info for all cipher suites the 1st time and used the cached value

for further requests

@return [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 two keys: `:severity` (integer) and `:description`
(string). Each hash in `vulns` correspond to a vulnerability.
# File lib/tls_map/app/extended/ciphersuiteinfo.rb, line 96
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_value do |v|
    out['vulns'].push(find_vuln(v)) if @tech.keys.include?(v)
  end
  out['vulns'].flatten!
  out['vulns'].uniq!
  out.store('url', "#{ROOT}cs/#{iana_name}/") # Add upstream URL
  out
end
find_vuln(tech) click to toggle source

Find vulnerabilities related to a technology @param tech [String] The technology acronym, eg. CBC @return [Array<Hash>] Array of vulnerabilities as described for {extend} return value in the `vulns` key.

# File lib/tls_map/app/extended/ciphersuiteinfo.rb, line 153
def find_vuln(tech)
  return @tech[tech][:vulnerabilities].map { |vuln| @vuln[vuln] } unless @tech[tech][:vulnerabilities].nil?

  nil
end
translate_acronym(term) click to toggle source

Translate cipher related acronyms @param term [String] Acronym, eg. DSS @return [String] The long name of the acronym, eg. Digital Signature Standard or `nil` if it's not found

# File lib/tls_map/app/extended/ciphersuiteinfo.rb, line 144
def translate_acronym(term)
  return @tech[term][:long_name] unless @tech[term].nil?

  nil
end

Protected Instance Methods

fetch_ciphersuite() click to toggle source

Fetch all cipher suite data from ciphersuite.info and store it in the instance attribute for batch usage.

# File lib/tls_map/app/extended/ciphersuiteinfo.rb, line 70
def fetch_ciphersuite
  return unless @ciphersuite_all.nil?

  @ciphersuite_all = JSON.parse(Net::HTTP.get(URI("#{API_ROOT}cs/")))['ciphersuites'].reduce(:merge!)
end
parse_tech() click to toggle source

Extract data from the YAML file ({TECH_DATA}) to craft a simplified Ruby hash

# File lib/tls_map/app/extended/ciphersuiteinfo.rb, line 120
def parse_tech
  data = Psych.load_file(@tech_file)
  out = {}
  data.each do |item|
    out.store(item['pk'], { long_name: item['fields']['long_name'],
                            vulnerabilities: item['fields']['vulnerabilities'] })
  end
  out
end
parse_vuln() click to toggle source

Extract data from the YAML file ({VULN_DATA}) to craft a simplified Ruby hash

# File lib/tls_map/app/extended/ciphersuiteinfo.rb, line 131
def parse_vuln
  data = Psych.load_file(@vuln_file)
  out = {}
  data.each do |item|
    out.store(item['pk'], { severity: item['fields']['severity'],
                            description: item['fields']['description'] })
  end
  out
end