make script work again
[tls-check.git] / tls-check
index 84ca0094df53a911e9a739d536b388fcb958282d..0445084ffafe5194be7418681250682a0a1d7853 100755 (executable)
--- a/tls-check
+++ b/tls-check
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
 import subprocess, sys, argparse, time, re
 from collections import OrderedDict, namedtuple
 from enum import Enum
 import subprocess, sys, argparse, time, re
 from collections import OrderedDict, namedtuple
 from enum import Enum
@@ -59,7 +59,7 @@ def test_cipher(host, port, protocol, cipher = None, wait_time=0, options=[]):
     try:
         if cipher is not None:
             options = ["-cipher", cipher]+options
     try:
         if cipher is not None:
             options = ["-cipher", cipher]+options
-        subprocess.check_call(["openssl", "s_client", "-"+protocol, "-connect", host+":"+str(port)]+options,
+        subprocess.check_call(["openssl", "s_client", "-"+protocol, "-connect", host+":"+str(port), "-servername", host]+options,
                               stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
     except subprocess.CalledProcessError:
         return False
                               stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
     except subprocess.CalledProcessError:
         return False
@@ -93,36 +93,36 @@ def test_host(host, port, wait_time=0, options=[]):
 # cipher classification
 class CipherStrength(Enum):
     unknown = -1
 # cipher classification
 class CipherStrength(Enum):
     unknown = -1
-    exp = 0
-    low = 1
-    medium = 2
     high = 3
     
     def colorName(self):
     high = 3
     
     def colorName(self):
-        if self == CipherStrength.unknown:
-            return self.name
-        elif self.value == CipherStrength.high.value:
+        if self.value == CipherStrength.high.value:
             return ConsoleFormat.color(self.name, ConsoleFormat.GREEN)
             return ConsoleFormat.color(self.name, ConsoleFormat.GREEN)
-        elif self.value == CipherStrength.medium.value:
-            return ConsoleFormat.color(self.name, ConsoleFormat.YELLOW)
         else:
         else:
-            return ConsoleFormat.color(self.name, ConsoleFormat.RED)
+            return ConsoleFormat.color(self.name, ConsoleFormat.YELLOW)
 
 CipherProps = namedtuple('CipherProps', 'bits, strength, isPfs')
 
 class CipherPropsProvider:
     def __init__(self):
 
 CipherProps = namedtuple('CipherProps', 'bits, strength, isPfs')
 
 class CipherPropsProvider:
     def __init__(self):
-        self.exp = set(list_ciphers("EXP"))
-        self.low = set(list_ciphers("LOW"))
-        self.medium = set(list_ciphers("MEDIUM"))
         self.high = set(list_ciphers("HIGH"))
         self.props = {}
     
     def getProps(self, protocol, cipher):
         self.high = set(list_ciphers("HIGH"))
         self.props = {}
     
     def getProps(self, protocol, cipher):
+        # strip the sub-version-number from the protocol
+        pos = protocol.find('_')
+        if pos >= 0:
+            protocol = protocol[:pos]
         # as OpenSSL about this cipher
         cipherInfo = subprocess.check_output(["openssl", "ciphers", "-v", "-"+protocol, cipher]).decode('UTF-8').strip()
         # as OpenSSL about this cipher
         cipherInfo = subprocess.check_output(["openssl", "ciphers", "-v", "-"+protocol, cipher]).decode('UTF-8').strip()
-        assert '\n' not in cipherInfo, "Cipher "+cipher+" produced unexpected output:\n"+cipherInfo
-        cipherInfoFields = cipherInfo.split()
+        cipherInfoFields = None
+        for line in cipherInfo.split('\n'):
+            line = line.split()
+            if line[0] == cipher:
+                cipherInfoFields = line
+                break
+        if cipherInfoFields is None:
+            raise Exception("Cannot determine cipher properties of {0} (protocol: {1})".format(cipher, protocol))
         # get # of bits
         encMatch = re.match(r'^Enc=([0-9A-Za-z]+)\(([0-9]+)\)$', cipherInfoFields[4])
         if encMatch is None:
         # get # of bits
         encMatch = re.match(r'^Enc=([0-9A-Za-z]+)\(([0-9]+)\)$', cipherInfoFields[4])
         if encMatch is None:
@@ -139,18 +139,7 @@ class CipherPropsProvider:
         kx = kxMatch.group(1)
         isPfs = kx in ('DH', 'DH(512)', 'ECDH')
         # determine security level
         kx = kxMatch.group(1)
         isPfs = kx in ('DH', 'DH(512)', 'ECDH')
         # determine security level
-        isExp = cipher in self.exp
-        isLow = cipher in self.low
-        isMedium = cipher in self.medium
-        isHigh = cipher in self.high
-        assert isExp+isLow+isMedium+isHigh <= 1, "Cipher "+cipher+" is more than one from EXP, LOW, MEDIUM, HIGH"
-        if isExp:
-            strength = CipherStrength.exp
-        elif isLow:
-            strength = CipherStrength.low
-        elif isMedium:
-            strength = CipherStrength.medium
-        elif isHigh:
+        if cipher in self.high:
             strength = CipherStrength.high
         else:
             strength = CipherStrength.unknown
             strength = CipherStrength.high
         else:
             strength = CipherStrength.unknown