CultriX commited on
Commit
26bf868
·
verified ·
1 Parent(s): 454716c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +99 -0
app.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Import necessary libraries
2
+ import gradio as gr
3
+ import ssl
4
+ import socket
5
+ import logging
6
+ import json
7
+ from cryptography import x509
8
+ from cryptography.hazmat.backends import default_backend
9
+ from cryptography.hazmat.primitives import hashes
10
+ from datetime import datetime, timezone
11
+
12
+ def setup_logging():
13
+ logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
14
+ file_handler = logging.FileHandler("ssl_check.log")
15
+ file_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
16
+ logging.getLogger().addHandler(file_handler)
17
+
18
+ setup_logging()
19
+
20
+ def get_fingerprints(cert):
21
+ return {
22
+ "SHA-256": cert.fingerprint(hashes.SHA256()).hex(),
23
+ "SHA-1": cert.fingerprint(hashes.SHA1()).hex(),
24
+ "MD5": cert.fingerprint(hashes.MD5()).hex(),
25
+ }
26
+
27
+ def get_san_list(cert):
28
+ try:
29
+ san_extension = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName)
30
+ return san_extension.value.get_values_for_type(x509.DNSName)
31
+ except x509.ExtensionNotFound:
32
+ return []
33
+
34
+ def extract_certificate_details(cert):
35
+ now = datetime.now(timezone.utc)
36
+ expiry_date = cert.not_valid_after
37
+ not_before = cert.not_valid_before
38
+ days_remaining = (expiry_date - now).days
39
+ fingerprints = get_fingerprints(cert)
40
+ san_list = get_san_list(cert)
41
+
42
+ return {
43
+ "expiry_date": expiry_date.isoformat(),
44
+ "not_before": not_before.isoformat(),
45
+ "days_remaining": days_remaining,
46
+ "fingerprints": fingerprints,
47
+ "issuer": {attr.oid._name: attr.value for attr in cert.issuer},
48
+ "subject": {attr.oid._name: attr.value for attr in cert.subject},
49
+ "san_list": san_list,
50
+ }
51
+
52
+ def establish_tls_connection(hostname, port, timeout):
53
+ context = ssl.create_default_context()
54
+ context.check_hostname = False
55
+ context.verify_mode = ssl.CERT_REQUIRED
56
+
57
+ with socket.create_connection((hostname, port), timeout=timeout) as sock:
58
+ with context.wrap_socket(sock, server_hostname=hostname) as tls_conn:
59
+ peer_cert_bin = tls_conn.getpeercert(binary_form=True)
60
+ if not peer_cert_bin:
61
+ raise ValueError("Peer certificate is missing.")
62
+ return peer_cert_bin, tls_conn.version()
63
+
64
+ def check_certificate(hostname, port, timeout):
65
+ try:
66
+ peer_cert_bin, tls_version = establish_tls_connection(hostname, port, timeout)
67
+ cert = x509.load_der_x509_certificate(peer_cert_bin, default_backend())
68
+ cert_details = extract_certificate_details(cert)
69
+ cert_details["tls_version"] = tls_version
70
+ return json.dumps(cert_details, indent=2)
71
+ except Exception as e:
72
+ logging.error(f"Error checking certificate: {e}")
73
+ return f"Error: {e}"
74
+
75
+ def gradio_interface(hostname, port, timeout):
76
+ try:
77
+ port = int(port)
78
+ timeout = int(timeout)
79
+ return check_certificate(hostname, port, timeout)
80
+ except ValueError:
81
+ return "Port and timeout must be integers."
82
+
83
+ def create_interface():
84
+ iface = gr.Interface(
85
+ fn=gradio_interface,
86
+ inputs=[
87
+ gr.Textbox(label="Hostname", placeholder="Enter server hostname", lines=1),
88
+ gr.Number(label="Port", value=443),
89
+ gr.Number(label="Timeout (seconds)", value=10),
90
+ ],
91
+ outputs=gr.Textbox(label="Certificate Details"),
92
+ title="SSL Certificate Checker",
93
+ description="Check the SSL certificate details of a server.",
94
+ )
95
+ return iface
96
+
97
+ if __name__ == "__main__":
98
+ iface = create_interface()
99
+ iface.launch()