Skip to content

Commit

Permalink
openssl_pkcs12: Add support for certificate_content and `other_cert…
Browse files Browse the repository at this point in the history
…ificates_content`
  • Loading branch information
apollo13 committed Feb 17, 2025
1 parent a42e541 commit dd6c144
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 6 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/openssl_pkcs12_content.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- openssl_pkcs12 - The module now supports ``certificate_content``/``other_certificates_content`` to match ``privatekey_content`` (https://github.com/ansible-collections/community.crypto/pull/848).
42 changes: 36 additions & 6 deletions plugins/modules/openssl_pkcs12.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@
type: list
elements: path
aliases: [ca_certificates]
other_certificates_content:
description:
- List of other certificates to include.
- Mutually exclusive with O(other_certificates).
type: list
elements: str
version_added: "2.26.0"
other_certificates_parse_all:
description:
- If set to V(true), assumes that the files mentioned in O(other_certificates) can contain more than one certificate
Expand All @@ -63,6 +70,12 @@
- The path to read certificates and private keys from.
- Must be in PEM format.
type: path
certificate_content:
description:
- Content of the certificate file.
- Mutually exclusive with O(certificate_path).
type: str
version_added: "2.26.0"
force:
description:
- Should the file be regenerated even if it already exists.
Expand Down Expand Up @@ -363,7 +376,9 @@ def __init__(self, module, backend, iter_size_default=2048):
self.action = module.params['action']
self.other_certificates = module.params['other_certificates']
self.other_certificates_parse_all = module.params['other_certificates_parse_all']
self.other_certificates_content = module.params['other_certificates_content']
self.certificate_path = module.params['certificate_path']
self.certificate_content = module.params['certificate_content']
self.friendly_name = module.params['friendly_name']
self.iter_size = module.params['iter_size'] or iter_size_default
self.maciter_size = module.params['maciter_size'] or 1
Expand All @@ -383,6 +398,15 @@ def __init__(self, module, backend, iter_size_default=2048):
self.backup = module.params['backup']
self.backup_file = None

if self.certificate_path is not None:
try:
with open(self.certificate_path, 'rb') as fh:
self.certificate_content = fh.read()
except (IOError, OSError) as exc:
raise PkcsError(exc)
elif self.certificate_content is not None:
self.certificate_content = to_bytes(self.certificate_content)

if self.privatekey_path is not None:
try:
with open(self.privatekey_path, 'rb') as fh:
Expand All @@ -402,6 +426,8 @@ def __init__(self, module, backend, iter_size_default=2048):
self.other_certificates = [
load_certificate(other_cert, backend=self.backend) for other_cert in self.other_certificates
]
elif self.other_certificates_content:
self.other_certificates = self.other_certificates_content

@abc.abstractmethod
def generate_bytes(self, module):
Expand Down Expand Up @@ -458,11 +484,11 @@ def _check_pkey_passphrase():
elif bool(pkcs12_privatekey) != bool(self.privatekey_content):
return False

if (pkcs12_certificate is not None) and (self.certificate_path is not None):
if (pkcs12_certificate is not None) and (self.certificate_content is not None):
expected_cert = self._dump_certificate(self.pkcs12)
if pkcs12_certificate != expected_cert:
return False
elif bool(pkcs12_certificate) != bool(self.certificate_path):
elif bool(pkcs12_certificate) != bool(self.certificate_content):
return False

if (pkcs12_other_certificates is not None) and (self.other_certificates is not None):
Expand Down Expand Up @@ -554,8 +580,8 @@ def generate_bytes(self, module):
if self.other_certificates:
self.pkcs12.set_ca_certificates(self.other_certificates)

if self.certificate_path:
self.pkcs12.set_certificate(load_certificate(self.certificate_path, backend=self.backend))
if self.certificate_content:
self.pkcs12.set_certificate(load_certificate(None, content=self.certificate_content, backend=self.backend))

if self.friendly_name:
self.pkcs12.set_friendlyname(to_bytes(self.friendly_name))
Expand Down Expand Up @@ -628,8 +654,8 @@ def generate_bytes(self, module):
raise PkcsError(exc)

cert = None
if self.certificate_path:
cert = load_certificate(self.certificate_path, backend=self.backend)
if self.certificate_content:
cert = load_certificate(None, content=self.certificate_content, backend=self.backend)

friendly_name = to_bytes(self.friendly_name) if self.friendly_name is not None else None

Expand Down Expand Up @@ -759,7 +785,9 @@ def main():
action=dict(type='str', default='export', choices=['export', 'parse']),
other_certificates=dict(type='list', elements='path', aliases=['ca_certificates']),
other_certificates_parse_all=dict(type='bool', default=False),
other_certificates_content=dict(type='list', elements='str'),
certificate_path=dict(type='path'),
certificate_content=dict(type='str'),
force=dict(type='bool', default=False),
friendly_name=dict(type='str', aliases=['name']),
encryption_level=dict(type='str', choices=['auto', 'compatibility2022'], default='auto'),
Expand All @@ -783,6 +811,8 @@ def main():

mutually_exclusive = [
['privatekey_path', 'privatekey_content'],
['certificate_path', 'certificate_content'],
['other_certificates', 'other_certificates_content'],
]

module = AnsibleModule(
Expand Down
34 changes: 34 additions & 0 deletions tests/integration/targets/openssl_pkcs12/tasks/impl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@
return_content: true
register: p12_standard_idempotency

- name: "({{ select_crypto_backend }}) Generate PKCS#12 file again from content, idempotency"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ remote_tmp_dir }}/ansible.p12'
friendly_name: abracadabra
privatekey_content: '{{ lookup("ansible.builtin.file", remote_tmp_dir ~ "/ansible_pkey1.pem") }}'
certificate_content: '{{ lookup("ansible.builtin.file", remote_tmp_dir ~ "/ansible1.crt") }}'
state: present
return_content: true
register: p12_standard_idempotency_content

- name: "({{ select_crypto_backend }}) Generate PKCS#12 file again, idempotency (empty other_certificates)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
Expand Down Expand Up @@ -88,6 +99,7 @@
that:
- p12_standard.pkcs12 == ansible_p12_content.content
- p12_standard_idempotency.pkcs12 == p12_standard.pkcs12
- p12_standard_idempotency_content.pkcs12 == p12_standard.pkcs12

- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (force)"
openssl_pkcs12:
Expand Down Expand Up @@ -168,6 +180,20 @@
state: present
register: p12_multiple_certs_idempotency

- name: "({{ select_crypto_backend }}) Generate PKCS#12 file with multiple certs from content and passphrase, again (idempotency)"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
path: '{{ remote_tmp_dir }}/ansible_multi_certs.p12'
friendly_name: abracadabra
passphrase: hunter3
privatekey_path: '{{ remote_tmp_dir }}/ansible_pkey1.pem'
certificate_path: '{{ remote_tmp_dir }}/ansible1.crt'
other_certificates_content:
- '{{ lookup("ansible.builtin.file", remote_tmp_dir ~ "/ansible2.crt") }}'
- '{{ lookup("ansible.builtin.file", remote_tmp_dir ~ "/ansible3.crt") }}'
state: present
register: p12_multiple_certs_idempotency_content

- name: "({{ select_crypto_backend }}) Dump PKCS#12 with multiple certs and passphrase"
openssl_pkcs12:
select_crypto_backend: '{{ select_crypto_backend }}'
Expand All @@ -176,6 +202,14 @@
passphrase: hunter3
action: parse
state: present
register: p12_multiple_certs

- name: "({{ select_crypto_backend }}) Validate PKCS#12"
assert:
that:
- p12_multiple_certs.pkcs12 == ansible_p12_content.content
- p12_multiple_certs_idempotency.pkcs12 == p12_multiple_certs.pkcs12
- p12_multiple_certs_idempotency_content.pkcs12 == p12_multiple_certs.pkcs12

- name: "({{ select_crypto_backend }}) Generate PKCS#12 file (password fail 1)"
openssl_pkcs12:
Expand Down

0 comments on commit dd6c144

Please sign in to comment.