maykinmedia / django-simple-certmanager

MIT License
0 stars 0 forks source link

Support other TLS/SSL certificates formats (currently only PEM) #43

Open sam-bertin opened 3 months ago

sam-bertin commented 3 months ago

https://github.com/maykinmedia/django-simple-certmanager/pull/40#discussion_r1703670347

It would be interesting to consider the other files formats for the certificates we upload. So far we have decided to only support PEM.

ALL TLS/SSL CERTIFICATES FORMATS : https://www.sslmarket.com/ssl/tls-certificate-formats-and-their-use

ALL X509 CERTIFICATES FORMATS https://cryptography.io/en/latest/x509/reference/#loading-certificates

sam-bertin commented 3 months ago

maybe something like this can be done for the loading part.

# Create custom error classes for better error handling
class Invalidx509CertificateError(Exception):
    pass

class InvalidPKCS12CertificateError(Exception):
    pass

class InvalidPKCS7CertificateError(Exception):
    pass

def load_certificate_file(
    cert_file: InMemoryUploadedFile, password: Optional[str] = None,
):
    if cert_file.content_type == "application/x-x509-ca-cert":
        # Verify if PEM or DER
        # Could be multiple certificates in one file
        try:
            certs = x509.load_pem_x509_certificates(cert_file.read())
        except ValueError:
            try:
                # DER method only accepts one certificate
                cert_file.seek(0)
                certs = x509.load_der_x509_certificate(
                    cert_file.read(), default_backend()
                )
            except ValueError:
                raise Invalidx509CertificateError()
    elif cert_file.content_type == "application/pkcs12":
        # Could be multiple certificates in one file
        # Password is required for PFX/P12
        try:
            certs = pkcs12.load_pkcs12(
                cert_file.read(), password.encode(), default_backend()
            )
        except ValueError:
            try:
                cert_file.seek(0)
                certs = pkcs12.load_key_and_certificates(
                    cert_file.read(), password.encode(), default_backend()
                )
            except ValueError:
                raise InvalidPKCS12CertificateError()
    elif cert_file.content_type == "application/x-pkcs7-certificates":
        # Verify if PEM or DER
        # Could be multiple certificates in one file
        try:
            certs = pkcs7.load_der_pkcs7_certificates(cert_file.read())
        except ValueError:
            try:
                cert_file.seek(0)
                certs = pkcs7.load_pem_pkcs7_certificates(cert_file.read())
            except ValueError:
                raise InvalidPKCS7CertificateError()
    elif cert_file.content_type == "application/x-java-keystore":
        # Password is required for JKS
        raise NotImplementedError()

    return certs