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
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'),