Spaces:
Sleeping
Sleeping
Create app.py
Browse files
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()
|