Skip to content

Commit d0d3923

Browse files
committed
Add TLS Checker
1 parent 050c7ff commit d0d3923

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ narbeh@narbeh-laptop:~/ssl-checker$ ./ssl_checker.py -H time.com github.com:443
9393
Valid from: 2019-09-06
9494
Valid to: 2020-10-06 (78 days left)
9595
Validity days: 396
96+
TLS Version: TLS 1.2
9697
Certificate valid: True
9798
Certificate S/N: 20641318859548253362475798736742284477
9899
Certificate SHA1 FP: D5:CE:1B:77:AB:59:C9:BE:37:58:0F:5D:73:97:64:98:C4:3E:43:30
@@ -112,6 +113,7 @@ narbeh@narbeh-laptop:~/ssl-checker$ ./ssl_checker.py -H time.com github.com:443
112113
Valid from: 2020-05-05
113114
Valid to: 2022-05-10 (659 days left)
114115
Validity days: 735
116+
TLS Version: TLS 1.2
115117
Certificate valid: True
116118
Certificate S/N: 7101927171473588541993819712332065657
117119
Certificate SHA1 FP: 5F:3F:7A:C2:56:9F:50:A4:66:76:47:C6:A1:8C:A0:07:AA:ED:BB:8E
@@ -158,6 +160,7 @@ narbeh@narbeh-xps:~/ssl-checker$ ./ssl_checker.py -H facebook.com -s localhost:9
158160
Valid from: 2020-05-14
159161
Valid to: 2020-08-05 (16 days left)
160162
Validity days: 83
163+
TLS Version: TLS 1.2
161164
Certificate valid: True
162165
Certificate S/N: 19351530099991824979726880175805235719
163166
Certificate SHA1 FP: 89:7F:54:63:61:34:2F:7E:B4:B5:68:E2:92:79:D2:98:B4:97:D8:EA
@@ -216,6 +219,7 @@ Warning: -a/--analyze is enabled. It takes more time...
216219
Valid from: 2018-04-21
217220
Valid to: 2018-07-20 (88 days left)
218221
Validity days: 90
222+
TLS Version: TLS 1.2
219223
Certificate S/N: 338163108483756707389368573553026254634358
220224
Certificate version: 2
221225
Certificate algorithm: sha256WithRSAEncryption

ssl_checker.py

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,37 @@ def get_cert(self, host, port, socks_host=None, socks_port=None):
4141
socket.socket = socks.socksocket
4242

4343
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
44-
osobj = SSL.Context(SSL.TLSv1_2_METHOD)
4544
sock.settimeout(5)
4645
sock.connect((host, int(port)))
4746
sock.settimeout(None)
48-
oscon = SSL.Connection(osobj, sock)
49-
oscon.set_tlsext_host_name(host.encode())
50-
oscon.set_connect_state()
51-
oscon.do_handshake()
52-
cert = oscon.get_peer_certificate()
53-
resolved_ip = socket.gethostbyname(host)
54-
sock.close()
55-
56-
return cert, resolved_ip
47+
48+
# Try different TLS versions in order of preference (newest to oldest)
49+
tls_methods = [
50+
(SSL.TLSv1_2_METHOD, "TLS 1.2"), # TLS 1.2
51+
(SSL.TLSv1_1_METHOD, "TLS 1.1"), # TLS 1.1
52+
(SSL.TLSv1_METHOD, "TLS 1.0"), # TLS 1.0
53+
]
54+
55+
for tls_method, tls_version in tls_methods:
56+
try:
57+
osobj = SSL.Context(tls_method)
58+
oscon = SSL.Connection(osobj, sock)
59+
oscon.set_tlsext_host_name(host.encode())
60+
oscon.set_connect_state()
61+
oscon.do_handshake()
62+
cert = oscon.get_peer_certificate()
63+
resolved_ip = socket.gethostbyname(host)
64+
sock.close()
65+
return cert, resolved_ip, tls_version
66+
except SSL.SysCallError as e:
67+
# If this TLS version fails, try the next one
68+
continue
69+
except Exception as e:
70+
# For other exceptions, try the next TLS version
71+
continue
72+
73+
# If all TLS versions fail, raise the last exception
74+
raise SSL.SysCallError("Failed to establish SSL connection with any supported TLS version")
5775

5876
def border_msg(self, message):
5977
"""Print the message in the box."""
@@ -122,14 +140,15 @@ def get_cert_sans(self, x509cert):
122140
san = san.replace(',', ';')
123141
return san
124142

125-
def get_cert_info(self, host, cert, resolved_ip):
143+
def get_cert_info(self, host, cert, resolved_ip, tls_version=None):
126144
"""Get all the information about cert and create a JSON file."""
127145
context = {}
128146

129147
cert_subject = cert.get_subject()
130148

131149
context['host'] = host
132150
context['resolved_ip'] = resolved_ip
151+
context['tls_version'] = tls_version
133152
context['issued_to'] = cert_subject.CN
134153
context['issued_o'] = cert_subject.O
135154
context['issuer_c'] = cert.get_issuer().countryName
@@ -186,6 +205,7 @@ def print_status(self, host, context, analyze=False):
186205
print('\t\tValid from: {}'.format(context[host]['valid_from']))
187206
print('\t\tValid to: {} ({} days left)'.format(context[host]['valid_till'], context[host]['valid_days_to_expire']))
188207
print('\t\tValidity days: {}'.format(context[host]['validity_days']))
208+
print('\t\tTLS Version: {}'.format(context[host]['tls_version']))
189209
print('\t\tCertificate valid: {}'.format(context[host]['cert_valid']))
190210
print('\t\tCertificate S/N: {}'.format(context[host]['cert_sn']))
191211
print('\t\tCertificate SHA1 FP: {}'.format(context[host]['cert_sha1']))
@@ -238,11 +258,11 @@ def show_result(self, user_args):
238258
print('{}Socks proxy enabled, connecting via proxy{}\n'.format(Clr.YELLOW, Clr.RST))
239259

240260
socks_host, socks_port = self.filter_hostname(user_args.socks)
241-
cert, resolved_ip = self.get_cert(host, port, socks_host, socks_port)
261+
cert, resolved_ip, tls_version = self.get_cert(host, port, socks_host, socks_port)
242262
else:
243-
cert, resolved_ip = self.get_cert(host, port)
263+
cert, resolved_ip, tls_version = self.get_cert(host, port)
244264

245-
context[host] = self.get_cert_info(host, cert, resolved_ip)
265+
context[host] = self.get_cert_info(host, cert, resolved_ip, tls_version)
246266
context[host]['tcp_port'] = int(port)
247267

248268
# Analyze the certificate if enabled

0 commit comments

Comments
 (0)