Public
Snippet $176 authored by Owo Sugiana

SSL Info

ssl_info.py
import socket
import ssl
from datetime import datetime, timezone
from cryptography import x509
from cryptography.hazmat.primitives import serialization


def ssl_info(hostname, port=443):
    # Inisialisasi variabel status keamanan
    code = 0  # OK
    message = "OK"
    cert_der = None
    # --- LANGKAH 1: Uji Validitas SSL (Deteksi Error) ---
    standard_context = ssl.create_default_context()
    try:
        with socket.create_connection((hostname, port), timeout=5) as sock:
            with standard_context.wrap_socket(
                    sock, server_hostname=hostname) as ssock:
                cert_der = ssock.getpeercert(binary_form=True)
    except ssl.SSLCertVerificationError as e:
        code = e.errno  # 1
        message = e.reason
    except socket.gaierror as e:
        code = e.errno  # -2
        message = e.strerror
    if code not in (0, 1):
        return dict(code=code, message=message)
    # --- LANGKAH 2: Ambil Data Secara Paksa Jika Terjadi Error ---
    if code == 1:
        # Buat konteks longgar tanpa verifikasi keamanan untuk mengunduh
        # sertifikat bermasalah
        bypass_context = ssl.create_default_context()
        bypass_context.check_hostname = False
        bypass_context.verify_mode = ssl.CERT_NONE
        with socket.create_connection((hostname, port), timeout=5) as sock:
            with bypass_context.wrap_socket(
                    sock, server_hostname=hostname) as ssock:
                cert_der = ssock.getpeercert(binary_form=True)
    # --- LANGKAH 3: Parse Data Sertifikat Memakai Cryptography ---
    cert = x509.load_der_x509_certificate(cert_der)
    # A. Ekstrak Penerbit (Issuer)
    issuer_orgs = cert.issuer.get_attributes_for_oid(
        x509.oid.NameOID.ORGANIZATION_NAME)
    if not issuer_orgs:
        issuer_orgs = cert.issuer.get_attributes_for_oid(
            x509.oid.NameOID.COMMON_NAME)
    issuer_name = issuer_orgs[0].value if issuer_orgs else "Tidak Diketahui"
    # B. Ekstrak Tanggal Kedaluwarsa
    expiry_date = cert.not_valid_after_utc
    days_left = (expiry_date - datetime.now(timezone.utc)).days
    if days_left < 0:
        code = 2
        message = f'Kedaluwarsa {abs(days_left)} hari yang lalu'
    # C. Ekstrak Public Key (Format PEM)
    public_key = cert.public_key()
    pem_public_key = public_key.public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
    ).decode('utf-8')
    return dict(
        code=code,
        message=message,
        issuer=issuer_name,
        expiry_date=expiry_date,
        days_left=days_left,
        public_key=pem_public_key)


if __name__ == "__main__":
    import sys
    from pprint import pprint
    hostname = sys.argv[1]
    r = ssl_info(hostname)
    pprint(r)