7777
7878# Increment this PATCH version before using `charmcraft publish-lib` or reset
7979# to 0 if you are raising the major API version
80- LIBPATCH = 25
80+ LIBPATCH = 26
8181
8282PYDEPS = [
8383 "cryptography>=43.0.0" ,
@@ -868,6 +868,15 @@ def __str__(self) -> str:
868868 """Return the CSR as a string."""
869869 return self ._csr .public_bytes (serialization .Encoding .PEM ).decode ().strip ()
870870
871+ @property
872+ def additional_critical_extensions (self ) -> List [x509 .ExtensionType ]:
873+ """Return additional critical extensions present on the CSR (excluding SAN)."""
874+ extensions : List [x509 .ExtensionType ] = []
875+ for extension in self ._csr .extensions :
876+ if extension .critical and extension .oid != ExtensionOID .SUBJECT_ALTERNATIVE_NAME :
877+ extensions .append (extension .value )
878+ return extensions
879+
871880 @classmethod
872881 def from_string (cls , csr : str ) -> "CertificateSigningRequest" :
873882 """Create a CertificateSigningRequest object from a CSR."""
@@ -987,6 +996,9 @@ def generate(
987996 csr_builder = csr_builder .add_extension (
988997 x509 .SubjectAlternativeName (set (_sans )), critical = False
989998 )
999+ if attributes .additional_critical_extensions :
1000+ for extension in attributes .additional_critical_extensions :
1001+ csr_builder = csr_builder .add_extension (extension , critical = True )
9901002 signed_certificate_request = csr_builder .sign (signing_key , hashes .SHA256 ())
9911003 return cls (x509_object = signed_certificate_request )
9921004
@@ -1008,6 +1020,7 @@ def __init__(
10081020 locality_name : Optional [str ] = None ,
10091021 is_ca : bool = False ,
10101022 add_unique_id_to_subject_name : bool = True ,
1023+ additional_critical_extensions : Optional [Collection [x509 .ExtensionType ]] = None ,
10111024 ):
10121025 if not common_name and not sans_dns and not sans_ip and not sans_oid :
10131026 raise ValueError (
@@ -1025,6 +1038,7 @@ def __init__(
10251038 self ._locality_name = locality_name
10261039 self ._is_ca = is_ca
10271040 self ._add_unique_id_to_subject_name = add_unique_id_to_subject_name
1041+ self ._additional_critical_extensions = list (additional_critical_extensions or [])
10281042
10291043 @property
10301044 def common_name (self ) -> str :
@@ -1087,6 +1101,11 @@ def add_unique_id_to_subject_name(self) -> bool:
10871101 """Return whether to add a unique identifier to the subject name."""
10881102 return self ._add_unique_id_to_subject_name
10891103
1104+ @property
1105+ def additional_critical_extensions (self ) -> List [x509 .ExtensionType ]:
1106+ """Return additional critical extensions to be added to the CSR."""
1107+ return self ._additional_critical_extensions
1108+
10901109 @classmethod
10911110 def from_csr (
10921111 cls , csr : CertificateSigningRequest , is_ca : bool
@@ -1113,6 +1132,7 @@ def from_csr(
11131132 locality_name = csr .locality_name ,
11141133 is_ca = is_ca ,
11151134 add_unique_id_to_subject_name = csr .has_unique_identifier ,
1135+ additional_critical_extensions = csr .additional_critical_extensions ,
11161136 )
11171137
11181138 def __eq__ (self , other : object ) -> bool :
@@ -1132,6 +1152,7 @@ def __eq__(self, other: object) -> bool:
11321152 and self .locality_name == other .locality_name
11331153 and self .is_ca == other .is_ca
11341154 and self .add_unique_id_to_subject_name == other .add_unique_id_to_subject_name
1155+ and self .additional_critical_extensions == other .additional_critical_extensions
11351156 )
11361157
11371158 def is_valid (self ) -> bool :
0 commit comments