Spaces:
Sleeping
Sleeping
| # Import necessary libraries | |
| import gradio as gr | |
| import ssl | |
| import socket | |
| import logging | |
| import json | |
| from cryptography import x509 | |
| from cryptography.hazmat.backends import default_backend | |
| from cryptography.hazmat.primitives import hashes | |
| from datetime import datetime, timezone | |
| def setup_logging(): | |
| logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") | |
| file_handler = logging.FileHandler("ssl_check.log") | |
| file_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")) | |
| logging.getLogger().addHandler(file_handler) | |
| setup_logging() | |
| def get_fingerprints(cert): | |
| return { | |
| "SHA-256": cert.fingerprint(hashes.SHA256()).hex(), | |
| "SHA-1": cert.fingerprint(hashes.SHA1()).hex(), | |
| "MD5": cert.fingerprint(hashes.MD5()).hex(), | |
| } | |
| def get_san_list(cert): | |
| try: | |
| san_extension = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName) | |
| return san_extension.value.get_values_for_type(x509.DNSName) | |
| except x509.ExtensionNotFound: | |
| return [] | |
| def extract_certificate_details(cert): | |
| """ | |
| Extract key details from the certificate, including issuer, subject, fingerprints, and validity. | |
| Args: | |
| cert (x509.Certificate): The certificate object. | |
| Returns: | |
| dict: Dictionary containing certificate details. | |
| """ | |
| now = datetime.now(timezone.utc) | |
| expiry_date = cert.not_valid_after.replace(tzinfo=timezone.utc) | |
| not_before = cert.not_valid_before.replace(tzinfo=timezone.utc) | |
| days_remaining = (expiry_date - now).days | |
| fingerprints = get_fingerprints(cert) | |
| san_list = get_san_list(cert) | |
| return { | |
| "expiry_date": expiry_date.isoformat(), | |
| "not_before": not_before.isoformat(), | |
| "days_remaining": days_remaining, | |
| "fingerprints": fingerprints, | |
| "issuer": {attr.oid._name: attr.value for attr in cert.issuer}, | |
| "subject": {attr.oid._name: attr.value for attr in cert.subject}, | |
| "san_list": san_list, | |
| } | |
| def establish_tls_connection(hostname, port, timeout): | |
| context = ssl.create_default_context() | |
| context.check_hostname = False | |
| context.verify_mode = ssl.CERT_REQUIRED | |
| with socket.create_connection((hostname, port), timeout=timeout) as sock: | |
| with context.wrap_socket(sock, server_hostname=hostname) as tls_conn: | |
| peer_cert_bin = tls_conn.getpeercert(binary_form=True) | |
| if not peer_cert_bin: | |
| raise ValueError("Peer certificate is missing.") | |
| return peer_cert_bin, tls_conn.version() | |
| def check_certificate(hostname, port, timeout): | |
| try: | |
| peer_cert_bin, tls_version = establish_tls_connection(hostname, port, timeout) | |
| cert = x509.load_der_x509_certificate(peer_cert_bin, default_backend()) | |
| cert_details = extract_certificate_details(cert) | |
| cert_details["tls_version"] = tls_version | |
| return json.dumps(cert_details, indent=2) | |
| except Exception as e: | |
| logging.error(f"Error checking certificate: {e}") | |
| return f"Error: {e}" | |
| def gradio_interface(hostname, port, timeout): | |
| try: | |
| port = int(port) | |
| timeout = int(timeout) | |
| return check_certificate(hostname, port, timeout) | |
| except ValueError: | |
| return "Port and timeout must be integers." | |
| def create_interface(): | |
| iface = gr.Interface( | |
| fn=gradio_interface, | |
| inputs=[ | |
| gr.Textbox(label="Hostname", placeholder="Enter server hostname", lines=1), | |
| gr.Number(label="Port", value=443), | |
| gr.Number(label="Timeout (seconds)", value=10), | |
| ], | |
| outputs=gr.Textbox(label="Certificate Details"), | |
| title="SSL Certificate Checker", | |
| description="Check the SSL certificate details of a server.", | |
| ) | |
| return iface | |
| if __name__ == "__main__": | |
| iface = create_interface() | |
| iface.launch() | |