diff --git a/accesser/__init__.py b/accesser/__init__.py index 2d8da8d..7e96d14 100644 --- a/accesser/__init__.py +++ b/accesser/__init__.py @@ -64,7 +64,7 @@ async def send_pac(writer: asyncio.StreamWriter): await writer.wait_closed() async def send_crt(writer: asyncio.StreamWriter, path: str): - with open(os.path.join(basepath, path.lstrip('/')), 'rb') as f: + with open(os.path.join(cm.certpath, path.rsplit(sep = '/',maxsplit = 1)[-1]), 'rb') as f: crt = f.read() writer.write(f'HTTP/1.1 200 OK\r\nContent-Type: application/x-x509-ca-cert\r\nContent-Length: {len(crt)}\r\n\r\n'.encode('iso-8859-1')) writer.write(crt) diff --git a/accesser/utils/certmanager.py b/accesser/utils/certmanager.py index 201d21d..f50c709 100644 --- a/accesser/utils/certmanager.py +++ b/accesser/utils/certmanager.py @@ -17,8 +17,6 @@ # along with this program. If not, see . import os -import random -import sys import datetime from pathlib import Path @@ -27,54 +25,90 @@ from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography.x509.extensions import ( + AuthorityKeyIdentifier, + KeyUsage, + ExtendedKeyUsage, + SubjectKeyIdentifier, +) +from cryptography.x509.oid import ExtendedKeyUsageOID from . import setting from .setting import basepath -if setting.config['importca']: - certpath = os.path.join(basepath, 'CERT') +if setting.config["importca"]: + certpath = os.path.join(basepath, "CERT") else: - certpath ='CERT' + certpath = "CERT" if not os.path.exists(certpath): os.makedirs(certpath, exist_ok=True) + def create_root_ca(): key = rsa.generate_private_key( public_exponent=65537, key_size=4096, ) - subject = issuer = x509.Name([ - x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Accesser"), - x509.NameAttribute(NameOID.COMMON_NAME, "Accesser"), - ]) - cert = x509.CertificateBuilder().subject_name( - subject - ).issuer_name( - issuer - ).public_key( - key.public_key() - ).serial_number( - x509.random_serial_number() - ).not_valid_before( - datetime.datetime.now(datetime.timezone.utc) - ).not_valid_after( - datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=10*365) - ).add_extension( - x509.BasicConstraints(ca=True, path_length=None), critical=True, - ).sign(key, hashes.SHA256()) - - (Path(certpath) / "root.crt").write_bytes(cert.public_bytes(serialization.Encoding.PEM)) - - (Path(certpath) / "root.key").write_bytes(key.private_bytes( - encoding=serialization.Encoding.PEM, - format=serialization.PrivateFormat.PKCS8, - encryption_algorithm=serialization.NoEncryption(), - )) - - (Path(certpath) / "root.pfx").write_bytes(serialization.pkcs12.serialize_key_and_certificates( - b"Accesser", key, cert, None, serialization.NoEncryption() - )) + subject = issuer = x509.Name( + [ + x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Accesser"), + x509.NameAttribute(NameOID.COMMON_NAME, "Accesser"), + ] + ) + cert = ( + x509.CertificateBuilder() + .subject_name(subject) + .issuer_name(issuer) + .public_key(key.public_key()) + .serial_number(x509.random_serial_number()) + .not_valid_before(datetime.datetime.now(datetime.timezone.utc)) + .not_valid_after( + datetime.datetime.now(datetime.timezone.utc) + + datetime.timedelta(days=10 * 365) + ) + .add_extension( + x509.BasicConstraints(ca=True, path_length=None), + critical=True, + ) + .add_extension( + KeyUsage( + digital_signature=False, + content_commitment=False, + key_encipherment=False, + data_encipherment=False, + key_agreement=False, + key_cert_sign=True, + crl_sign=True, + encipher_only=False, + decipher_only=False, + ), + critical=True, + ) + .add_extension( + SubjectKeyIdentifier.from_public_key(key.public_key()), + critical=False, + ) + .sign(key, hashes.SHA256()) + ) + + (Path(certpath) / "root.crt").write_bytes( + cert.public_bytes(serialization.Encoding.PEM) + ) + + (Path(certpath) / "root.key").write_bytes( + key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption(), + ) + ) + + (Path(certpath) / "root.pfx").write_bytes( + serialization.pkcs12.serialize_key_and_certificates( + b"Accesser", key, cert, None, serialization.NoEncryption() + ) + ) def create_certificate(server_name): @@ -83,32 +117,72 @@ def create_certificate(server_name): ca_cert = x509.load_pem_x509_certificate(rootpem) pkey = serialization.load_pem_private_key(rootkey, password=None) - cert = x509.CertificateBuilder().subject_name(x509.Name([ - x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Accesser"), - x509.NameAttribute(NameOID.COMMON_NAME, "Accesser_Proxy"), - ]) - ).issuer_name( - ca_cert.subject - ).public_key( - pkey.public_key() - ).serial_number( - x509.random_serial_number() - ).not_valid_before( - datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(seconds=600) - ).not_valid_after( - datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=365) - ).add_extension( - x509.SubjectAlternativeName([ - x509.DNSName(server_name), - x509.DNSName('*.'+server_name), - ]), - critical=False, - ).sign(pkey, hashes.SHA256()) - + cert = ( + x509.CertificateBuilder() + .subject_name( + x509.Name( + [ + x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Accesser"), + x509.NameAttribute(NameOID.COMMON_NAME, "Accesser_Proxy"), + ] + ) + ) + .issuer_name(ca_cert.subject) + .public_key(pkey.public_key()) + .serial_number(x509.random_serial_number()) + .not_valid_before( + datetime.datetime.now(datetime.timezone.utc) + - datetime.timedelta(seconds=600) + ) + .not_valid_after( + datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=365) + ) + .add_extension( + x509.SubjectAlternativeName( + [ + x509.DNSName(server_name), + x509.DNSName("*." + server_name), + ] + ), + critical=False, + ) + .add_extension( + KeyUsage( + digital_signature=True, + content_commitment=False, + key_encipherment=False, + data_encipherment=False, + key_agreement=False, + key_cert_sign=False, + crl_sign=False, + encipher_only=False, + decipher_only=False, + ), + critical=True, + ) + .add_extension( + AuthorityKeyIdentifier.from_issuer_public_key(pkey.public_key()), + critical=False, + ) + .add_extension( + SubjectKeyIdentifier.from_public_key(pkey.public_key()), + critical=False, + ) + .add_extension( + ExtendedKeyUsage( + usages=[ + ExtendedKeyUsageOID.SERVER_AUTH, + ExtendedKeyUsageOID.CLIENT_AUTH, + ] + ), + critical=True, + ) + .sign(pkey, hashes.SHA256()) + ) (Path(certpath) / f"{server_name}.crt").write_bytes( - cert.public_bytes(serialization.Encoding.PEM) + - pkey.private_bytes( + cert.public_bytes(serialization.Encoding.PEM) + + pkey.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption(),