"""Membuat sertifikat HTTPS self-signed untuk server guru.
Pemakaian: python gen_cert.py [IP_SERVER] [NAMA_HOST]
Hasil: data/server.crt (salin ke komputer siswa untuk -CaFile) dan data/server.key (RAHASIA)."""
import datetime
import ipaddress
import socket
import sys
from pathlib import Path

from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID

out = Path(__file__).parent / "data"
out.mkdir(exist_ok=True)
host = socket.gethostname()
ips = {"127.0.0.1"}
try:
    ips.update(i[4][0] for i in socket.getaddrinfo(host, None, socket.AF_INET))
except OSError:
    pass
names = {host, "localhost"}
for a in sys.argv[1:]:
    try:
        ips.add(str(ipaddress.ip_address(a)))
    except ValueError:
        names.add(a)
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "Classroom Management Server")])
now = datetime.datetime.now(datetime.timezone.utc)
san = [x509.DNSName(n) for n in sorted(names)] + [x509.IPAddress(ipaddress.ip_address(i)) for i in sorted(ips)]
cert = (x509.CertificateBuilder().subject_name(name).issuer_name(name).public_key(key.public_key())
        .serial_number(x509.random_serial_number()).not_valid_before(now - datetime.timedelta(days=1))
        .not_valid_after(now + datetime.timedelta(days=825))
        .add_extension(x509.SubjectAlternativeName(san), critical=False)
        .add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True)
        .sign(key, hashes.SHA256()))
(out / "server.crt").write_bytes(cert.public_bytes(serialization.Encoding.PEM))
(out / "server.key").write_bytes(key.private_bytes(serialization.Encoding.PEM, serialization.PrivateFormat.TraditionalOpenSSL, serialization.NoEncryption()))
print("Sertifikat dibuat di", out)
print("Berlaku untuk:", ", ".join(sorted(names) + sorted(ips)))
print("Salin server.crt ke komputer siswa. JANGAN bagikan server.key.")
