Toggle Light / Dark / Auto color theme
Toggle table of contents sidebar
Source code for commands.create_tls_certs
"""Django management command for creating a self-signed TLS server credential."""
from __future__ import annotations
import datetime
import ipaddress
import subprocess
from pathlib import Path
from cryptography import x509
from cryptography.hazmat.primitives import hashes , serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from django.core.management.base import BaseCommand
[docs]
BASE_PATH = Path ( __file__ ) . parent . parent . parent . parent . parent / 'tests/data/x509/'
[docs]
SERVER_CERT_PATH = BASE_PATH / 'https_server.crt'
[docs]
SERVER_KEY_PATH = BASE_PATH / 'https_server.pem'
[docs]
class Command ( BaseCommand ):
"""Django management command for creating a self-signed TLS server credential."""
[docs]
help = 'Creates a TLS Server Certificate as required.'
[docs]
def handle ( self , * _args : tuple [ str ], ** _kwargs : dict [ str , str ]) -> None :
"""Executes the command."""
one_day = datetime . timedelta ( 1 , 0 , 0 )
ipv4_addresses = subprocess . check_output ([ 'hostname' , '-I' ]) . decode () . strip () # noqa: S603, S607
# ipv4_addresses = '10.10.0.5 10.10.4.89' # noqa: ERA001
ipv4_addresses_list = ipv4_addresses . split ( ' ' )
ipv4_addresses_list . append ( '127.0.0.1' )
basic_constraints_extension = x509 . BasicConstraints ( ca = False , path_length = None )
key_usage_extension = x509 . KeyUsage (
digital_signature = True ,
content_commitment = False ,
key_encipherment = True ,
data_encipherment = True ,
key_agreement = False ,
key_cert_sign = False ,
crl_sign = False ,
decipher_only = False ,
encipher_only = False ,
)
extended_key_usage_extension = x509 . ExtendedKeyUsage ([ x509 . oid . ExtendedKeyUsageOID . SERVER_AUTH ])
subject_alt_name_content = [ x509 . DNSName ( 'localhost' ), x509 . DNSName ( 'trustpoint.local' )]
subject_alt_name_content . extend ( x509 . IPAddress ( ipaddress . IPv4Address ( ipv4 )) for ipv4 in ipv4_addresses_list )
subject_alternative_names_extension = x509 . SubjectAlternativeName ( subject_alt_name_content )
subject = x509 . Name (
[
x509 . NameAttribute ( x509 . oid . NameOID . COMMON_NAME , 'Trustpoint TLS Server Certificate' ),
x509 . NameAttribute ( x509 . oid . NameOID . COUNTRY_NAME , 'DE' ),
x509 . NameAttribute ( x509 . oid . NameOID . ORGANIZATION_NAME , 'Trustpoint Project' ),
]
)
issuer = subject
private_key = rsa . generate_private_key (
public_exponent = 65537 ,
key_size = 4096 ,
)
public_key = private_key . public_key ()
builder = x509 . CertificateBuilder ()
builder = builder . subject_name ( subject )
builder = builder . issuer_name ( issuer )
builder = builder . not_valid_before ( datetime . datetime . now ( tz = datetime . UTC ) - one_day )
builder = builder . not_valid_after ( datetime . datetime . now ( tz = datetime . UTC ) + ( one_day * 365 ))
builder = builder . serial_number ( x509 . random_serial_number ())
builder = builder . public_key ( public_key )
builder = builder . add_extension ( basic_constraints_extension , critical = True )
builder = builder . add_extension ( key_usage_extension , critical = False )
builder = builder . add_extension ( extended_key_usage_extension , critical = True )
builder = builder . add_extension ( subject_alternative_names_extension , critical = True )
certificate = builder . sign ( private_key = private_key , algorithm = hashes . SHA256 ())
SERVER_CERT_PATH . write_text ( certificate . public_bytes ( serialization . Encoding . PEM ) . decode ())
SERVER_KEY_PATH . write_text (
private_key . private_bytes (
encoding = serialization . Encoding . PEM ,
format = serialization . PrivateFormat . TraditionalOpenSSL ,
encryption_algorithm = serialization . NoEncryption (),
) . decode ()
)