diff --git a/changelogs/fragments/622-der-format-support.yml b/changelogs/fragments/622-der-format-support.yml new file mode 100644 index 000000000..b4ba93e67 --- /dev/null +++ b/changelogs/fragments/622-der-format-support.yml @@ -0,0 +1,2 @@ +minor_changes: + - "x509_certificate_info - added support for certificates in DER format when using ``path`` parameter (https://github.com/ansible-collections/community.crypto/issues/603)." diff --git a/plugins/module_utils/crypto/module_backends/certificate_info.py b/plugins/module_utils/crypto/module_backends/certificate_info.py index a7beec6c1..b10733ceb 100644 --- a/plugins/module_utils/crypto/module_backends/certificate_info.py +++ b/plugins/module_utils/crypto/module_backends/certificate_info.py @@ -143,9 +143,9 @@ def _get_ocsp_uri(self): def _get_issuer_uri(self): pass - def get_info(self, prefer_one_fingerprint=False): + def get_info(self, prefer_one_fingerprint=False, der_support_enabled=False): result = dict() - self.cert = load_certificate(None, content=self.content, backend=self.backend) + self.cert = load_certificate(None, content=self.content, backend=self.backend, der_support_enabled=der_support_enabled) result['signature_algorithm'] = self._get_signature_algorithm() subject = self._get_subject_ordered() diff --git a/plugins/module_utils/crypto/support.py b/plugins/module_utils/crypto/support.py index ad8f16109..473246b1b 100644 --- a/plugins/module_utils/crypto/support.py +++ b/plugins/module_utils/crypto/support.py @@ -18,6 +18,10 @@ from ansible.module_utils import six from ansible.module_utils.common.text.converters import to_native, to_bytes +from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import ( + identify_pem_format, +) + try: from OpenSSL import crypto HAS_PYOPENSSL = True @@ -189,7 +193,7 @@ def load_publickey(path=None, content=None, backend=None): raise OpenSSLObjectError('Error while deserializing key: {0}'.format(e)) -def load_certificate(path, content=None, backend='cryptography'): +def load_certificate(path, content=None, backend='cryptography', der_support_enabled=False): """Load the specified certificate.""" try: @@ -201,12 +205,21 @@ def load_certificate(path, content=None, backend='cryptography'): except (IOError, OSError) as exc: raise OpenSSLObjectError(exc) if backend == 'pyopenssl': - return crypto.load_certificate(crypto.FILETYPE_PEM, cert_content) + if der_support_enabled is False or identify_pem_format(cert_content): + return crypto.load_certificate(crypto.FILETYPE_PEM, cert_content) + elif der_support_enabled: + raise OpenSSLObjectError('Certificate in DER format is not supported by the pyopenssl backend.') elif backend == 'cryptography': - try: - return x509.load_pem_x509_certificate(cert_content, cryptography_backend()) - except ValueError as exc: - raise OpenSSLObjectError(exc) + if der_support_enabled is False or identify_pem_format(cert_content): + try: + return x509.load_pem_x509_certificate(cert_content, cryptography_backend()) + except ValueError as exc: + raise OpenSSLObjectError(exc) + elif der_support_enabled: + try: + return x509.load_der_x509_certificate(cert_content, cryptography_backend()) + except ValueError as exc: + raise OpenSSLObjectError('Cannot parse DER certificate: {0}'.format(exc)) def load_certificate_request(path, content=None, backend='cryptography'): diff --git a/plugins/modules/x509_certificate_info.py b/plugins/modules/x509_certificate_info.py index d875c5727..145cd2195 100644 --- a/plugins/modules/x509_certificate_info.py +++ b/plugins/modules/x509_certificate_info.py @@ -40,6 +40,7 @@ description: - Remote absolute path where the certificate file is loaded from. - Either I(path) or I(content) must be specified, but not both. + - PEM and DER formats are supported. type: path content: description: @@ -447,7 +448,7 @@ def main(): valid_at[k] = get_relative_time_option(v, 'valid_at.{0}'.format(k)) try: - result = module_backend.get_info() + result = module_backend.get_info(der_support_enabled=module.params['content'] is None) not_before = module_backend.get_not_before() not_after = module_backend.get_not_after()