import argparse from datetime import datetime, timedelta from pathlib import Path from cryptography import x509 from cryptography.hazmat.primitives import serialization, hashes from cryptography.hazmat.primitives.asymmetric import rsa def run(parser: argparse.ArgumentParser, arguments: argparse.Namespace): print("creating a new machine...") directory_admin = Path("./assets/admin/") if not directory_admin.exists(): raise ValueError("Can't find the admin. Have you initialized it ?") directory_machine = Path(f"./assets/machine/{arguments.name}/") if directory_machine.exists(): raise ValueError("This machine already exists !") directory_machine.mkdir(parents=True) # Generate a private key private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, ) (directory_machine / "private.key").write_bytes( private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption(), ) ) certificate_admin = x509.load_pem_x509_certificate( (directory_admin / "certificate.pem").read_bytes() ) private_key_admin = serialization.load_pem_private_key( (directory_admin / "private.key").read_bytes(), password=None ) # Generate a self-signed root certificate subject = x509.Name([ x509.NameAttribute(x509.NameOID.COUNTRY_NAME, "FR"), x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, "Province"), x509.NameAttribute(x509.NameOID.LOCALITY_NAME, "Locality"), x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, "Organization"), x509.NameAttribute(x509.NameOID.COMMON_NAME, "domain.com"), ]) certificate = ( x509.CertificateBuilder() .subject_name(subject) .issuer_name(certificate_admin.subject) .public_key(private_key.public_key()) .serial_number(x509.random_serial_number()) .not_valid_before(datetime.now() - timedelta(days=1)) # TODO(Faraphel): settings .not_valid_after(datetime.now() + timedelta(days=365)) # TODO(Faraphel): settings .sign(private_key_admin, hashes.SHA256()) ) # Save the root certificate to a file (directory_machine / "certificate.pem").write_bytes(certificate.public_bytes(serialization.Encoding.PEM)) print("machine created !")