Browse Source

Improving output

new-scoring
aeris 2 years ago
parent
commit
d92523e4f2
3 changed files with 68 additions and 29 deletions
  1. 8
    3
      lib/cryptcheck/tls/cipher.rb
  2. 3
    3
      lib/cryptcheck/tls/https/server.rb
  3. 57
    23
      lib/cryptcheck/tls/server.rb

+ 8
- 3
lib/cryptcheck/tls/cipher.rb View File

@@ -141,9 +141,14 @@ module CryptCheck
@status = Status[@states.reject { |_, v| v.empty? }.keys]
end

def to_s
states = @states.collect { |k, vs| vs.collect { |v| v.to_s.colorize k }}.flatten.join ' '
"#{@method} #{@name.colorize @status} [#{states}]"
def to_s(type = :long)
case type
when :long
states = @states.collect { |k, vs| vs.collect { |v| v.to_s.colorize k }}.flatten.join ' '
"#{@method} #{@name.colorize @status} [#{states}]"
when :short
@name.colorize @status
end
end

PRIORITY = { good: 1, none: 2, warning: 3, error: 4, critical: 5 }

+ 3
- 3
lib/cryptcheck/tls/https/server.rb View File

@@ -20,14 +20,14 @@ module CryptCheck
follow_redirects: false,
verify: false,
timeout: SSL_TIMEOUT,
ssl_version: self.supported_protocols.first,
ciphers: 'ALL:COMPLEMENTOFALL'
ssl_version: @supported_methods.first.name,
ciphers: Cipher::ALL
}
if header = response.headers['strict-transport-security']
name, value = header.split '='
if name == 'max-age'
@hsts = value.to_i
Logger.info { "HSTS : #{@hsts.to_s.colorize hsts_long? ? :good : nil}" }
Logger.info { 'HSTS : ' + @hsts.to_s.colorize(hsts_long? ? :good : nil) }
return
end
end

+ 57
- 23
lib/cryptcheck/tls/server.rb View File

@@ -43,38 +43,40 @@ module CryptCheck
fetch_ecdsa_certs
fetch_supported_curves

fetch_ciphers_preferences

# verify_certs

check_fallback_scsv

exit
end

def supported_method?(method)
ssl_client method
Logger.info { "Supported method : #{method}" }
Logger.info { "Method #{method} : supported" }
true
rescue TLSException
Logger.debug { "Method not supported : #{method}" }
Logger.debug { "Method #{method} : not supported" }
false
end

def fetch_supported_methods
Logger.info { '' }
Logger.info { 'Supported methods' }
@supported_methods = Method.select { |m| supported_method? m }
end

def supported_cipher?(method, cipher)
connection = ssl_client method, cipher
Logger.info { "Supported cipher #{cipher}" }
Logger.info { "Cipher #{cipher} : supported" }
connection
rescue TLSException
Logger.debug { "Not supported cipher #{cipher}" }
Logger.debug { "Cipher #{cipher} : not supported" }
nil
end

def fetch_supported_ciphers
Logger.info { '' }
Logger.info { 'Supported ciphers' }
@supported_ciphers = @supported_methods.collect do |method|
ciphers = Cipher[method].collect do |cipher|
connection = supported_cipher? method, cipher
@@ -108,6 +110,7 @@ module CryptCheck

def fetch_supported_curves
Logger.info { '' }
Logger.info { 'Supported elliptic curves' }

ecdsa_curve = @ecdsa_certs.keys.first
if ecdsa_curve
@@ -128,9 +131,9 @@ module CryptCheck
curve = dh.curve
supported = curve != ecdsa_curve
if supported
Logger.info { "Supported ECC curve #{curve}" }
Logger.info { "ECC curve #{curve} : supported" }
else
Logger.debug { "Not supported ECC curve #{curve}" }
Logger.debug { "ECC curve #{curve} : not supported" }
end
supported
rescue TLSException
@@ -148,9 +151,9 @@ module CryptCheck
@supported_curves = Curve.select do |curve|
begin
ssl_client method, ecdh, curves: curve
Logger.info { "Supported ECC curve #{curve}" }
Logger.info { "ECC curve #{curve} : supported" }
rescue TLSException
Logger.debug { "Not supported ECC curve #{curve}" }
Logger.debug { "ECC curve #{curve} : not supported" }
false
end
end
@@ -159,7 +162,39 @@ module CryptCheck
end
end

def fetch_ciphers_preferences
Logger.info { '' }
Logger.info { 'Server preferences' }

@preferences = @supported_ciphers.collect do |method, ciphers|
ciphers = ciphers.keys
if ciphers.size < 2
Logger.info { "Preference not applicable for #{method}" }
else
a, b, _ = ciphers
ab = ssl_client(method, [a, b]).cipher.first
ba = ssl_client(method, [b, a]).cipher.first
if ab != ba
Logger.info { 'Server use client preference for '.colorize(:warning) + method.to_s }
:client
else
sort = -> (a, b) do
connection = ssl_client method, [a, b]
cipher = connection.cipher.first
cipher == a.name ? -1 : 1
end
preferences = ciphers.sort &sort
Logger.info { "Cipher preference for #{method} is #{preferences.collect { |c| c.to_s :short }.join ':'}" }
preferences
end
end
[method, preferences]
end.to_h
end

def check_fallback_scsv
Logger.info { '' }

@fallback_scsv = false
if @supported_methods.size > 1
# We will try to connect to the not better supported method
@@ -174,16 +209,15 @@ module CryptCheck
@fallback_scsv = nil
end

Logger.info { '' }
text, color = case @fallback_scsv
when true
['Supported', :good]
['supported', :good]
when false
['Not supported', :error]
['not supported', :error]
when nil
['Not applicable', :unknown]
['not applicable', :unknown]
end
Logger.info { "Fallback SCSV : #{text.colorize color}" }
Logger.info { 'Fallback SCSV : ' + text.colorize(color) }
end

Method.each do |method|
@@ -297,16 +331,16 @@ module CryptCheck
retry
rescue ::OpenSSL::SSL::SSLError => e
case e.message
when /state=SSLv3 read server hello A$/
raise TLSNotAvailableException, e
when /state=SSLv3 read server hello A: wrong version number$/
raise MethodNotAvailable, e
when /state=SSLv3 read server hello A: tlsv1 alert protocol version$/
when /state=SSLv3 read server hello A$/,
/state=SSLv3 read server hello A: wrong version number$/,
/state=SSLv3 read server hello A: tlsv1 alert protocol version$/
raise MethodNotAvailable, e
when /state=error: no ciphers available$/,
/state=SSLv3 read server hello A: sslv3 alert handshake failure$/
when /state=SSLv2 read server hello A: peer error no cipher/,
/state=error: no ciphers available$/,
/state=SSLv3 read server hello A: sslv3 alert handshake failure$/,
/state=error: missing export tmp dh key/
raise CipherNotAvailable, e
when /state=SSLv3 read server hello A: tlsv3 alert inappropriate fallback$/
when /state=SSLv3 read server hello A: tlsv1 alert inappropriate fallback$/
raise InappropriateFallback, e
end
raise

Loading…
Cancel
Save