X-Git-Url: https://git.ralfj.de/tls-check.git/blobdiff_plain/ba9287202872b62c09e903adb767eaaad87504fa..HEAD:/tls-check diff --git a/tls-check b/tls-check index fcbf941..0445084 100755 --- 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 @@ -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 - 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 @@ -93,28 +93,18 @@ def test_host(host, port, wait_time=0, options=[]): # cipher classification class CipherStrength(Enum): unknown = -1 - exp = 0 - low = 1 - medium = 2 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) - elif self.value == CipherStrength.medium.value: - return ConsoleFormat.color(self.name, ConsoleFormat.YELLOW) 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): - 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 = {} @@ -125,8 +115,14 @@ class CipherPropsProvider: protocol = protocol[:pos] # 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: @@ -143,18 +139,7 @@ class CipherPropsProvider: 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