@@ -90,7 +90,7 @@ def verify_x509_attestation_chain(x5c: list[bytes]) -> bool:
9090 if not _check_datetime (exp ):
9191 return False
9292
93- pems = [DER_cert_to_PEM_cert (cert ) for cert in x5c ]
93+ pems = [to_PEM_cert (cert ) for cert in x5c ]
9494
9595 return _verify_x509_certificate_chain (pems )
9696
@@ -149,8 +149,22 @@ def to_PEM_cert(cer: str | bytes) -> str:
149149 use it unless you do NOT hany prior way to know the actual representation
150150 format of a certificate
151151 """
152- raise NotImplementedError ( "TODO" )
152+ cert_s = b""
153153
154+ if isinstance (cer , str ):
155+ if is_pem_format (cer ):
156+ return cer
157+ cert_s = cer .encode ()
158+ else :
159+ cert_s = cer
160+
161+ if cert_s .startswith (b"-----BEGIN CERTIFICATE-----" ):
162+ return str (cert_s )
163+
164+ if _BASE64_RE .fullmatch (str (cert_s )):
165+ return B64DER_cert_to_PEM_cert (cert_s )
166+ else :
167+ return DER_cert_to_PEM_cert (cert_s )
154168
155169def pem_to_pems_list (cert : str ) -> list [str ]:
156170 """
@@ -164,29 +178,31 @@ def pem_to_pems_list(cert: str) -> list[str]:
164178 """
165179 return [str (cert ) for cert in pem .parse (cert )]
166180
167- def der_list_to_pem_list (der_list : list [bytes ]) -> list [str ]:
181+ def to_pem_list (der_list : list [bytes ] | list [ str ]) -> list [str ]:
168182 """
169- Convert the x509 certificate chain from DER to PEM.
183+ If the input is a list of DER certificates, it will be converted to a list of PEM certificates.
184+ If the input is a list of PEM certificates, it will be returned as is.
170185
171186 :param der: The x509 certificate chain in DER format
172187 :type der: list[bytes]
173188
174189 :returns: The x509 certificate chain in PEM format
175190 :rtype: list[str]
176191 """
177- return [DER_cert_to_PEM_cert (cert ) for cert in der_list ]
192+ return [to_PEM_cert (cert ) for cert in der_list ]
178193
179- def pem_list_to_der_list (pem_list : list [str ]) -> list [bytes ]:
194+ def to_der_list (pem_list : list [str ] | list [ bytes ]) -> list [bytes ]:
180195 """
181- Convert the x509 certificate chain from PEM to DER.
196+ If the input is a list of PEM certificates, it will be converted to a list of DER certificates.
197+ If the input is a list of DER certificates, it will be returned as is.
182198
183199 :param pem_list: The x509 certificate chain in PEM format
184200 :type pem_list: list[str]
185201
186202 :returns: The x509 certificate chain in DER format
187203 :rtype: list[bytes]
188204 """
189- return [PEM_cert_to_DER_cert (cert ) for cert in pem_list ]
205+ return [to_DER_cert (cert ) for cert in pem_list ]
190206
191207def get_expiry_date_from_x5c (x5c : list [bytes ]) -> datetime :
192208 """
@@ -211,7 +227,7 @@ def verify_x509_anchor(pem_str: str) -> bool:
211227 :returns: True if the x509 anchor certificate is valid else False
212228 :rtype: bool
213229 """
214- cert_data = load_der_x509_certificate (PEM_cert_to_DER_cert (pem_str ))
230+ cert_data = load_der_x509_certificate (to_DER_cert (pem_str ))
215231
216232 if not _check_datetime (cert_data .not_valid_after ):
217233 logging .error (LOG_ERROR .format ("check datetime failed" ))
@@ -258,7 +274,7 @@ def get_issuer_from_x5c(x5c: list[bytes] | list[str]) -> Optional[str]:
258274 :returns: The issuer
259275 :rtype: str
260276 """
261- der = x5c [ 0 ] if isinstance ( x5c [ 0 ], bytes ) else PEM_cert_to_DER_cert (x5c [0 ])
277+ der = to_DER_cert (x5c [0 ])
262278 return get_get_subject_name (der )
263279
264280
@@ -272,7 +288,7 @@ def get_trust_anchor_from_x5c(x5c: list[bytes] | list[str]) -> Optional[str]:
272288 :returns: The issuer
273289 :rtype: str
274290 """
275- der = x5c [ - 1 ] if isinstance ( x5c [ - 1 ], bytes ) else PEM_cert_to_DER_cert (x5c [- 1 ])
291+ der = to_DER_cert (x5c [- 1 ])
276292 return get_get_subject_name (der )
277293
278294def get_expiry_date_from_x5c (x5c : list [bytes ] | list [str ]) -> datetime :
@@ -285,7 +301,7 @@ def get_expiry_date_from_x5c(x5c: list[bytes] | list[str]) -> datetime:
285301 :returns: The expiry date
286302 :rtype: datetime
287303 """
288- der = x5c [ 0 ] if isinstance ( x5c [ 0 ], bytes ) else PEM_cert_to_DER_cert (x5c [0 ])
304+ der = to_DER_cert (x5c [0 ])
289305 cert = load_der_x509_certificate (der )
290306 return cert .not_valid_after
291307
@@ -303,7 +319,7 @@ def get_x509_info(cert: bytes | str, info_type: str = "x509_san_dns") -> str:
303319 """
304320 get_common_name = lambda cert : cert .subject .get_attributes_for_oid (x509 .NameOID .COMMON_NAME )[0 ].value
305321
306- der = cert if isinstance ( cert , bytes ) else PEM_cert_to_DER_cert (cert )
322+ der = to_DER_cert (cert )
307323 cert : x509 .Certificate = load_der_x509_certificate (der , default_backend ())
308324
309325 try :
@@ -334,13 +350,29 @@ def is_der_format(cert: bytes) -> str:
334350 except crypto .Error as e :
335351 logging .error (LOG_ERROR .format (e ))
336352 return False
353+
354+ def is_pem_format (cert : str ) -> str :
355+ """
356+ Check if the certificate is in PEM format.
337357
358+ :param cert: The certificate
359+ :type cert: bytes
360+
361+ :returns: True if the certificate is in PEM format else False
362+ :rtype: bool
363+ """
364+ try :
365+ crypto .load_certificate (crypto .FILETYPE_PEM , cert )
366+ return True
367+ except crypto .Error as e :
368+ logging .error (LOG_ERROR .format (e ))
369+ return False
338370
339371def get_public_key_from_x509_chain (x5c : list [bytes ]) -> ECKey | RSAKey | dict :
340372 raise NotImplementedError ("TODO" )
341373
342374def get_certificate_type (cert : str | bytes ) -> str :
343- pem = cert if isinstance ( cert , str ) and cert . startswith ( "-----BEGIN CERTIFICATE-----" ) else DER_cert_to_PEM_cert (cert )
375+ pem = to_PEM_cert (cert )
344376
345377 cert = x509 .load_pem_x509_certificate (pem .encode (), default_backend ())
346378 public_key = cert .public_key ()
0 commit comments