crypto: Fix known issues in modules (#52302)

* crypto: Fix known issues in modules

This fixes a few issues reported by 'validate-modules'.

* Fix whitespace
This commit is contained in:
Dag Wieers 2019-02-15 11:46:44 +01:00 committed by GitHub
parent 9c1033422b
commit cedd9d9926
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 590 additions and 522 deletions

View file

@ -1,8 +1,8 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016-2017, Yanis Guenane <yanis+ansible@guenane.org>
# (c) 2017, Markus Teufelberger <mteufelberger+ansible@mgit.at>
# Copyright: (c) 2016-2017, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright: (c) 2017, Markus Teufelberger <mteufelberger+ansible@mgit.at>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
@ -14,268 +14,322 @@ ANSIBLE_METADATA = {'metadata_version': '1.1',
'supported_by': 'community'}
DOCUMENTATION = '''
DOCUMENTATION = r'''
---
module: openssl_certificate
author:
- Yanis Guenane (@Spredzy)
- Markus Teufelberger (@MarkusTeufelberger)
version_added: "2.4"
short_description: Generate and/or check OpenSSL certificates
description:
- "This module allows one to (re)generate OpenSSL certificates. It implements a notion
of provider (ie. C(selfsigned), C(ownca), C(acme), C(assertonly)) for your certificate.
The 'assertonly' provider is intended for use cases where one is only interested in
checking properties of a supplied certificate.
The 'ownca' provider is intended for generate OpenSSL certificate signed with your own
CA (Certificate Authority) certificate (self-signed certificate).
Many properties that can be specified in this module are for validation of an
existing or newly generated certificate. The proper place to specify them, if you
want to receive a certificate with these properties is a CSR (Certificate Signing Request).
It uses the pyOpenSSL python library to interact with OpenSSL."
- This module allows one to (re)generate OpenSSL certificates.
- It implements a notion of provider (ie. C(selfsigned), C(ownca), C(acme), C(assertonly))
for your certificate.
- The C(assertonly) provider is intended for use cases where one is only interested in
checking properties of a supplied certificate.
- The C(ownca) provider is intended for generate OpenSSL certificate signed with your own
CA (Certificate Authority) certificate (self-signed certificate).
- Many properties that can be specified in this module are for validation of an
existing or newly generated certificate. The proper place to specify them, if you
want to receive a certificate with these properties is a CSR (Certificate Signing Request).
- It uses the pyOpenSSL python library to interact with OpenSSL.
requirements:
- python-pyOpenSSL >= 0.15 (if using C(selfsigned) or C(assertonly) provider)
- acme-tiny (if using the C(acme) provider)
author:
- Yanis Guenane (@Spredzy)
- Markus Teufelberger (@MarkusTeufelberger)
options:
state:
default: "present"
choices: [ present, absent ]
description:
- Whether the certificate should exist or not, taking action if the state is different from what is stated.
type: str
choices: [ absent, present ]
default: present
path:
required: true
description:
- Remote absolute path where the generated certificate file should be created or is already located.
type: path
required: true
provider:
required: true
choices: [ 'selfsigned', 'ownca', 'assertonly', 'acme' ]
description:
- Name of the provider to use to generate/retrieve the OpenSSL certificate.
The C(assertonly) provider will not generate files and fail if the certificate file is missing.
- The C(assertonly) provider will not generate files and fail if the certificate file is missing.
required: true
type: str
choices: [ acme, assertonly, ownca, selfsigned ]
force:
default: False
type: bool
description:
- Generate the certificate, even if it already exists.
type: bool
default: no
csr_path:
description:
- Path to the Certificate Signing Request (CSR) used to generate this certificate. This is not required in C(assertonly) mode.
- Path to the Certificate Signing Request (CSR) used to generate this certificate.
- This is not required in C(assertonly) mode.
type: path
privatekey_path:
description:
- Path to the private key to use when signing the certificate.
type: path
privatekey_passphrase:
description:
- The passphrase for the I(privatekey_path).
type: str
selfsigned_version:
default: 3
description:
- Version of the C(selfsigned) certificate. Nowadays it should almost always be C(3).
- Version of the C(selfsigned) certificate.
- Nowadays it should almost always be C(3).
type: int
default: 3
version_added: "2.5"
selfsigned_digest:
default: "sha256"
description:
- Digest algorithm to be used when self-signing the certificate
- Digest algorithm to be used when self-signing the certificate.
type: str
default: sha256
selfsigned_not_before:
default: +0s
description:
- "The point in time the certificate is valid from. Time can be specified either as relative time or as absolute timestamp.
Time will always be interpreted as UTC. Valid formats are: C([+-]timespec | ASN.1 TIME)
where timespec can be an integer + C([w | d | h | m | s]) (e.g. C(+32w1d2h).
Note that if using relative time this module is NOT idempotent.
If this value is not specified, the certificate will start being valid from now."
- The point in time the certificate is valid from.
- Time can be specified either as relative time or as absolute timestamp.
- Time will always be interpreted as UTC.
- Valid format is C([+-]timespec | ASN.1 TIME) where timespec can be an integer
+ C([w | d | h | m | s]) (e.g. C(+32w1d2h).
- Note that if using relative time this module is NOT idempotent.
- If this value is not specified, the certificate will start being valid from now.
type: str
default: +0s
aliases: [ selfsigned_notBefore ]
selfsigned_not_after:
default: +3650d
description:
- "The point in time at which the certificate stops being valid. Time can be specified either as relative time or as absolute timestamp.
Time will always be interpreted as UTC. Valid formats are: C([+-]timespec | ASN.1 TIME)
where timespec can be an integer + C([w | d | h | m | s]) (e.g. C(+32w1d2h).
Note that if using relative time this module is NOT idempotent.
If this value is not specified, the certificate will stop being valid 10 years from now."
- The point in time at which the certificate stops being valid.
- Time can be specified either as relative time or as absolute timestamp.
- Time will always be interpreted as UTC.
- Valid format is C([+-]timespec | ASN.1 TIME) where timespec can be an integer
+ C([w | d | h | m | s]) (e.g. C(+32w1d2h).
- Note that if using relative time this module is NOT idempotent.
- If this value is not specified, the certificate will stop being valid 10 years from now.
type: str
default: +3650d
aliases: [ selfsigned_notAfter ]
ownca_path:
description:
- Remote absolute path of the CA (Certificate Authority) certificate.
type: path
version_added: "2.7"
ownca_privatekey_path:
description:
- Path to the CA (Certificate Authority) private key to use when signing the certificate.
type: path
version_added: "2.7"
ownca_privatekey_passphrase:
description:
- The passphrase for the I(ownca_privatekey_path).
type: str
version_added: "2.7"
ownca_digest:
default: "sha256"
description:
- Digest algorithm to be used for the C(ownca) certificate.
- The digest algorithm to be used for the C(ownca) certificate.
type: str
default: sha256
version_added: "2.7"
ownca_version:
default: 3
description:
- Version of the C(ownca) certificate. Nowadays it should almost always be C(3).
- The version of the C(ownca) certificate.
- Nowadays it should almost always be C(3).
type: int
default: 3
version_added: "2.7"
ownca_not_before:
default: +0s
description:
- "The point in time the certificate is valid from. Time can be specified either as relative time or as absolute timestamp.
Time will always be interpreted as UTC. Valid formats are: C([+-]timespec | ASN.1 TIME)
where timespec can be an integer + C([w | d | h | m | s]) (e.g. C(+32w1d2h).
Note that if using relative time this module is NOT idempotent.
If this value is not specified, the certificate will start being valid from now."
- The point in time the certificate is valid from.
- Time can be specified either as relative time or as absolute timestamp.
- Time will always be interpreted as UTC.
- Valid format is C([+-]timespec | ASN.1 TIME) where timespec can be an integer
+ C([w | d | h | m | s]) (e.g. C(+32w1d2h).
- Note that if using relative time this module is NOT idempotent.
- If this value is not specified, the certificate will start being valid from now.
type: str
default: +0s
version_added: "2.7"
ownca_not_after:
default: +3650d
description:
- "The point in time at which the certificate stops being valid. Time can be specified either as relative time or as absolute timestamp.
Time will always be interpreted as UTC. Valid formats are: C([+-]timespec | ASN.1 TIME)
where timespec can be an integer + C([w | d | h | m | s]) (e.g. C(+32w1d2h).
Note that if using relative time this module is NOT idempotent.
If this value is not specified, the certificate will stop being valid 10 years from now."
- The point in time at which the certificate stops being valid.
- Time can be specified either as relative time or as absolute timestamp.
- Time will always be interpreted as UTC.
- Valid format is C([+-]timespec | ASN.1 TIME) where timespec can be an integer
+ C([w | d | h | m | s]) (e.g. C(+32w1d2h).
- Note that if using relative time this module is NOT idempotent.
- If this value is not specified, the certificate will stop being valid 10 years from now.
type: str
default: +3650d
version_added: "2.7"
acme_accountkey_path:
description:
- Path to the accountkey for the C(acme) provider
- The path to the accountkey for the C(acme) provider.
type: path
acme_challenge_path:
description:
- Path to the ACME challenge directory that is served on U(http://<HOST>:80/.well-known/acme-challenge/)
- The path to the ACME challenge directory that is served on U(http://<HOST>:80/.well-known/acme-challenge/)
type: path
acme_chain:
default: True
description:
- Include the intermediate certificate to the generated certificate
type: bool
default: yes
version_added: "2.5"
signature_algorithms:
description:
- list of algorithms that you would accept the certificate to be signed with
- A list of algorithms that you would accept the certificate to be signed with
(e.g. ['sha256WithRSAEncryption', 'sha512WithRSAEncryption']).
type: str
issuer:
description:
- Key/value pairs that must be present in the issuer name field of the certificate.
If you need to specify more than one value with the same key, use a list as value.
- The key/value pairs that must be present in the issuer name field of the certificate.
- If you need to specify more than one value with the same key, use a list as value.
type: str
issuer_strict:
default: False
type: bool
description:
- If set to True, the I(issuer) field must contain only these values.
- If set to C(yes), the I(issuer) field must contain only these values.
type: bool
default: no
version_added: "2.5"
subject:
description:
- Key/value pairs that must be present in the subject name field of the certificate.
If you need to specify more than one value with the same key, use a list as value.
- The key/value pairs that must be present in the subject name field of the certificate.
- If you need to specify more than one value with the same key, use a list as value.
type: str
subject_strict:
default: False
type: bool
description:
- If set to True, the I(subject) field must contain only these values.
- If set to C(yes), the I(subject) field must contain only these values.
type: bool
default: no
version_added: "2.5"
has_expired:
default: False
type: bool
description:
- Checks if the certificate is expired/not expired at the time the module is executed.
type: bool
default: no
version:
description:
- Version of the certificate. Nowadays it should almost always be 3.
- The version of the certificate.
- Nowadays it should almost always be 3.
type: int
valid_at:
description:
- The certificate must be valid at this point in time. The timestamp is formatted as an ASN.1 TIME.
- The certificate must be valid at this point in time.
- The timestamp is formatted as an ASN.1 TIME.
type: str
invalid_at:
description:
- The certificate must be invalid at this point in time. The timestamp is formatted as an ASN.1 TIME.
- The certificate must be invalid at this point in time.
- The timestamp is formatted as an ASN.1 TIME.
type: str
not_before:
description:
- The certificate must start to become valid at this point in time. The timestamp is formatted as an ASN.1 TIME.
- The certificate must start to become valid at this point in time.
- The timestamp is formatted as an ASN.1 TIME.
type: str
aliases: [ notBefore ]
not_after:
description:
- The certificate must expire at this point in time. The timestamp is formatted as an ASN.1 TIME.
- The certificate must expire at this point in time.
- The timestamp is formatted as an ASN.1 TIME.
type: str
aliases: [ notAfter ]
valid_in:
description:
- "The certificate must still be valid at this relative time offset from now.
Valid formats are: C([+-]timespec | number_of_seconds)
where timespec can be an integer + C([w | d | h | m | s]) (e.g. C(+32w1d2h).
Note that if using this parameter, this module is NOT idempotent."
- The certificate must still be valid at this relative time offset from now.
- Valid format is C([+-]timespec | number_of_seconds) where timespec can be an integer
+ C([w | d | h | m | s]) (e.g. C(+32w1d2h).
- Note that if using this parameter, this module is NOT idempotent.
type: str
key_usage:
description:
- The I(key_usage) extension field must contain all these values.
type: list
aliases: [ keyUsage ]
key_usage_strict:
default: False
type: bool
description:
- If set to True, the I(key_usage) extension field must contain only these values.
- If set to C(yes), the I(key_usage) extension field must contain only these values.
type: bool
default: no
aliases: [ keyUsage_strict ]
extended_key_usage:
description:
- The I(extended_key_usage) extension field must contain all these values.
type: list
aliases: [ extendedKeyUsage ]
extended_key_usage_strict:
default: False
type: bool
description:
- If set to True, the I(extended_key_usage) extension field must contain only these values.
- If set to C(yes), the I(extended_key_usage) extension field must contain only these values.
type: bool
default: no
aliases: [ extendedKeyUsage_strict ]
subject_alt_name:
description:
- The I(subject_alt_name) extension field must contain these values.
type: list
aliases: [ subjectAltName ]
subject_alt_name_strict:
default: False
type: bool
description:
- If set to True, the I(subject_alt_name) extension field must contain only these values.
- If set to C(yes), the I(subject_alt_name) extension field must contain only these values.
type: bool
default: no
aliases: [ subjectAltName_strict ]
extends_documentation_fragment: files
notes:
- All ASN.1 TIME values should be specified following the YYYYMMDDHHMMSSZ pattern.
Date specified should be UTC. Minutes and seconds are mandatory.
- Date specified should be UTC. Minutes and seconds are mandatory.
- For security reason, when you use C(ownca) provider, you should NOT run M(openssl_certificate) on
a target machine, but on a dedicated CA machine. It is recommended not to store the CA private key
on the target machine. Once signed, the certificate can be moved to the target machine.
seealso:
- module: openssl_csr
- module: openssl_dhparam
- module: openssl_pkcs12
- module: openssl_privatekey
- module: openssl_publickey
'''
EXAMPLES = '''
EXAMPLES = r'''
- name: Generate a Self Signed OpenSSL certificate
openssl_certificate:
path: /etc/ssl/crt/ansible.com.crt
@ -306,7 +360,7 @@ EXAMPLES = '''
provider: acme
acme_accountkey_path: /etc/ssl/private/ansible.com.pem
acme_challenge_path: /etc/ssl/challenges/ansible.com/
force: True
force: yes
# Examples for some checks one could use the assertonly provider for:
@ -315,8 +369,8 @@ EXAMPLES = '''
openssl_certificate:
path: /etc/ssl/crt/example.com.crt
provider: assertonly
has_expired: False
ignore_errors: True
has_expired: no
ignore_errors: yes
register: validity_check
- name: Run custom task(s) to get a new, valid certificate in case the initial check failed
@ -327,7 +381,7 @@ EXAMPLES = '''
openssl_certificate:
path: /etc/ssl/crt/example.com.crt
provider: assertonly
has_expired: False
has_expired: no
when: validity_check.failed
# Some other checks that assertonly could be used for:
@ -337,7 +391,7 @@ EXAMPLES = '''
provider: assertonly
issuer:
O: Let's Encrypt
has_expired: False
has_expired: no
- name: Ensure that a certificate uses a modern signature algorithm (no SHA1, MD5 or DSA)
openssl_certificate:
@ -405,8 +459,7 @@ EXAMPLES = '''
- test.example.com
'''
RETURN = '''
RETURN = r'''
filename:
description: Path to the generated Certificate
returned: changed or success
@ -710,14 +763,14 @@ class AssertOnlyCertificate(Certificate):
self.issuer_strict = module.params['issuer_strict']
self.has_expired = module.params['has_expired']
self.version = module.params['version']
self.keyUsage = module.params['keyUsage']
self.keyUsage_strict = module.params['keyUsage_strict']
self.extendedKeyUsage = module.params['extendedKeyUsage']
self.extendedKeyUsage_strict = module.params['extendedKeyUsage_strict']
self.subjectAltName = module.params['subjectAltName']
self.subjectAltName_strict = module.params['subjectAltName_strict']
self.notBefore = module.params['notBefore']
self.notAfter = module.params['notAfter']
self.keyUsage = module.params['key_usage']
self.keyUsage_strict = module.params['key_usage_strict']
self.extendedKeyUsage = module.params['extended_key_usage']
self.extendedKeyUsage_strict = module.params['extended_key_usage_strict']
self.subjectAltName = module.params['subject_alt_name']
self.subjectAltName_strict = module.params['subject_alt_name_strict']
self.notBefore = module.params['not_before']
self.notAfter = module.params['not_after']
self.valid_at = module.params['valid_at']
self.invalid_at = module.params['invalid_at']
self.valid_in = module.params['valid_in']
@ -1002,7 +1055,7 @@ def main():
argument_spec=dict(
state=dict(type='str', choices=['present', 'absent'], default='present'),
path=dict(type='path', required=True),
provider=dict(type='str', choices=['selfsigned', 'ownca', 'assertonly', 'acme']),
provider=dict(type='str', choices=['acme', 'assertonly', 'ownca', 'selfsigned']),
force=dict(type='bool', default=False,),
csr_path=dict(type='path'),
@ -1016,20 +1069,20 @@ def main():
issuer_strict=dict(type='bool', default=False),
has_expired=dict(type='bool', default=False),
version=dict(type='int'),
keyUsage=dict(type='list', aliases=['key_usage'], elements='str'),
keyUsage_strict=dict(type='bool', default=False, aliases=['key_usage_strict']),
extendedKeyUsage=dict(type='list', aliases=['extended_key_usage'], elements='str'),
extendedKeyUsage_strict=dict(type='bool', default=False, aliases=['extended_key_usage_strict']),
subjectAltName=dict(type='list', aliases=['subject_alt_name'], elements='str'),
subjectAltName_strict=dict(type='bool', default=False, aliases=['subject_alt_name_strict']),
notBefore=dict(type='str', aliases=['not_before']),
notAfter=dict(type='str', aliases=['not_after']),
key_usage=dict(type='list', elements='str', aliases=['keyUsage']),
key_usage_strict=dict(type='bool', default=False, aliases=['keyUsage_strict']),
extended_key_usage=dict(type='list', elements='str', aliases=['extendedKeyUsage']),
extended_key_usage_strict=dict(type='bool', default=False, aliases=['extendedKeyUsage_strict']),
subject_alt_name=dict(type='list', elements='str', aliases=['subjectAltName']),
subject_alt_name_strict=dict(type='bool', default=False, aliases=['subjectAltName_strict']),
not_before=dict(type='str', aliases=['notBefore']),
not_after=dict(type='str', aliases=['notAfter']),
valid_at=dict(type='str'),
invalid_at=dict(type='str'),
valid_in=dict(type='str'),
# provider: selfsigned
selfsigned_version=dict(type='int', default='3'),
selfsigned_version=dict(type='int', default=3),
selfsigned_digest=dict(type='str', default='sha256'),
selfsigned_not_before=dict(
type='str', default='+0s', aliases=['selfsigned_notBefore']),
@ -1041,7 +1094,7 @@ def main():
ownca_privatekey_path=dict(type='path'),
ownca_privatekey_passphrase=dict(type='path', no_log=True),
ownca_digest=dict(type='str', default='sha256'),
ownca_version=dict(type='int', default='3'),
ownca_version=dict(type='int', default=3),
ownca_not_before=dict(type='str', default='+0s'),
ownca_not_after=dict(type='str', default='+3650d'),

View file

@ -1,228 +1,225 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2017, Yanis Guenane <yanis+ansible@guenane.org>
# Copyrigt: (c) 2017, Yanis Guenane <yanis+ansible@guenane.org>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
DOCUMENTATION = r'''
---
module: openssl_csr
author: "Yanis Guenane (@Spredzy)"
version_added: "2.4"
version_added: '2.4'
short_description: Generate OpenSSL Certificate Signing Request (CSR)
description:
- "This module allows one to (re)generate OpenSSL certificate signing requests.
It uses the pyOpenSSL python library to interact with openssl. This module supports
the subjectAltName, keyUsage, extendedKeyUsage, basicConstraints and OCSP Must Staple
extensions."
- This module allows one to (re)generate OpenSSL certificate signing requests.
- It uses the pyOpenSSL python library to interact with openssl. This module supports
the subjectAltName, keyUsage, extendedKeyUsage, basicConstraints and OCSP Must Staple
extensions.
requirements:
- "One of the following Python libraries:"
- "cryptography >= 1.3"
- "pyOpenSSL >= 0.15"
- Either cryptography >= 1.3
- Or pyOpenSSL >= 0.15
author:
- Yanis Guenane (@Spredzy)
options:
state:
required: false
default: "present"
choices: [ present, absent ]
description:
- Whether the certificate signing request should exist or not, taking action if the state is different from what is stated.
type: str
required: false
choices: [ absent, present ]
default: present
digest:
required: false
default: "sha256"
description:
- Digest used when signing the certificate signing request with the private key
- The digest used when signing the certificate signing request with the private key.
type: str
default: sha256
privatekey_path:
required: true
description:
- Path to the privatekey to use when signing the certificate signing request
- The path to the privatekey to use when signing the certificate signing request.
type: path
required: true
privatekey_passphrase:
required: false
description:
- The passphrase for the privatekey.
type: str
version:
required: false
description:
- The version of the certificate signing request.
type: int
default: 1
description:
- Version of the certificate signing request
force:
required: false
default: False
description:
- Should the certificate signing request be forced regenerated by this ansible module.
type: bool
description:
- Should the certificate signing request be forced regenerated by this ansible module
default: no
path:
required: true
description:
- Name of the file into which the generated OpenSSL certificate signing request will be written
- The name of the file into which the generated OpenSSL certificate signing request will be written.
type: path
required: true
subject:
required: false
description:
- Key/value pairs that will be present in the subject name field of the certificate signing request.
- If you need to specify more than one value with the same key, use a list as value.
type: str
version_added: '2.5'
country_name:
required: false
aliases: [ 'C', 'countryName' ]
description:
- countryName field of the certificate signing request subject
- The countryName field of the certificate signing request subject.
type: str
aliases: [ C, countryName ]
state_or_province_name:
required: false
aliases: [ 'ST', 'stateOrProvinceName' ]
description:
- stateOrProvinceName field of the certificate signing request subject
- The stateOrProvinceName field of the certificate signing request subject.
type: str
aliases: [ ST, stateOrProvinceName ]
locality_name:
required: false
aliases: [ 'L', 'localityName' ]
description:
- localityName field of the certificate signing request subject
- The localityName field of the certificate signing request subject.
type: str
aliases: [ L, localityName ]
organization_name:
required: false
aliases: [ 'O', 'organizationName' ]
description:
- organizationName field of the certificate signing request subject
- The organizationName field of the certificate signing request subject.
type: str
aliases: [ O, organizationName ]
organizational_unit_name:
required: false
aliases: [ 'OU', 'organizationalUnitName' ]
description:
- organizationalUnitName field of the certificate signing request subject
- The organizationalUnitName field of the certificate signing request subject.
type: str
aliases: [ OU, organizationalUnitName ]
common_name:
required: false
aliases: [ 'CN', 'commonName' ]
description:
- commonName field of the certificate signing request subject
- The commonName field of the certificate signing request subject.
type: str
aliases: [ CN, commonName ]
email_address:
required: false
aliases: [ 'E', 'emailAddress' ]
description:
- emailAddress field of the certificate signing request subject
- The emailAddress field of the certificate signing request subject.
type: str
aliases: [ E, emailAddress ]
subject_alt_name:
required: false
aliases: [ 'subjectAltName' ]
description:
- SAN extension to attach to the certificate signing request
- SAN extension to attach to the certificate signing request.
- This can either be a 'comma separated string' or a YAML list.
- Values should be prefixed by their options. (i.e., C(email), C(URI), C(DNS), C(RID), C(IP), C(dirName),
C(otherName) and the ones specific to your CA)
- Note that if no SAN is specified, but a common name, the common
name will be added as a SAN except if C(useCommonNameForSAN) is
set to I(false).
- More at U(https://tools.ietf.org/html/rfc5280#section-4.2.1.6)
- More at U(https://tools.ietf.org/html/rfc5280#section-4.2.1.6).
type: list
aliases: [ subjectAltName ]
subject_alt_name_critical:
required: false
aliases: [ 'subjectAltName_critical' ]
description:
- Should the subjectAltName extension be considered as critical
useCommonNameForSAN:
- Should the subjectAltName extension be considered as critical.
type: bool
default: true
aliases: [ subjectAltName_critical ]
use_common_name_for_san:
description:
- If set to I(true), the module will fill the common name in for
- If set to C(yes), the module will fill the common name in for
C(subject_alt_name) with C(DNS:) prefix if no SAN is specified.
type: bool
default: yes
aliases: [ useCommonNameForSAN ]
version_added: '2.8'
key_usage:
required: false
aliases: [ 'keyUsage' ]
description:
- This defines the purpose (e.g. encipherment, signature, certificate signing)
of the key contained in the certificate.
- This can either be a 'comma separated string' or a YAML list.
type: list
aliases: [ keyUsage ]
key_usage_critical:
required: false
aliases: [ 'keyUsage_critical' ]
description:
- Should the keyUsage extension be considered as critical
- Should the keyUsage extension be considered as critical.
type: bool
aliases: [ keyUsage_critical ]
extended_key_usage:
required: false
aliases: [ 'extKeyUsage', 'extendedKeyUsage' ]
description:
- Additional restrictions (e.g. client authentication, server authentication)
on the allowed purposes for which the public key may be used.
- This can either be a 'comma separated string' or a YAML list.
type: list
aliases: [ extKeyUsage, extendedKeyUsage ]
extended_key_usage_critical:
required: false
aliases: [ 'extKeyUsage_critical', 'extendedKeyUsage_critical' ]
description:
- Should the extkeyUsage extension be considered as critical
- Should the extkeyUsage extension be considered as critical.
type: bool
aliases: [ extKeyUsage_critical, extendedKeyUsage_critical ]
basic_constraints:
required: false
aliases: ['basicConstraints']
description:
- Indicates basic constraints, such as if the certificate is a CA.
version_added: 2.5
type: list
aliases: [ basicConstraints ]
version_added: '2.5'
basic_constraints_critical:
required: false
aliases: [ 'basicConstraints_critical' ]
description:
- Should the basicConstraints extension be considered as critical
version_added: 2.5
- Should the basicConstraints extension be considered as critical.
type: bool
aliases: [ basicConstraints_critical ]
version_added: '2.5'
ocsp_must_staple:
required: false
aliases: ['ocspMustStaple']
description:
- Indicates that the certificate should contain the OCSP Must Staple
extension (U(https://tools.ietf.org/html/rfc7633)).
version_added: 2.5
type: bool
aliases: [ ocspMustStaple ]
version_added: '2.5'
ocsp_must_staple_critical:
required: false
aliases: [ 'ocspMustStaple_critical' ]
description:
- Should the OCSP Must Staple extension be considered as critical
- "Warning: according to the RFC, this extension should not be marked
as critical, as old clients not knowing about OCSP Must Staple
are required to reject such certificates
(see U(https://tools.ietf.org/html/rfc7633#section-4))."
version_added: 2.5
- Note that according to the RFC, this extension should not be marked
as critical, as old clients not knowing about OCSP Must Staple
are required to reject such certificates
(see U(https://tools.ietf.org/html/rfc7633#section-4)).
type: bool
aliases: [ ocspMustStaple_critical ]
version_added: '2.5'
select_crypto_backend:
description:
- "Determines which crypto backend to use. The default choice is C(auto),
which tries to use C(cryptography) if available, and falls back to
C(pyopenssl)."
- "If set to C(pyopenssl), will try to use the L(pyOpenSSL,https://pypi.org/project/pyOpenSSL/)
library."
- "If set to C(cryptography), will try to use the
L(cryptography,https://cryptography.io/) library."
- Determines which crypto backend to use.
- The default choice is C(auto), which tries to use C(cryptography) if available, and falls back to C(pyopenssl).
- If set to C(pyopenssl), will try to use the L(pyOpenSSL,https://pypi.org/project/pyOpenSSL/) library.
- If set to C(cryptography), will try to use the L(cryptography,https://cryptography.io/) library.
type: str
default: 'auto'
choices:
- auto
- cryptography
- pyopenssl
version_added: "2.8"
extends_documentation_fragment: files
choices: [ auto, cryptography, pyopenssl ]
default: auto
version_added: '2.8'
extends_documentation_fragment:
- files
notes:
- "If the certificate signing request already exists it will be checked whether subjectAltName,
keyUsage, extendedKeyUsage and basicConstraints only contain the requested values, whether
OCSP Must Staple is as requested, and if the request was signed by the given private key."
- If the certificate signing request already exists it will be checked whether subjectAltName,
keyUsage, extendedKeyUsage and basicConstraints only contain the requested values, whether
OCSP Must Staple is as requested, and if the request was signed by the given private key.
seealso:
- module: openssl_certificate
- module: openssl_dhparam
- module: openssl_pkcs12
- module: openssl_privatekey
- module: openssl_publickey
'''
EXAMPLES = '''
# Generate an OpenSSL Certificate Signing Request
- openssl_csr:
EXAMPLES = r'''
- name: Generate an OpenSSL Certificate Signing Request
openssl_csr:
path: /etc/ssl/csr/www.ansible.com.csr
privatekey_path: /etc/ssl/private/ansible.com.pem
common_name: www.ansible.com
# Generate an OpenSSL Certificate Signing Request with a
# passphrase protected private key
- openssl_csr:
- name: Generate an OpenSSL Certificate Signing Request with a passphrase protected private key
openssl_csr:
path: /etc/ssl/csr/www.ansible.com.csr
privatekey_path: /etc/ssl/private/ansible.com.pem
privatekey_passphrase: ansible
common_name: www.ansible.com
# Generate an OpenSSL Certificate Signing Request with Subject information
- openssl_csr:
- name: Generate an OpenSSL Certificate Signing Request with Subject information
openssl_csr:
path: /etc/ssl/csr/www.ansible.com.csr
privatekey_path: /etc/ssl/private/ansible.com.pem
country_name: FR
@ -230,14 +227,14 @@ EXAMPLES = '''
email_address: jdoe@ansible.com
common_name: www.ansible.com
# Generate an OpenSSL Certificate Signing Request with subjectAltName extension
- openssl_csr:
- name: Generate an OpenSSL Certificate Signing Request with subjectAltName extension
openssl_csr:
path: /etc/ssl/csr/www.ansible.com.csr
privatekey_path: /etc/ssl/private/ansible.com.pem
subject_alt_name: 'DNS:www.ansible.com,DNS:m.ansible.com'
# Generate an OpenSSL CSR with subjectAltName extension with dynamic list
- openssl_csr:
- name: Generate an OpenSSL CSR with subjectAltName extension with dynamic list
openssl_csr:
path: /etc/ssl/csr/www.ansible.com.csr
privatekey_path: /etc/ssl/private/ansible.com.pem
subject_alt_name: "{{ item.value | map('regex_replace', '^', 'DNS:') | list }}"
@ -246,15 +243,15 @@ EXAMPLES = '''
- www.ansible.com
- m.ansible.com
# Force re-generate an OpenSSL Certificate Signing Request
- openssl_csr:
- name: Force re-generate an OpenSSL Certificate Signing Request
openssl_csr:
path: /etc/ssl/csr/www.ansible.com.csr
privatekey_path: /etc/ssl/private/ansible.com.pem
force: True
force: yes
common_name: www.ansible.com
# Generate an OpenSSL Certificate Signing Request with special key usages
- openssl_csr:
- name: Generate an OpenSSL Certificate Signing Request with special key usages
openssl_csr:
path: /etc/ssl/csr/www.ansible.com.csr
privatekey_path: /etc/ssl/private/ansible.com.pem
common_name: www.ansible.com
@ -264,16 +261,15 @@ EXAMPLES = '''
extended_key_usage:
- clientAuth
# Generate an OpenSSL Certificate Signing Request with OCSP Must Staple
- openssl_csr:
- name: Generate an OpenSSL Certificate Signing Request with OCSP Must Staple
openssl_csr:
path: /etc/ssl/csr/www.ansible.com.csr
privatekey_path: /etc/ssl/private/ansible.com.pem
common_name: www.ansible.com
ocsp_must_staple: true
ocsp_must_staple: yes
'''
RETURN = '''
RETURN = r'''
privatekey:
description: Path to the TLS/SSL private key the CSR was generated for
returned: changed or success
@ -384,34 +380,34 @@ class CertificateSigningRequestBase(crypto_utils.OpenSSLObject):
self.privatekey_path = module.params['privatekey_path']
self.privatekey_passphrase = module.params['privatekey_passphrase']
self.version = module.params['version']
self.subjectAltName = module.params['subjectAltName']
self.subjectAltName_critical = module.params['subjectAltName_critical']
self.keyUsage = module.params['keyUsage']
self.keyUsage_critical = module.params['keyUsage_critical']
self.extendedKeyUsage = module.params['extendedKeyUsage']
self.extendedKeyUsage_critical = module.params['extendedKeyUsage_critical']
self.basicConstraints = module.params['basicConstraints']
self.basicConstraints_critical = module.params['basicConstraints_critical']
self.ocspMustStaple = module.params['ocspMustStaple']
self.ocspMustStaple_critical = module.params['ocspMustStaple_critical']
self.subjectAltName = module.params['subject_alt_name']
self.subjectAltName_critical = module.params['subject_alt_name_critical']
self.keyUsage = module.params['key_usage']
self.keyUsage_critical = module.params['key_usage_critical']
self.extendedKeyUsage = module.params['extended_key_usage']
self.extendedKeyUsage_critical = module.params['extended_key_usage_critical']
self.basicConstraints = module.params['basic_constraints']
self.basicConstraints_critical = module.params['basic_constraints_critical']
self.ocspMustStaple = module.params['ocsp_must_staple']
self.ocspMustStaple_critical = module.params['ocsp_must_staple_critical']
self.request = None
self.privatekey = None
self.subject = [
('C', module.params['countryName']),
('ST', module.params['stateOrProvinceName']),
('L', module.params['localityName']),
('O', module.params['organizationName']),
('OU', module.params['organizationalUnitName']),
('CN', module.params['commonName']),
('emailAddress', module.params['emailAddress']),
('C', module.params['country_name']),
('ST', module.params['state_or_province_name']),
('L', module.params['locality_name']),
('O', module.params['organization_name']),
('OU', module.params['organizational_unit_name']),
('CN', module.params['common_name']),
('emailAddress', module.params['email_address']),
]
if module.params['subject']:
self.subject = self.subject + crypto_utils.parse_name_field(module.params['subject'])
self.subject = [(entry[0], entry[1]) for entry in self.subject if entry[1]]
if not self.subjectAltName and module.params['useCommonNameForSAN']:
if not self.subjectAltName and module.params['use_common_name_for_san']:
for sub in self.subject:
if sub[0] in ('commonName', 'CN'):
self.subjectAltName = ['DNS:%s' % sub[1]]
@ -944,33 +940,33 @@ class CertificateSigningRequestCryptography(CertificateSigningRequestBase):
def main():
module = AnsibleModule(
argument_spec=dict(
state=dict(default='present', choices=['present', 'absent'], type='str'),
digest=dict(default='sha256', type='str'),
privatekey_path=dict(require=True, type='path'),
state=dict(type='str', default='present', choices=['absent', 'present']),
digest=dict(type='str', default='sha256'),
privatekey_path=dict(type='path', require=True),
privatekey_passphrase=dict(type='str', no_log=True),
version=dict(default='1', type='int'),
force=dict(default=False, type='bool'),
path=dict(required=True, type='path'),
version=dict(type='int', default=1),
force=dict(type='bool', default=False),
path=dict(type='path', required=True),
subject=dict(type='dict'),
countryName=dict(aliases=['C', 'country_name'], type='str'),
stateOrProvinceName=dict(aliases=['ST', 'state_or_province_name'], type='str'),
localityName=dict(aliases=['L', 'locality_name'], type='str'),
organizationName=dict(aliases=['O', 'organization_name'], type='str'),
organizationalUnitName=dict(aliases=['OU', 'organizational_unit_name'], type='str'),
commonName=dict(aliases=['CN', 'common_name'], type='str'),
emailAddress=dict(aliases=['E', 'email_address'], type='str'),
subjectAltName=dict(aliases=['subject_alt_name'], type='list', elements='str'),
subjectAltName_critical=dict(aliases=['subject_alt_name_critical'], default=False, type='bool'),
useCommonNameForSAN=dict(type='bool', default=True),
keyUsage=dict(aliases=['key_usage'], type='list', elements='str'),
keyUsage_critical=dict(aliases=['key_usage_critical'], default=False, type='bool'),
extendedKeyUsage=dict(aliases=['extKeyUsage', 'extended_key_usage'], type='list', elements='str'),
extendedKeyUsage_critical=dict(aliases=['extKeyUsage_critical', 'extended_key_usage_critical'], default=False, type='bool'),
basicConstraints=dict(aliases=['basic_constraints'], type='list', elements='str'),
basicConstraints_critical=dict(aliases=['basic_constraints_critical'], default=False, type='bool'),
ocspMustStaple=dict(aliases=['ocsp_must_staple'], default=False, type='bool'),
ocspMustStaple_critical=dict(aliases=['ocsp_must_staple_critical'], default=False, type='bool'),
select_crypto_backend=dict(required=False, choices=['auto', 'pyopenssl', 'cryptography'], default='auto', type='str'),
country_name=dict(type='str', aliases=['C', 'countryName']),
state_or_province_name=dict(type='str', aliases=['ST', 'stateOrProvinceName']),
locality_name=dict(type='str', aliases=['L', 'localityName']),
organization_name=dict(type='str', aliases=['O', 'organizationName']),
organizational_unit_name=dict(type='str', aliases=['OU', 'organizationalUnitName']),
common_name=dict(type='str', aliases=['CN', 'commonName']),
email_address=dict(type='str', aliases=['E', 'emailAddress']),
subject_alt_name=dict(type='list', elements='str', aliases=['subjectAltName']),
subject_alt_name_critical=dict(type='bool', default=False, aliases=['subjectAltName_critical']),
use_common_name_for_san=dict(type='bool', default=True, aliases=['useCommonNameForSAN']),
key_usage=dict(type='list', elements='str', aliases=['keyUsage']),
key_usage_critical=dict(type='bool', default=False, aliases=['keyUsage_critical']),
extended_key_usage=dict(type='list', elements='str', aliases=['extKeyUsage', 'extendedKeyUsage']),
extended_key_usage_critical=dict(type='bool', default=False, aliases=['extKeyUsage_critical', 'extendedKeyUsage_critical']),
basic_constraints=dict(type='list', elements='str', aliases=['basicConstraints']),
basic_constraints_critical=dict(type='bool', default=False, aliases=['basicConstraints_critical']),
ocsp_must_staple=dict(type='bool', default=False, aliases=['ocspMustStaple']),
ocsp_must_staple_critical=dict(type='bool', default=False, aliases=['ocspMustStaple_critical']),
select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'cryptography', 'pyopenssl']),
),
add_file_common_args=True,
supports_check_mode=True,

View file

@ -1,80 +1,85 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2017, Thom Wiggers <ansible@thomwiggers.nl>
# Copyright: (c) 2017, Thom Wiggers <ansible@thomwiggers.nl>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
DOCUMENTATION = r'''
---
module: openssl_dhparam
author: "Thom Wiggers (@thomwiggers)"
version_added: "2.5"
short_description: Generate OpenSSL Diffie-Hellman Parameters
description:
- "This module allows one to (re)generate OpenSSL DH-params.
This module uses file common arguments to specify generated file permissions."
- This module allows one to (re)generate OpenSSL DH-params.
- This module uses file common arguments to specify generated file permissions.
requirements:
- OpenSSL
author:
- Thom Wiggers (@thomwiggers)
options:
state:
required: false
default: "present"
choices: [ present, absent ]
description:
- Whether the parameters should exist or not,
taking action if the state is different from what is stated.
type: str
choices: [ absent, present ]
default: present
size:
required: false
description:
- Size (in bits) of the generated DH-params.
type: int
default: 4096
description:
- Size (in bits) of the generated DH-params
force:
required: false
default: False
type: bool
description:
- Should the parameters be regenerated even it it already exists
- Should the parameters be regenerated even it it already exists.
type: bool
default: no
path:
required: true
description:
- Name of the file in which the generated parameters will be saved.
extends_documentation_fragment: files
type: path
required: true
extends_documentation_fragment:
- files
seealso:
- module: openssl_certificate
- module: openssl_csr
- module: openssl_pkcs12
- module: openssl_privatekey
- module: openssl_publickey
'''
EXAMPLES = '''
# Generate Diffie-Hellman parameters with the default size (4096 bits)
- openssl_dhparam:
EXAMPLES = r'''
- name: Generate Diffie-Hellman parameters with the default size (4096 bits)
openssl_dhparam:
path: /etc/ssl/dhparams.pem
# Generate DH Parameters with a different size (2048 bits)
- openssl_dhparam:
- name: Generate DH Parameters with a different size (2048 bits)
openssl_dhparam:
path: /etc/ssl/dhparams.pem
size: 2048
# Force regenerate an DH parameters if they already exist
- openssl_dhparam:
- name: Force regenerate an DH parameters if they already exist
openssl_dhparam:
path: /etc/ssl/dhparams.pem
force: True
force: yes
'''
RETURN = '''
RETURN = r'''
size:
description: Size (in bits) of the Diffie-Hellman parameters
description: Size (in bits) of the Diffie-Hellman parameters.
returned: changed or success
type: int
sample: 4096
filename:
description: Path to the generated Diffie-Hellman parameters
description: Path to the generated Diffie-Hellman parameters.
returned: changed or success
type: str
sample: /etc/ssl/dhparams.pem
@ -97,7 +102,7 @@ class DHParameter(object):
def __init__(self, module):
self.state = module.params['state']
self.path = module.params['path']
self.size = int(module.params['size'])
self.size = module.params['size']
self.force = module.params['force']
self.changed = False
self.openssl_bin = module.get_bin_path('openssl', True)
@ -150,8 +155,8 @@ class DHParameter(object):
match = re.search(r"Parameters:\s+\((\d+) bit\).*", result)
if not match:
return False # No "xxxx bit" in output
else:
bits = int(match.group(1))
bits = int(match.group(1))
# if output contains "WARNING" we've got a problem
if "WARNING" in result or "WARNING" in to_native(err):
@ -182,10 +187,10 @@ def main():
module = AnsibleModule(
argument_spec=dict(
state=dict(default='present', choices=['present', 'absent'], type='str'),
size=dict(default=4096, type='int'),
force=dict(default=False, type='bool'),
path=dict(required=True, type='path'),
state=dict(type='str', default='present', choices=['absent', 'present']),
size=dict(type='int', default=4096),
force=dict(type='bool', default=False),
path=dict(type='path', required=True),
),
supports_check_mode=True,
add_file_common_args=True,
@ -195,7 +200,7 @@ def main():
if not os.path.isdir(base_dir):
module.fail_json(
name=base_dir,
msg='The directory %s does not exist or the file is not a directory' % base_dir
msg="The directory '%s' does not exist or the file is not a directory" % base_dir
)
dhparam = DHParameter(module)

View file

@ -1,8 +1,8 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright: (c) 2017, Guillaume Delpierre <gde@llew.me>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# Copyright (c) 2017 Guillaume Delpierre <gde@llew.me>
from __future__ import absolute_import, division, print_function
__metaclass__ = type
@ -11,128 +11,145 @@ ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
DOCUMENTATION = r'''
---
module: openssl_pkcs12
author: "Guillaume Delpierre (@gdelpierre)"
author:
- Guillaume Delpierre (@gdelpierre)
version_added: "2.7"
short_description: Generate OpenSSL PKCS#12 archive.
short_description: Generate OpenSSL PKCS#12 archive
description:
- This module allows one to (re-)generate PKCS#12.
requirements:
- python-pyOpenSSL
options:
action:
default: export
choices: ['parse', 'export']
description:
- C(export) or C(parse) a PKCS#12.
choices: [ export, parse ]
default: export
ca_certificates:
description:
- List of CA certificate to include.
type: list
certificate_path:
description:
- The path to read certificates and private keys from. Must be in PEM format.
- The path to read certificates and private keys from.
- Must be in PEM format.
type: path
force:
default: False
type: bool
description:
- Should the file be regenerated even if it already exists.
type: bool
default: no
friendly_name:
aliases: ['name']
description:
- Specifies the friendly name for the certificate and private key.
type: str
aliases: [ name ]
iter_size:
default: 2048
description:
- Number of times to repeat the encryption step.
type: int
default: 2048
maciter_size:
default: 1
description:
- Number of times to repeat the MAC step.
type: int
default: 1
passphrase:
description:
- The PKCS#12 password.
type: str
path:
required: True
description:
- Filename to write the PKCS#12 file to.
type: path
required: True
privatekey_passphrase:
description:
- Passphrase source to decrypt any input private keys with.
type: str
privatekey_path:
description:
- File to read private key from.
type: path
state:
default: 'present'
choices: ['present', 'absent']
description:
- Whether the file should exist or not.
All parameters except C(path) are ignored when state is C(absent).
choices: [ absent, present ]
default: present
src:
description:
- PKCS#12 file path to parse.
type: path
extends_documentation_fragment:
- files
seealso:
- module: openssl_certificate
- module: openssl_csr
- module: openssl_dhparam
- module: openssl_privatekey
- module: openssl_publickey
'''
EXAMPLES = '''
- name: 'Generate PKCS#12 file'
EXAMPLES = r'''
- name: Generate PKCS#12 file
openssl_pkcs12:
action: export
path: '/opt/certs/ansible.p12'
friendly_name: 'raclette'
privatekey_path: '/opt/certs/keys/key.pem'
certificate_path: '/opt/certs/cert.pem'
ca_certificates: '/opt/certs/ca.pem'
path: /opt/certs/ansible.p12
friendly_name: raclette
privatekey_path: /opt/certs/keys/key.pem
certificate_path: /opt/certs/cert.pem
ca_certificates: /opt/certs/ca.pem
state: present
- name: 'Change PKCS#12 file permission'
- name: Change PKCS#12 file permission
openssl_pkcs12:
action: export
path: '/opt/certs/ansible.p12'
friendly_name: 'raclette'
privatekey_path: '/opt/certs/keys/key.pem'
certificate_path: '/opt/certs/cert.pem'
ca_certificates: '/opt/certs/ca.pem'
path: /opt/certs/ansible.p12
friendly_name: raclette
privatekey_path: /opt/certs/keys/key.pem
certificate_path: /opt/certs/cert.pem
ca_certificates: /opt/certs/ca.pem
state: present
mode: 0600
mode: '0600'
- name: 'Regen PKCS#12 file'
- name: Regen PKCS#12 file
openssl_pkcs12:
action: export
src: '/opt/certs/ansible.p12'
path: '/opt/certs/ansible.p12'
friendly_name: 'raclette'
privatekey_path: '/opt/certs/keys/key.pem'
certificate_path: '/opt/certs/cert.pem'
ca_certificates: '/opt/certs/ca.pem'
src: /opt/certs/ansible.p12
path: /opt/certs/ansible.p12
friendly_name: raclette
privatekey_path: /opt/certs/keys/key.pem
certificate_path: /opt/certs/cert.pem
ca_certificates: /opt/certs/ca.pem
state: present
mode: 0600
force: True
mode: '0600'
force: yes
- name: 'Dump/Parse PKCS#12 file'
- name: Dump/Parse PKCS#12 file
openssl_pkcs12:
action: parse
src: '/opt/certs/ansible.p12'
path: '/opt/certs/ansible.pem'
src: /opt/certs/ansible.p12
path: /opt/certs/ansible.pem
state: present
- name: 'Remove PKCS#12 file'
- name: Remove PKCS#12 file
openssl_pkcs12:
path: '/opt/certs/ansible.p12'
path: /opt/certs/ansible.p12
state: absent
'''
RETURN = '''
RETURN = r'''
filename:
description: Path to the generate PKCS#12 file.
returned: changed or success
type: str
sample: /opt/certs/ansible.p12
privatekey:
description: Path to the TLS/SSL private key the public key was generated from
description: Path to the TLS/SSL private key the public key was generated from.
returned: changed or success
type: str
sample: /etc/ssl/private/ansible.com.pem
@ -280,8 +297,7 @@ class Pkcs(crypto_utils.OpenSSLObject):
def main():
argument_spec = dict(
action=dict(type='str', default='export',
choices=['parse', 'export']),
action=dict(type='str', default='export', choices=['export', 'parse']),
ca_certificates=dict(type='list', elements='path'),
certificate_path=dict(type='path'),
force=dict(type='bool', default=False),
@ -292,8 +308,7 @@ def main():
path=dict(type='path', required=True),
privatekey_passphrase=dict(type='str', no_log=True),
privatekey_path=dict(type='path'),
state=dict(type='str', default='present',
choices=['present', 'absent']),
state=dict(type='str', default='present', choices=['absent', 'present']),
src=dict(type='path'),
)
@ -320,8 +335,7 @@ def main():
if not os.path.isdir(base_dir):
module.fail_json(
name=base_dir,
msg='The directory %s does not exist or '
'the path is not a directory' % base_dir
msg="The directory '%s' does not exist or the path is not a directory" % base_dir
)
pkcs12 = Pkcs(module)

View file

@ -1,66 +1,65 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright: (c) 2016, Yanis Guenane <yanis+ansible@guenane.org>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
DOCUMENTATION = r'''
---
module: openssl_privatekey
author:
- "Yanis Guenane (@Spredzy)"
- "Felix Fontein (@felixfontein)"
version_added: "2.3"
short_description: Generate OpenSSL private keys.
short_description: Generate OpenSSL private keys
description:
- "This module allows one to (re)generate OpenSSL private keys. One can
generate L(RSA,https://en.wikipedia.org/wiki/RSA_(cryptosystem)),
L(DSA,https://en.wikipedia.org/wiki/Digital_Signature_Algorithm) or
L(ECC,https://en.wikipedia.org/wiki/Elliptic-curve_cryptography)
private keys. Keys are generated in PEM format."
- "The module can use the cryptography Python library, or the pyOpenSSL Python
library. By default, it tries to detect which one is available. This can be
overridden with the I(select_crypto_backend) option."
- This module allows one to (re)generate OpenSSL private keys.
- One can generate L(RSA,https://en.wikipedia.org/wiki/RSA_(cryptosystem)),
L(DSA,https://en.wikipedia.org/wiki/Digital_Signature_Algorithm) or
L(ECC,https://en.wikipedia.org/wiki/Elliptic-curve_cryptography)
private keys.
- Keys are generated in PEM format.
- The module can use the cryptography Python library, or the pyOpenSSL Python
library. By default, it tries to detect which one is available. This can be
overridden with the I(select_crypto_backend) option."
requirements:
- "One of the following Python libraries:"
- "cryptography >= 1.2.3 (older versions might work as well)"
- "pyOpenSSL"
- Either cryptography >= 1.2.3 (older versions might work as well)
- Or pyOpenSSL
author:
- Yanis Guenane (@Spredzy)
- Felix Fontein (@felixfontein)
options:
state:
required: false
default: "present"
choices: [ present, absent ]
description:
- Whether the private key should exist or not, taking action if the state is different from what is stated.
type: str
choices: [ absent, present ]
default: present
size:
required: false
description:
- Size (in bits) of the TLS/SSL key to generate.
type: int
default: 4096
description:
- Size (in bits) of the TLS/SSL key to generate
type:
required: false
default: "RSA"
choices:
- RSA
- DSA
- ECC
# - X448
# - X25519
description:
- The algorithm used to generate the TLS/SSL private key
- "Note that C(ECC) requires the C(cryptography) backend. Depending on the curve, you need a newer
version of the cryptography backend."
- The algorithm used to generate the TLS/SSL private key.
- Note that C(ECC) requires the C(cryptography) backend.
- Depending on the curve, you need a newer version of the cryptography backend.
type: str
#choices: [ DSA, ECC, RSA, X448, X25519 ]
choices: [ DSA, ECC, RSA ]
default: RSA
curve:
required: false
description:
- Note that not all curves are supported by all versions of C(cryptography).
- For maximal interoperability, C(secp384r1) or C(secp256k1) should be used.
- We use the curve names as defined in the
L(IANA registry for TLS,https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8).
type: str
choices:
- secp384r1
- secp521r1
@ -80,105 +79,100 @@ options:
- sect283r1
- sect233r1
- sect163r2
description:
- Note that not all curves are supported by all versions of C(cryptography).
- For maximal interoperability, C(secp384r1) or C(secp256k1) should be used.
- We use the curve names as defined in the
L(IANA registry for TLS,https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8).
version_added: "2.8"
force:
required: false
default: False
type: bool
description:
- Should the key be regenerated even if it already exists
- Should the key be regenerated even if it already exists.
type: bool
default: no
path:
required: true
description:
- Name of the file in which the generated TLS/SSL private key will be written. It will have 0600 mode.
type: path
required: true
passphrase:
required: false
description:
- The passphrase for the private key.
type: str
version_added: "2.4"
cipher:
required: false
description:
- The cipher to encrypt the private key. (cipher can be found by running `openssl list-cipher-algorithms`)
- When using the C(cryptography) backend, use C(auto).
type: str
version_added: "2.4"
select_crypto_backend:
description:
- "Determines which crypto backend to use. The default choice is C(auto),
which tries to use C(cryptography) if available, and falls back to
C(pyopenssl)."
- "If set to C(pyopenssl), will try to use the L(pyOpenSSL,https://pypi.org/project/pyOpenSSL/)
library."
- "If set to C(cryptography), will try to use the
L(cryptography,https://cryptography.io/) library."
- Determines which crypto backend to use.
- The default choice is C(auto), which tries to use C(cryptography) if available, and falls back to C(pyopenssl).
- If set to C(pyopenssl), will try to use the L(pyOpenSSL,https://pypi.org/project/pyOpenSSL/) library.
- If set to C(cryptography), will try to use the L(cryptography,https://cryptography.io/) library.
type: str
default: 'auto'
choices:
- auto
- cryptography
- pyopenssl
choices: [ auto, cryptography, pyopenssl ]
default: auto
version_added: "2.8"
extends_documentation_fragment: files
extends_documentation_fragment:
- files
seealso:
- module: openssl_certificate
- module: openssl_csr
- module: openssl_dhparam
- module: openssl_pkcs12
- module: openssl_publickey
'''
EXAMPLES = '''
# Generate an OpenSSL private key with the default values (4096 bits, RSA)
- openssl_privatekey:
EXAMPLES = r'''
- name: Generate an OpenSSL private key with the default values (4096 bits, RSA)
openssl_privatekey:
path: /etc/ssl/private/ansible.com.pem
# Generate an OpenSSL private key with the default values (4096 bits, RSA)
# and a passphrase
- openssl_privatekey:
- name: Generate an OpenSSL private key with the default values (4096 bits, RSA) and a passphrase
openssl_privatekey:
path: /etc/ssl/private/ansible.com.pem
passphrase: ansible
cipher: aes256
# Generate an OpenSSL private key with a different size (2048 bits)
- openssl_privatekey:
- name: Generate an OpenSSL private key with a different size (2048 bits)
openssl_privatekey:
path: /etc/ssl/private/ansible.com.pem
size: 2048
# Force regenerate an OpenSSL private key if it already exists
- openssl_privatekey:
- name: Force regenerate an OpenSSL private key if it already exists
openssl_privatekey:
path: /etc/ssl/private/ansible.com.pem
force: True
force: yes
# Generate an OpenSSL private key with a different algorithm (DSA)
- openssl_privatekey:
- name: Generate an OpenSSL private key with a different algorithm (DSA)
openssl_privatekey:
path: /etc/ssl/private/ansible.com.pem
type: DSA
'''
RETURN = '''
RETURN = r'''
size:
description: Size (in bits) of the TLS/SSL private key
description: Size (in bits) of the TLS/SSL private key.
returned: changed or success
type: int
sample: 4096
type:
description: Algorithm used to generate the TLS/SSL private key
description: Algorithm used to generate the TLS/SSL private key.
returned: changed or success
type: str
sample: RSA
curve:
description: Elliptic curve used to generate the TLS/SSL private key
description: Elliptic curve used to generate the TLS/SSL private key.
returned: changed or success, and I(type) is C(ECC)
type: str
sample: secp256k1
filename:
description: Path to the generated TLS/SSL private key file
description: Path to the generated TLS/SSL private key file.
returned: changed or success
type: str
sample: /etc/ssl/private/ansible.com.pem
fingerprint:
description: The fingerprint of the public key. Fingerprint will be generated for
each C(hashlib.algorithms) available.
The PyOpenSSL backend requires PyOpenSSL >= 16.0 for meaningful output.
description:
- The fingerprint of the public key. Fingerprint will be generated for each C(hashlib.algorithms) available.
- The PyOpenSSL backend requires PyOpenSSL >= 16.0 for meaningful output.
returned: changed or success
type: dict
sample:

View file

@ -1,117 +1,125 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Yanis Guenane <yanis+ansible@guenane.org>
# Copyright: (c) 2016, Yanis Guenane <yanis+ansible@guenane.org>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
DOCUMENTATION = r'''
---
module: openssl_publickey
author: "Yanis Guenane (@Spredzy)"
version_added: "2.3"
short_description: Generate an OpenSSL public key from its private key.
description:
- "This module allows one to (re)generate OpenSSL public keys from their private keys.
It uses the pyOpenSSL python library to interact with openssl. Keys are generated
in PEM format. This module works only if the version of PyOpenSSL is recent enough (> 16.0.0)."
- This module allows one to (re)generate OpenSSL public keys from their private keys.
- It uses the pyOpenSSL python library to interact with openssl.
- Keys are generated in PEM format.
- This module works only if the version of PyOpenSSL is recent enough (> 16.0.0).
requirements:
- "python-pyOpenSSL"
- python-pyOpenSSL
author:
- Yanis Guenane (@Spredzy)
options:
state:
required: false
default: "present"
choices: [ present, absent ]
description:
- Whether the public key should exist or not, taking action if the state is different from what is stated.
type: str
choices: [ absent, present ]
default: present
force:
required: false
default: False
type: bool
description:
- Should the key be regenerated even it it already exists
- Should the key be regenerated even it it already exists.
type: bool
default: no
format:
required: false
default: PEM
choices: [ PEM, OpenSSH ]
description:
- The format of the public key.
type: str
choices: [ OpenSSH, PEM ]
default: PEM
version_added: "2.4"
path:
required: true
description:
- Name of the file in which the generated TLS/SSL public key will be written.
privatekey_path:
type: path
required: true
privatekey_path:
description:
- Path to the TLS/SSL private key from which to generate the public key.
type: path
required: true
privatekey_passphrase:
required: false
description:
- The passphrase for the privatekey.
type: str
version_added: "2.4"
extends_documentation_fragment: files
extends_documentation_fragment:
- files
seealso:
- module: openssl_certificate
- module: openssl_csr
- module: openssl_dhparam
- module: openssl_pkcs12
- module: openssl_privatekey
'''
EXAMPLES = '''
# Generate an OpenSSL public key in PEM format.
- openssl_publickey:
EXAMPLES = r'''
- name: Generate an OpenSSL public key in PEM format
openssl_publickey:
path: /etc/ssl/public/ansible.com.pem
privatekey_path: /etc/ssl/private/ansible.com.pem
# Generate an OpenSSL public key in OpenSSH v2 format.
- openssl_publickey:
- name: Generate an OpenSSL public key in OpenSSH v2 format
openssl_publickey:
path: /etc/ssl/public/ansible.com.pem
privatekey_path: /etc/ssl/private/ansible.com.pem
format: OpenSSH
# Generate an OpenSSL public key with a passphrase protected
# private key
- openssl_publickey:
- name: Generate an OpenSSL public key with a passphrase protected private key
openssl_publickey:
path: /etc/ssl/public/ansible.com.pem
privatekey_path: /etc/ssl/private/ansible.com.pem
privatekey_passphrase: ansible
# Force regenerate an OpenSSL public key if it already exists
- openssl_publickey:
- name: Force regenerate an OpenSSL public key if it already exists
openssl_publickey:
path: /etc/ssl/public/ansible.com.pem
privatekey_path: /etc/ssl/private/ansible.com.pem
force: True
force: yes
# Remove an OpenSSL public key
- openssl_publickey:
- name: Remove an OpenSSL public key
openssl_publickey:
path: /etc/ssl/public/ansible.com.pem
privatekey_path: /etc/ssl/private/ansible.com.pem
state: absent
'''
RETURN = '''
RETURN = r'''
privatekey:
description: Path to the TLS/SSL private key the public key was generated from
description: Path to the TLS/SSL private key the public key was generated from.
returned: changed or success
type: str
sample: /etc/ssl/private/ansible.com.pem
format:
description: The format of the public key (PEM, OpenSSH, ...)
description: The format of the public key (PEM, OpenSSH, ...).
returned: changed or success
type: str
sample: PEM
filename:
description: Path to the generated TLS/SSL public key file
description: Path to the generated TLS/SSL public key file.
returned: changed or success
type: str
sample: /etc/ssl/public/ansible.com.pem
fingerprint:
description: The fingerprint of the public key. Fingerprint will be generated for each hashlib.algorithms available.
Requires PyOpenSSL >= 16.0 for meaningful output.
description:
- The fingerprint of the public key. Fingerprint will be generated for each hashlib.algorithms available.
- Requires PyOpenSSL >= 16.0 for meaningful output.
returned: changed or success
type: dict
sample:
@ -259,16 +267,16 @@ def main():
module = AnsibleModule(
argument_spec=dict(
state=dict(default='present', choices=['present', 'absent'], type='str'),
force=dict(default=False, type='bool'),
path=dict(required=True, type='path'),
state=dict(type='str', default='present', choices=['present', 'absent']),
force=dict(type='bool', default=False),
path=dict(type='path', required=True),
privatekey_path=dict(type='path'),
format=dict(type='str', choices=['PEM', 'OpenSSH'], default='PEM'),
format=dict(type='str', default='PEM', choices=['OpenSSH', 'PEM']),
privatekey_passphrase=dict(type='str', no_log=True),
),
supports_check_mode=True,
add_file_common_args=True,
required_if=[('state', 'present', ['privatekey_path'])]
required_if=[('state', 'present', ['privatekey_path'])],
)
if not pyopenssl_found:
@ -278,7 +286,7 @@ def main():
if not os.path.isdir(base_dir):
module.fail_json(
name=base_dir,
msg='The directory %s does not exist or the file is not a directory' % base_dir
msg="The directory '%s' does not exist or the file is not a directory" % base_dir
)
public_key = PublicKey(module)

View file

@ -360,8 +360,6 @@ lib/ansible/modules/clustering/znode.py E326
lib/ansible/modules/commands/command.py E322
lib/ansible/modules/commands/command.py E323
lib/ansible/modules/commands/command.py E325
lib/ansible/modules/crypto/openssl_certificate.py E325
lib/ansible/modules/crypto/openssl_csr.py E325
lib/ansible/modules/database/influxdb/influxdb_database.py E324
lib/ansible/modules/database/influxdb/influxdb_query.py E324
lib/ansible/modules/database/influxdb/influxdb_retention_policy.py E324